mirror of
https://github.com/the-djmaze/snappymail.git
synced 2026-09-05 23:47:03 +03:00
Move RainLoop core files to new folder
This commit is contained in:
parent
3a9bc849c9
commit
345e7c58af
69 changed files with 1695 additions and 1694 deletions
|
|
@ -1,457 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace RainLoop;
|
||||
|
||||
class Account
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sEmail;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sLogin;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $sPassword;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sProxyAuthUser;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sProxyAuthPassword;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sSignMeToken;
|
||||
|
||||
/**
|
||||
* @var \RainLoop\Domain
|
||||
*/
|
||||
private $oDomain;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sParentEmail;
|
||||
|
||||
/**
|
||||
* @param string $sEmail
|
||||
* @param string $sLogin
|
||||
* @param string $sPassword
|
||||
* @param \RainLoop\Domain $oDomain
|
||||
* @param string $sSignMeToken = ''
|
||||
* @param string $sProxyAuthUser = ''
|
||||
* @param string $sProxyAuthPassword = ''
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function __construct($sEmail, $sLogin, $sPassword, \RainLoop\Domain $oDomain,
|
||||
$sSignMeToken = '', $sProxyAuthUser = '', $sProxyAuthPassword = '')
|
||||
{
|
||||
$this->sEmail = \MailSo\Base\Utils::IdnToAscii($sEmail, true);
|
||||
$this->sLogin = \MailSo\Base\Utils::IdnToAscii($sLogin);
|
||||
$this->sPassword = $sPassword;
|
||||
$this->oDomain = $oDomain;
|
||||
$this->sSignMeToken = $sSignMeToken;
|
||||
$this->sProxyAuthUser = $sProxyAuthUser;
|
||||
$this->sProxyAuthPassword = $sProxyAuthPassword;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sEmail
|
||||
* @param string $sLogin
|
||||
* @param string $sPassword
|
||||
* @param \RainLoop\Domain $oDomain
|
||||
* @param string $sSignMeToken = ''
|
||||
* @param string $sProxyAuthUser = ''
|
||||
* @param string $sProxyAuthPassword = ''
|
||||
*
|
||||
* @return \RainLoop\Account
|
||||
*/
|
||||
public static function NewInstance($sEmail, $sLogin, $sPassword, \RainLoop\Domain $oDomain,
|
||||
$sSignMeToken = '', $sProxyAuthUser = '', $sProxyAuthPassword = '')
|
||||
{
|
||||
return new self($sEmail, $sLogin, $sPassword, $oDomain, $sSignMeToken, $sProxyAuthUser, $sProxyAuthPassword);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function Email()
|
||||
{
|
||||
return $this->sEmail;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function ParentEmail()
|
||||
{
|
||||
return $this->sParentEmail;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function ProxyAuthUser()
|
||||
{
|
||||
return $this->sProxyAuthUser;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function ProxyAuthPassword()
|
||||
{
|
||||
return $this->sProxyAuthPassword;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function ParentEmailHelper()
|
||||
{
|
||||
return 0 < \strlen($this->sParentEmail) ? $this->sParentEmail : $this->sEmail;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function IncLogin()
|
||||
{
|
||||
$sLogin = $this->sLogin;
|
||||
if ($this->oDomain->IncShortLogin())
|
||||
{
|
||||
$sLogin = \MailSo\Base\Utils::GetAccountNameFromEmail($this->sLogin);
|
||||
}
|
||||
|
||||
return $sLogin;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function IncPassword()
|
||||
{
|
||||
return $this->sPassword;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function OutLogin()
|
||||
{
|
||||
$sLogin = $this->sLogin;
|
||||
if ($this->oDomain->OutShortLogin())
|
||||
{
|
||||
$sLogin = \MailSo\Base\Utils::GetAccountNameFromEmail($this->sLogin);
|
||||
}
|
||||
|
||||
return $sLogin;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function Login()
|
||||
{
|
||||
return $this->IncLogin();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function Password()
|
||||
{
|
||||
return $this->IncPassword();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function SignMe()
|
||||
{
|
||||
return 0 < \strlen($this->sSignMeToken);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function SignMeToken()
|
||||
{
|
||||
return $this->sSignMeToken;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \RainLoop\Domain
|
||||
*/
|
||||
public function Domain()
|
||||
{
|
||||
return $this->oDomain;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \RainLoop\Domain
|
||||
*/
|
||||
public function Hash()
|
||||
{
|
||||
return md5(APP_SALT.$this->Email().APP_SALT.$this->DomainIncHost().
|
||||
APP_SALT.$this->DomainIncPort().APP_SALT.$this->Password().APP_SALT.'0'.APP_SALT.$this->ParentEmail().APP_SALT);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sPassword
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function SetPassword($sPassword)
|
||||
{
|
||||
$this->sPassword = $sPassword;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sParentEmail
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function SetParentEmail($sParentEmail)
|
||||
{
|
||||
$this->sParentEmail = \MailSo\Base\Utils::IdnToAscii($sParentEmail, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sProxyAuthUser
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function SetProxyAuthUser($sProxyAuthUser)
|
||||
{
|
||||
return $this->sProxyAuthUser = $sProxyAuthUser;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sProxyAuthPassword
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function SetProxyAuthPassword($sProxyAuthPassword)
|
||||
{
|
||||
return $this->sProxyAuthPassword = $sProxyAuthPassword;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function DomainIncHost()
|
||||
{
|
||||
return $this->Domain()->IncHost(\MailSo\Base\Utils::GetDomainFromEmail($this->Email()));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function DomainIncPort()
|
||||
{
|
||||
return $this->Domain()->IncPort();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function DomainIncSecure()
|
||||
{
|
||||
return $this->Domain()->IncSecure();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool|null $bGlobalVerify = null
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function DomainIncVerifySsl($bGlobalVerify = null)
|
||||
{
|
||||
return $this->Domain()->IncVerifySsl($bGlobalVerify);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function DomainOutHost()
|
||||
{
|
||||
return $this->Domain()->OutHost(\MailSo\Base\Utils::GetDomainFromEmail($this->Email()));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function DomainOutPort()
|
||||
{
|
||||
return $this->Domain()->OutPort();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function DomainOutSecure()
|
||||
{
|
||||
return $this->Domain()->OutSecure();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function DomainOutAuth()
|
||||
{
|
||||
return $this->Domain()->OutAuth();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool|null $bGlobalVerify = null
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function DomainOutVerifySsl($bGlobalVerify = null)
|
||||
{
|
||||
return $this->Domain()->OutVerifySsl($bGlobalVerify);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function GetAuthToken()
|
||||
{
|
||||
return \RainLoop\Utils::EncodeKeyValues(array(
|
||||
'token', // 0
|
||||
$this->sEmail, // 1
|
||||
$this->sLogin, // 2
|
||||
$this->sPassword, // 3
|
||||
\RainLoop\Utils::Fingerprint(), // 4
|
||||
$this->sSignMeToken, // 5
|
||||
$this->sParentEmail, // 6
|
||||
\RainLoop\Utils::GetShortToken(), // 7
|
||||
$this->sProxyAuthUser, // 8
|
||||
$this->sProxyAuthPassword // 9
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \RainLoop\Plugins\Manager $oPlugins
|
||||
* @param \MailSo\Mail\MailClient $oMailClient
|
||||
* @param \RainLoop\Application $oConfig
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function IncConnectAndLoginHelper($oPlugins, $oMailClient, $oConfig)
|
||||
{
|
||||
$bLogin = false;
|
||||
|
||||
$aImapCredentials = array(
|
||||
'UseConnect' => true,
|
||||
'UseAuth' => true,
|
||||
'Host' => $this->DomainIncHost(),
|
||||
'Port' => $this->DomainIncPort(),
|
||||
'Secure' => $this->DomainIncSecure(),
|
||||
'Login' => $this->IncLogin(),
|
||||
'Password' => $this->Password(),
|
||||
'ProxyAuthUser' => $this->ProxyAuthUser(),
|
||||
'ProxyAuthPassword' => $this->ProxyAuthPassword(),
|
||||
'VerifySsl' => $this->DomainIncVerifySsl(!!$oConfig->Get('ssl', 'verify_certificate')),
|
||||
'UseAuthPlainIfSupported' => !!$oConfig->Get('labs', 'use_imap_auth_plain')
|
||||
);
|
||||
|
||||
$oPlugins->RunHook('filter.imap-credentials', array($this, &$aImapCredentials));
|
||||
|
||||
$oPlugins->RunHook('event.imap-pre-connect', array($this, $aImapCredentials['UseConnect'], $aImapCredentials));
|
||||
|
||||
if ($aImapCredentials['UseConnect'])
|
||||
{
|
||||
$oMailClient
|
||||
->Connect($aImapCredentials['Host'], $aImapCredentials['Port'],
|
||||
$aImapCredentials['Secure'], $aImapCredentials['VerifySsl']);
|
||||
}
|
||||
|
||||
$oPlugins->RunHook('event.imap-pre-login', array($this, $aImapCredentials['UseAuth'], $aImapCredentials));
|
||||
|
||||
if ($aImapCredentials['UseAuth'])
|
||||
{
|
||||
if (0 < \strlen($aImapCredentials['ProxyAuthUser']) &&
|
||||
0 < \strlen($aImapCredentials['ProxyAuthPassword']))
|
||||
{
|
||||
$oMailClient
|
||||
->Login($aImapCredentials['ProxyAuthUser'], $aImapCredentials['ProxyAuthPassword'],
|
||||
$aImapCredentials['Login'], $aImapCredentials['UseAuthPlainIfSupported']);
|
||||
}
|
||||
else
|
||||
{
|
||||
$oMailClient->Login($aImapCredentials['Login'], $aImapCredentials['Password'], '',
|
||||
$aImapCredentials['UseAuthPlainIfSupported']);
|
||||
}
|
||||
|
||||
$bLogin = true;
|
||||
}
|
||||
|
||||
$oPlugins->RunHook('event.imap-post-login', array($this, $aImapCredentials['UseAuth'], $bLogin, $aImapCredentials));
|
||||
|
||||
return $bLogin;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \RainLoop\Plugins\Manager $oPlugins
|
||||
* @param \MailSo\Smtp\SmtpClient $oSmtpClient
|
||||
* @param \RainLoop\Application $oConfig
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function OutConnectAndLoginHelper($oPlugins, $oSmtpClient, $oConfig)
|
||||
{
|
||||
$bLogin = false;
|
||||
|
||||
$aSmtpCredentials = array(
|
||||
'UseConnect' => true,
|
||||
'UseAuth' => $this->DomainOutAuth(),
|
||||
'Ehlo' => \MailSo\Smtp\SmtpClient::EhloHelper(),
|
||||
'Host' => $this->DomainOutHost(),
|
||||
'Port' => $this->DomainOutPort(),
|
||||
'Secure' => $this->DomainOutSecure(),
|
||||
'Login' => $this->OutLogin(),
|
||||
'Password' => $this->Password(),
|
||||
'ProxyAuthUser' => $this->ProxyAuthUser(),
|
||||
'ProxyAuthPassword' => $this->ProxyAuthPassword(),
|
||||
'VerifySsl' => $this->DomainOutVerifySsl(!!$oConfig->Get('ssl', 'verify_certificate'))
|
||||
);
|
||||
|
||||
$oPlugins->RunHook('filter.smtp-credentials', array($this, &$aSmtpCredentials));
|
||||
|
||||
$oPlugins->RunHook('event.smtp-pre-connect', array($this, $aSmtpCredentials['UseConnect'], $aSmtpCredentials));
|
||||
|
||||
if ($aSmtpCredentials['UseConnect'])
|
||||
{
|
||||
$oSmtpClient->Connect($aSmtpCredentials['Host'], $aSmtpCredentials['Port'],
|
||||
$aSmtpCredentials['Ehlo'], $aSmtpCredentials['Secure'], $aSmtpCredentials['VerifySsl']);
|
||||
}
|
||||
|
||||
$oPlugins->RunHook('event.smtp-post-connect', array($this, $aSmtpCredentials['UseConnect'], $aSmtpCredentials));
|
||||
$oPlugins->RunHook('event.smtp-pre-login', array($this, $aSmtpCredentials['UseAuth'], $aSmtpCredentials));
|
||||
|
||||
if ($aSmtpCredentials['UseAuth'])
|
||||
{
|
||||
$oSmtpClient->Login($aSmtpCredentials['Login'], $aSmtpCredentials['Password']);
|
||||
|
||||
$bLogin = true;
|
||||
}
|
||||
|
||||
$oPlugins->RunHook('event.smtp-post-login', array($this, $aSmtpCredentials['UseAuth'], $bLogin, $aSmtpCredentials));
|
||||
|
||||
return $bLogin;
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -1,204 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace RainLoop;
|
||||
|
||||
class Api
|
||||
{
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
private function __construct()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public static function RunResult()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @staticvar bool $bOne
|
||||
* @return bool
|
||||
*/
|
||||
public static function Handle()
|
||||
{
|
||||
static $bOne = null;
|
||||
if (null === $bOne)
|
||||
{
|
||||
$bOne = \class_exists('MailSo\Version');
|
||||
if ($bOne)
|
||||
{
|
||||
\RainLoop\Api::SetupDefaultMailSoConfig();
|
||||
$bOne = \RainLoop\Api::RunResult();
|
||||
}
|
||||
}
|
||||
|
||||
return $bOne;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \RainLoop\Actions
|
||||
*/
|
||||
public static function Actions()
|
||||
{
|
||||
static $oActions = null;
|
||||
if (null === $oActions)
|
||||
{
|
||||
$oActions = \RainLoop\Actions::NewInstance();
|
||||
}
|
||||
|
||||
return $oActions;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \RainLoop\Application
|
||||
*/
|
||||
public static function Config()
|
||||
{
|
||||
return \RainLoop\Api::Actions()->Config();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \MailSo\Log\Logger
|
||||
*/
|
||||
public static function Logger()
|
||||
{
|
||||
return \RainLoop\Api::Actions()->Logger();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public static function SetupDefaultMailSoConfig()
|
||||
{
|
||||
if (\class_exists('MailSo\Config'))
|
||||
{
|
||||
if (\RainLoop\Api::Config()->Get('labs', 'disable_iconv_if_mbstring_supported', false) &&
|
||||
\MailSo\Base\Utils::IsMbStringSupported() && \MailSo\Config::$MBSTRING)
|
||||
{
|
||||
\MailSo\Config::$ICONV = false;
|
||||
}
|
||||
|
||||
\MailSo\Config::$MessageListFastSimpleSearch =
|
||||
!!\RainLoop\Api::Config()->Get('labs', 'imap_message_list_fast_simple_search', true);
|
||||
|
||||
\MailSo\Config::$MessageListCountLimitTrigger =
|
||||
(int) \RainLoop\Api::Config()->Get('labs', 'imap_message_list_count_limit_trigger', 0);
|
||||
|
||||
\MailSo\Config::$MessageListDateFilter =
|
||||
(int) \RainLoop\Api::Config()->Get('labs', 'imap_message_list_date_filter', 0);
|
||||
|
||||
\MailSo\Config::$LargeThreadLimit =
|
||||
(int) \RainLoop\Api::Config()->Get('labs', 'imap_large_thread_limit', 100);
|
||||
|
||||
\MailSo\Config::$SystemLogger = \RainLoop\Api::Logger();
|
||||
|
||||
$sSslCafile = \RainLoop\Api::Config()->Get('ssl', 'cafile', '');
|
||||
if (!empty($sSslCafile))
|
||||
{
|
||||
\MailSo\Hooks::Add('Net.NetClient.StreamContextSettings/Filter', function (&$aStreamContextSettings) use ($sSslCafile) {
|
||||
if (isset($aStreamContextSettings['ssl']) && \is_array($aStreamContextSettings['ssl']) &&
|
||||
empty($aStreamContextSettings['ssl']['cafile']))
|
||||
{
|
||||
$aStreamContextSettings['ssl']['cafile'] = $sSslCafile;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public static function Version()
|
||||
{
|
||||
return APP_VERSION;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sEmail
|
||||
* @param string $sPassword
|
||||
* @param bool $bUseTimeout = true
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function GetUserSsoHash($sEmail, $sPassword, $bUseTimeout = true)
|
||||
{
|
||||
$sSsoHash = \sha1(\rand(10000, 99999).$sEmail.$sPassword.\microtime(true));
|
||||
|
||||
return \RainLoop\Api::Actions()->Cacher()->Set(\RainLoop\KeyPathHelper::SsoCacherKey($sSsoHash), \RainLoop\Utils::EncodeKeyValues(array(
|
||||
'Email' => $sEmail,
|
||||
'Password' => $sPassword,
|
||||
'Time' => $bUseTimeout ? \time() : 0
|
||||
))) ? $sSsoHash : '';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sSsoHash
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function ClearUserSsoHash($sSsoHash)
|
||||
{
|
||||
return \RainLoop\Api::Actions()->Cacher()->Delete(\RainLoop\KeyPathHelper::SsoCacherKey($sSsoHash));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sEmail
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function ClearUserData($sEmail)
|
||||
{
|
||||
if (0 < \strlen($sEmail))
|
||||
{
|
||||
$sEmail = \MailSo\Base\Utils::IdnToAscii($sEmail);
|
||||
|
||||
$oStorageProvider = \RainLoop\Api::Actions()->StorageProvider();
|
||||
if ($oStorageProvider && $oStorageProvider->IsActive())
|
||||
{
|
||||
// TwoFactor Auth User Data
|
||||
$oStorageProvider->Clear(null,
|
||||
\RainLoop\Providers\Storage\Enumerations\StorageType::NOBODY,
|
||||
\RainLoop\KeyPathHelper::TwoFactorAuthUserData($sEmail)
|
||||
);
|
||||
|
||||
// Accounts list
|
||||
$oStorageProvider->Clear(null,
|
||||
\RainLoop\Providers\Storage\Enumerations\StorageType::NOBODY,
|
||||
\RainLoop\KeyPathHelper::WebmailAccounts($sEmail)
|
||||
);
|
||||
|
||||
// Contact sync data
|
||||
$oStorageProvider->Clear($sEmail,
|
||||
\RainLoop\Providers\Storage\Enumerations\StorageType::CONFIG,
|
||||
'contacts_sync'
|
||||
);
|
||||
}
|
||||
|
||||
\RainLoop\Api::Actions()->SettingsProvider()->ClearByEmail($sEmail);
|
||||
|
||||
if (\RainLoop\Api::Actions()->AddressBookProvider() &&
|
||||
\RainLoop\Api::Actions()->AddressBookProvider()->IsActive())
|
||||
{
|
||||
\RainLoop\Api::Actions()->AddressBookProvider()->DeleteAllContacts($sEmail);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public static function LogoutCurrentLogginedUser()
|
||||
{
|
||||
\RainLoop\Utils::ClearCookie('rlsession');
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,464 +0,0 @@
|
|||
<?php
|
||||
|
||||
if (!function_exists('mb_strtoupper'))
|
||||
{
|
||||
function mb_strtoupper($s, $encoding = INF)
|
||||
{
|
||||
if ('' === $s .= '') return '';
|
||||
|
||||
if (INF === $encoding) $encoding = 'UTF-8';
|
||||
else $encoding = strtoupper($encoding);
|
||||
|
||||
if ('UTF-8' === $encoding || 'UTF8' === $encoding) $encoding = INF;
|
||||
else $s = function_exists('iconv') ? iconv($encoding, 'UTF-8//IGNORE', $s) : $s;
|
||||
|
||||
static $upper;
|
||||
isset($upper) || $upper = unserialize(base64_decode('YToxMDUxOntzOjE6ImEiO3M6MToiQSI7czoxOiJiIjtzOjE6IkIiO3M6MToiYyI7czoxOiJDIjtz
|
||||
OjE6ImQiO3M6MToiRCI7czoxOiJlIjtzOjE6IkUiO3M6MToiZiI7czoxOiJGIjtzOjE6ImciO3M6
|
||||
MToiRyI7czoxOiJoIjtzOjE6IkgiO3M6MToiaSI7czoxOiJJIjtzOjE6ImoiO3M6MToiSiI7czox
|
||||
OiJrIjtzOjE6IksiO3M6MToibCI7czoxOiJMIjtzOjE6Im0iO3M6MToiTSI7czoxOiJuIjtzOjE6
|
||||
Ik4iO3M6MToibyI7czoxOiJPIjtzOjE6InAiO3M6MToiUCI7czoxOiJxIjtzOjE6IlEiO3M6MToi
|
||||
ciI7czoxOiJSIjtzOjE6InMiO3M6MToiUyI7czoxOiJ0IjtzOjE6IlQiO3M6MToidSI7czoxOiJV
|
||||
IjtzOjE6InYiO3M6MToiViI7czoxOiJ3IjtzOjE6IlciO3M6MToieCI7czoxOiJYIjtzOjE6Inki
|
||||
O3M6MToiWSI7czoxOiJ6IjtzOjE6IloiO3M6MjoiwrUiO3M6MjoizpwiO3M6Mjoiw6AiO3M6Mjoi
|
||||
w4AiO3M6Mjoiw6EiO3M6Mjoiw4EiO3M6Mjoiw6IiO3M6Mjoiw4IiO3M6Mjoiw6MiO3M6Mjoiw4Mi
|
||||
O3M6Mjoiw6QiO3M6Mjoiw4QiO3M6Mjoiw6UiO3M6Mjoiw4UiO3M6Mjoiw6YiO3M6Mjoiw4YiO3M6
|
||||
Mjoiw6ciO3M6Mjoiw4ciO3M6Mjoiw6giO3M6Mjoiw4giO3M6Mjoiw6kiO3M6Mjoiw4kiO3M6Mjoi
|
||||
w6oiO3M6Mjoiw4oiO3M6Mjoiw6siO3M6Mjoiw4siO3M6Mjoiw6wiO3M6Mjoiw4wiO3M6Mjoiw60i
|
||||
O3M6Mjoiw40iO3M6Mjoiw64iO3M6Mjoiw44iO3M6Mjoiw68iO3M6Mjoiw48iO3M6Mjoiw7AiO3M6
|
||||
Mjoiw5AiO3M6Mjoiw7EiO3M6Mjoiw5EiO3M6Mjoiw7IiO3M6Mjoiw5IiO3M6Mjoiw7MiO3M6Mjoi
|
||||
w5MiO3M6Mjoiw7QiO3M6Mjoiw5QiO3M6Mjoiw7UiO3M6Mjoiw5UiO3M6Mjoiw7YiO3M6Mjoiw5Yi
|
||||
O3M6Mjoiw7giO3M6Mjoiw5giO3M6Mjoiw7kiO3M6Mjoiw5kiO3M6Mjoiw7oiO3M6Mjoiw5oiO3M6
|
||||
Mjoiw7siO3M6Mjoiw5siO3M6Mjoiw7wiO3M6Mjoiw5wiO3M6Mjoiw70iO3M6Mjoiw50iO3M6Mjoi
|
||||
w74iO3M6Mjoiw54iO3M6Mjoiw78iO3M6MjoixbgiO3M6MjoixIEiO3M6MjoixIAiO3M6MjoixIMi
|
||||
O3M6MjoixIIiO3M6MjoixIUiO3M6MjoixIQiO3M6MjoixIciO3M6MjoixIYiO3M6MjoixIkiO3M6
|
||||
MjoixIgiO3M6MjoixIsiO3M6MjoixIoiO3M6MjoixI0iO3M6MjoixIwiO3M6MjoixI8iO3M6Mjoi
|
||||
xI4iO3M6MjoixJEiO3M6MjoixJAiO3M6MjoixJMiO3M6MjoixJIiO3M6MjoixJUiO3M6MjoixJQi
|
||||
O3M6MjoixJciO3M6MjoixJYiO3M6MjoixJkiO3M6MjoixJgiO3M6MjoixJsiO3M6MjoixJoiO3M6
|
||||
MjoixJ0iO3M6MjoixJwiO3M6MjoixJ8iO3M6MjoixJ4iO3M6MjoixKEiO3M6MjoixKAiO3M6Mjoi
|
||||
xKMiO3M6MjoixKIiO3M6MjoixKUiO3M6MjoixKQiO3M6MjoixKciO3M6MjoixKYiO3M6MjoixKki
|
||||
O3M6MjoixKgiO3M6MjoixKsiO3M6MjoixKoiO3M6MjoixK0iO3M6MjoixKwiO3M6MjoixK8iO3M6
|
||||
MjoixK4iO3M6MjoixLEiO3M6MToiSSI7czoyOiLEsyI7czoyOiLEsiI7czoyOiLEtSI7czoyOiLE
|
||||
tCI7czoyOiLEtyI7czoyOiLEtiI7czoyOiLEuiI7czoyOiLEuSI7czoyOiLEvCI7czoyOiLEuyI7
|
||||
czoyOiLEviI7czoyOiLEvSI7czoyOiLFgCI7czoyOiLEvyI7czoyOiLFgiI7czoyOiLFgSI7czoy
|
||||
OiLFhCI7czoyOiLFgyI7czoyOiLFhiI7czoyOiLFhSI7czoyOiLFiCI7czoyOiLFhyI7czoyOiLF
|
||||
iyI7czoyOiLFiiI7czoyOiLFjSI7czoyOiLFjCI7czoyOiLFjyI7czoyOiLFjiI7czoyOiLFkSI7
|
||||
czoyOiLFkCI7czoyOiLFkyI7czoyOiLFkiI7czoyOiLFlSI7czoyOiLFlCI7czoyOiLFlyI7czoy
|
||||
OiLFliI7czoyOiLFmSI7czoyOiLFmCI7czoyOiLFmyI7czoyOiLFmiI7czoyOiLFnSI7czoyOiLF
|
||||
nCI7czoyOiLFnyI7czoyOiLFniI7czoyOiLFoSI7czoyOiLFoCI7czoyOiLFoyI7czoyOiLFoiI7
|
||||
czoyOiLFpSI7czoyOiLFpCI7czoyOiLFpyI7czoyOiLFpiI7czoyOiLFqSI7czoyOiLFqCI7czoy
|
||||
OiLFqyI7czoyOiLFqiI7czoyOiLFrSI7czoyOiLFrCI7czoyOiLFryI7czoyOiLFriI7czoyOiLF
|
||||
sSI7czoyOiLFsCI7czoyOiLFsyI7czoyOiLFsiI7czoyOiLFtSI7czoyOiLFtCI7czoyOiLFtyI7
|
||||
czoyOiLFtiI7czoyOiLFuiI7czoyOiLFuSI7czoyOiLFvCI7czoyOiLFuyI7czoyOiLFviI7czoy
|
||||
OiLFvSI7czoyOiLFvyI7czoxOiJTIjtzOjI6IsaAIjtzOjI6IsmDIjtzOjI6IsaDIjtzOjI6IsaC
|
||||
IjtzOjI6IsaFIjtzOjI6IsaEIjtzOjI6IsaIIjtzOjI6IsaHIjtzOjI6IsaMIjtzOjI6IsaLIjtz
|
||||
OjI6IsaSIjtzOjI6IsaRIjtzOjI6IsaVIjtzOjI6Ise2IjtzOjI6IsaZIjtzOjI6IsaYIjtzOjI6
|
||||
IsaaIjtzOjI6Isi9IjtzOjI6IsaeIjtzOjI6IsigIjtzOjI6IsahIjtzOjI6IsagIjtzOjI6Isaj
|
||||
IjtzOjI6IsaiIjtzOjI6IsalIjtzOjI6IsakIjtzOjI6IsaoIjtzOjI6IsanIjtzOjI6IsatIjtz
|
||||
OjI6IsasIjtzOjI6IsawIjtzOjI6IsavIjtzOjI6Isa0IjtzOjI6IsazIjtzOjI6Isa2IjtzOjI6
|
||||
Isa1IjtzOjI6Isa5IjtzOjI6Isa4IjtzOjI6Isa9IjtzOjI6Isa8IjtzOjI6Isa/IjtzOjI6Ise3
|
||||
IjtzOjI6IseFIjtzOjI6IseEIjtzOjI6IseGIjtzOjI6IseEIjtzOjI6IseIIjtzOjI6IseHIjtz
|
||||
OjI6IseJIjtzOjI6IseHIjtzOjI6IseLIjtzOjI6IseKIjtzOjI6IseMIjtzOjI6IseKIjtzOjI6
|
||||
IseOIjtzOjI6IseNIjtzOjI6IseQIjtzOjI6IsePIjtzOjI6IseSIjtzOjI6IseRIjtzOjI6IseU
|
||||
IjtzOjI6IseTIjtzOjI6IseWIjtzOjI6IseVIjtzOjI6IseYIjtzOjI6IseXIjtzOjI6IseaIjtz
|
||||
OjI6IseZIjtzOjI6IsecIjtzOjI6IsebIjtzOjI6IsedIjtzOjI6IsaOIjtzOjI6IsefIjtzOjI6
|
||||
IseeIjtzOjI6IsehIjtzOjI6IsegIjtzOjI6IsejIjtzOjI6IseiIjtzOjI6IselIjtzOjI6Isek
|
||||
IjtzOjI6IsenIjtzOjI6IsemIjtzOjI6IsepIjtzOjI6IseoIjtzOjI6IserIjtzOjI6IseqIjtz
|
||||
OjI6IsetIjtzOjI6IsesIjtzOjI6IsevIjtzOjI6IseuIjtzOjI6IseyIjtzOjI6IsexIjtzOjI6
|
||||
IsezIjtzOjI6IsexIjtzOjI6Ise1IjtzOjI6Ise0IjtzOjI6Ise5IjtzOjI6Ise4IjtzOjI6Ise7
|
||||
IjtzOjI6Ise6IjtzOjI6Ise9IjtzOjI6Ise8IjtzOjI6Ise/IjtzOjI6Ise+IjtzOjI6IsiBIjtz
|
||||
OjI6IsiAIjtzOjI6IsiDIjtzOjI6IsiCIjtzOjI6IsiFIjtzOjI6IsiEIjtzOjI6IsiHIjtzOjI6
|
||||
IsiGIjtzOjI6IsiJIjtzOjI6IsiIIjtzOjI6IsiLIjtzOjI6IsiKIjtzOjI6IsiNIjtzOjI6IsiM
|
||||
IjtzOjI6IsiPIjtzOjI6IsiOIjtzOjI6IsiRIjtzOjI6IsiQIjtzOjI6IsiTIjtzOjI6IsiSIjtz
|
||||
OjI6IsiVIjtzOjI6IsiUIjtzOjI6IsiXIjtzOjI6IsiWIjtzOjI6IsiZIjtzOjI6IsiYIjtzOjI6
|
||||
IsibIjtzOjI6IsiaIjtzOjI6IsidIjtzOjI6IsicIjtzOjI6IsifIjtzOjI6IsieIjtzOjI6Isij
|
||||
IjtzOjI6IsiiIjtzOjI6IsilIjtzOjI6IsikIjtzOjI6IsinIjtzOjI6IsimIjtzOjI6IsipIjtz
|
||||
OjI6IsioIjtzOjI6IsirIjtzOjI6IsiqIjtzOjI6IsitIjtzOjI6IsisIjtzOjI6IsivIjtzOjI6
|
||||
IsiuIjtzOjI6IsixIjtzOjI6IsiwIjtzOjI6IsizIjtzOjI6IsiyIjtzOjI6Isi8IjtzOjI6Isi7
|
||||
IjtzOjI6Isi/IjtzOjM6IuKxviI7czoyOiLJgCI7czozOiLisb8iO3M6MjoiyYIiO3M6MjoiyYEi
|
||||
O3M6MjoiyYciO3M6MjoiyYYiO3M6MjoiyYkiO3M6MjoiyYgiO3M6MjoiyYsiO3M6MjoiyYoiO3M6
|
||||
MjoiyY0iO3M6MjoiyYwiO3M6MjoiyY8iO3M6MjoiyY4iO3M6MjoiyZAiO3M6Mzoi4rGvIjtzOjI6
|
||||
IsmRIjtzOjM6IuKxrSI7czoyOiLJkiI7czozOiLisbAiO3M6MjoiyZMiO3M6MjoixoEiO3M6Mjoi
|
||||
yZQiO3M6MjoixoYiO3M6MjoiyZYiO3M6MjoixokiO3M6MjoiyZciO3M6MjoixooiO3M6MjoiyZki
|
||||
O3M6Mjoixo8iO3M6MjoiyZsiO3M6MjoixpAiO3M6MjoiyaAiO3M6MjoixpMiO3M6MjoiyaMiO3M6
|
||||
MjoixpQiO3M6MjoiyaUiO3M6Mzoi6p6NIjtzOjI6IsmmIjtzOjM6IuqeqiI7czoyOiLJqCI7czoy
|
||||
OiLGlyI7czoyOiLJqSI7czoyOiLGliI7czoyOiLJqyI7czozOiLisaIiO3M6Mjoiya8iO3M6Mjoi
|
||||
xpwiO3M6MjoiybEiO3M6Mzoi4rGuIjtzOjI6IsmyIjtzOjI6IsadIjtzOjI6Ism1IjtzOjI6Isaf
|
||||
IjtzOjI6Ism9IjtzOjM6IuKxpCI7czoyOiLKgCI7czoyOiLGpiI7czoyOiLKgyI7czoyOiLGqSI7
|
||||
czoyOiLKiCI7czoyOiLGriI7czoyOiLKiSI7czoyOiLJhCI7czoyOiLKiiI7czoyOiLGsSI7czoy
|
||||
OiLKiyI7czoyOiLGsiI7czoyOiLKjCI7czoyOiLJhSI7czoyOiLKkiI7czoyOiLGtyI7czoyOiLN
|
||||
hSI7czoyOiLOmSI7czoyOiLNsSI7czoyOiLNsCI7czoyOiLNsyI7czoyOiLNsiI7czoyOiLNtyI7
|
||||
czoyOiLNtiI7czoyOiLNuyI7czoyOiLPvSI7czoyOiLNvCI7czoyOiLPviI7czoyOiLNvSI7czoy
|
||||
OiLPvyI7czoyOiLOrCI7czoyOiLOhiI7czoyOiLOrSI7czoyOiLOiCI7czoyOiLOriI7czoyOiLO
|
||||
iSI7czoyOiLOryI7czoyOiLOiiI7czoyOiLOsSI7czoyOiLOkSI7czoyOiLOsiI7czoyOiLOkiI7
|
||||
czoyOiLOsyI7czoyOiLOkyI7czoyOiLOtCI7czoyOiLOlCI7czoyOiLOtSI7czoyOiLOlSI7czoy
|
||||
OiLOtiI7czoyOiLOliI7czoyOiLOtyI7czoyOiLOlyI7czoyOiLOuCI7czoyOiLOmCI7czoyOiLO
|
||||
uSI7czoyOiLOmSI7czoyOiLOuiI7czoyOiLOmiI7czoyOiLOuyI7czoyOiLOmyI7czoyOiLOvCI7
|
||||
czoyOiLOnCI7czoyOiLOvSI7czoyOiLOnSI7czoyOiLOviI7czoyOiLOniI7czoyOiLOvyI7czoy
|
||||
OiLOnyI7czoyOiLPgCI7czoyOiLOoCI7czoyOiLPgSI7czoyOiLOoSI7czoyOiLPgiI7czoyOiLO
|
||||
oyI7czoyOiLPgyI7czoyOiLOoyI7czoyOiLPhCI7czoyOiLOpCI7czoyOiLPhSI7czoyOiLOpSI7
|
||||
czoyOiLPhiI7czoyOiLOpiI7czoyOiLPhyI7czoyOiLOpyI7czoyOiLPiCI7czoyOiLOqCI7czoy
|
||||
OiLPiSI7czoyOiLOqSI7czoyOiLPiiI7czoyOiLOqiI7czoyOiLPiyI7czoyOiLOqyI7czoyOiLP
|
||||
jCI7czoyOiLOjCI7czoyOiLPjSI7czoyOiLOjiI7czoyOiLPjiI7czoyOiLOjyI7czoyOiLPkCI7
|
||||
czoyOiLOkiI7czoyOiLPkSI7czoyOiLOmCI7czoyOiLPlSI7czoyOiLOpiI7czoyOiLPliI7czoy
|
||||
OiLOoCI7czoyOiLPlyI7czoyOiLPjyI7czoyOiLPmSI7czoyOiLPmCI7czoyOiLPmyI7czoyOiLP
|
||||
miI7czoyOiLPnSI7czoyOiLPnCI7czoyOiLPnyI7czoyOiLPniI7czoyOiLPoSI7czoyOiLPoCI7
|
||||
czoyOiLPoyI7czoyOiLPoiI7czoyOiLPpSI7czoyOiLPpCI7czoyOiLPpyI7czoyOiLPpiI7czoy
|
||||
OiLPqSI7czoyOiLPqCI7czoyOiLPqyI7czoyOiLPqiI7czoyOiLPrSI7czoyOiLPrCI7czoyOiLP
|
||||
ryI7czoyOiLPriI7czoyOiLPsCI7czoyOiLOmiI7czoyOiLPsSI7czoyOiLOoSI7czoyOiLPsiI7
|
||||
czoyOiLPuSI7czoyOiLPtSI7czoyOiLOlSI7czoyOiLPuCI7czoyOiLPtyI7czoyOiLPuyI7czoy
|
||||
OiLPuiI7czoyOiLQsCI7czoyOiLQkCI7czoyOiLQsSI7czoyOiLQkSI7czoyOiLQsiI7czoyOiLQ
|
||||
kiI7czoyOiLQsyI7czoyOiLQkyI7czoyOiLQtCI7czoyOiLQlCI7czoyOiLQtSI7czoyOiLQlSI7
|
||||
czoyOiLQtiI7czoyOiLQliI7czoyOiLQtyI7czoyOiLQlyI7czoyOiLQuCI7czoyOiLQmCI7czoy
|
||||
OiLQuSI7czoyOiLQmSI7czoyOiLQuiI7czoyOiLQmiI7czoyOiLQuyI7czoyOiLQmyI7czoyOiLQ
|
||||
vCI7czoyOiLQnCI7czoyOiLQvSI7czoyOiLQnSI7czoyOiLQviI7czoyOiLQniI7czoyOiLQvyI7
|
||||
czoyOiLQnyI7czoyOiLRgCI7czoyOiLQoCI7czoyOiLRgSI7czoyOiLQoSI7czoyOiLRgiI7czoy
|
||||
OiLQoiI7czoyOiLRgyI7czoyOiLQoyI7czoyOiLRhCI7czoyOiLQpCI7czoyOiLRhSI7czoyOiLQ
|
||||
pSI7czoyOiLRhiI7czoyOiLQpiI7czoyOiLRhyI7czoyOiLQpyI7czoyOiLRiCI7czoyOiLQqCI7
|
||||
czoyOiLRiSI7czoyOiLQqSI7czoyOiLRiiI7czoyOiLQqiI7czoyOiLRiyI7czoyOiLQqyI7czoy
|
||||
OiLRjCI7czoyOiLQrCI7czoyOiLRjSI7czoyOiLQrSI7czoyOiLRjiI7czoyOiLQriI7czoyOiLR
|
||||
jyI7czoyOiLQryI7czoyOiLRkCI7czoyOiLQgCI7czoyOiLRkSI7czoyOiLQgSI7czoyOiLRkiI7
|
||||
czoyOiLQgiI7czoyOiLRkyI7czoyOiLQgyI7czoyOiLRlCI7czoyOiLQhCI7czoyOiLRlSI7czoy
|
||||
OiLQhSI7czoyOiLRliI7czoyOiLQhiI7czoyOiLRlyI7czoyOiLQhyI7czoyOiLRmCI7czoyOiLQ
|
||||
iCI7czoyOiLRmSI7czoyOiLQiSI7czoyOiLRmiI7czoyOiLQiiI7czoyOiLRmyI7czoyOiLQiyI7
|
||||
czoyOiLRnCI7czoyOiLQjCI7czoyOiLRnSI7czoyOiLQjSI7czoyOiLRniI7czoyOiLQjiI7czoy
|
||||
OiLRnyI7czoyOiLQjyI7czoyOiLRoSI7czoyOiLRoCI7czoyOiLRoyI7czoyOiLRoiI7czoyOiLR
|
||||
pSI7czoyOiLRpCI7czoyOiLRpyI7czoyOiLRpiI7czoyOiLRqSI7czoyOiLRqCI7czoyOiLRqyI7
|
||||
czoyOiLRqiI7czoyOiLRrSI7czoyOiLRrCI7czoyOiLRryI7czoyOiLRriI7czoyOiLRsSI7czoy
|
||||
OiLRsCI7czoyOiLRsyI7czoyOiLRsiI7czoyOiLRtSI7czoyOiLRtCI7czoyOiLRtyI7czoyOiLR
|
||||
tiI7czoyOiLRuSI7czoyOiLRuCI7czoyOiLRuyI7czoyOiLRuiI7czoyOiLRvSI7czoyOiLRvCI7
|
||||
czoyOiLRvyI7czoyOiLRviI7czoyOiLSgSI7czoyOiLSgCI7czoyOiLSiyI7czoyOiLSiiI7czoy
|
||||
OiLSjSI7czoyOiLSjCI7czoyOiLSjyI7czoyOiLSjiI7czoyOiLSkSI7czoyOiLSkCI7czoyOiLS
|
||||
kyI7czoyOiLSkiI7czoyOiLSlSI7czoyOiLSlCI7czoyOiLSlyI7czoyOiLSliI7czoyOiLSmSI7
|
||||
czoyOiLSmCI7czoyOiLSmyI7czoyOiLSmiI7czoyOiLSnSI7czoyOiLSnCI7czoyOiLSnyI7czoy
|
||||
OiLSniI7czoyOiLSoSI7czoyOiLSoCI7czoyOiLSoyI7czoyOiLSoiI7czoyOiLSpSI7czoyOiLS
|
||||
pCI7czoyOiLSpyI7czoyOiLSpiI7czoyOiLSqSI7czoyOiLSqCI7czoyOiLSqyI7czoyOiLSqiI7
|
||||
czoyOiLSrSI7czoyOiLSrCI7czoyOiLSryI7czoyOiLSriI7czoyOiLSsSI7czoyOiLSsCI7czoy
|
||||
OiLSsyI7czoyOiLSsiI7czoyOiLStSI7czoyOiLStCI7czoyOiLStyI7czoyOiLStiI7czoyOiLS
|
||||
uSI7czoyOiLSuCI7czoyOiLSuyI7czoyOiLSuiI7czoyOiLSvSI7czoyOiLSvCI7czoyOiLSvyI7
|
||||
czoyOiLSviI7czoyOiLTgiI7czoyOiLTgSI7czoyOiLThCI7czoyOiLTgyI7czoyOiLThiI7czoy
|
||||
OiLThSI7czoyOiLTiCI7czoyOiLThyI7czoyOiLTiiI7czoyOiLTiSI7czoyOiLTjCI7czoyOiLT
|
||||
iyI7czoyOiLTjiI7czoyOiLTjSI7czoyOiLTjyI7czoyOiLTgCI7czoyOiLTkSI7czoyOiLTkCI7
|
||||
czoyOiLTkyI7czoyOiLTkiI7czoyOiLTlSI7czoyOiLTlCI7czoyOiLTlyI7czoyOiLTliI7czoy
|
||||
OiLTmSI7czoyOiLTmCI7czoyOiLTmyI7czoyOiLTmiI7czoyOiLTnSI7czoyOiLTnCI7czoyOiLT
|
||||
nyI7czoyOiLTniI7czoyOiLToSI7czoyOiLToCI7czoyOiLToyI7czoyOiLToiI7czoyOiLTpSI7
|
||||
czoyOiLTpCI7czoyOiLTpyI7czoyOiLTpiI7czoyOiLTqSI7czoyOiLTqCI7czoyOiLTqyI7czoy
|
||||
OiLTqiI7czoyOiLTrSI7czoyOiLTrCI7czoyOiLTryI7czoyOiLTriI7czoyOiLTsSI7czoyOiLT
|
||||
sCI7czoyOiLTsyI7czoyOiLTsiI7czoyOiLTtSI7czoyOiLTtCI7czoyOiLTtyI7czoyOiLTtiI7
|
||||
czoyOiLTuSI7czoyOiLTuCI7czoyOiLTuyI7czoyOiLTuiI7czoyOiLTvSI7czoyOiLTvCI7czoy
|
||||
OiLTvyI7czoyOiLTviI7czoyOiLUgSI7czoyOiLUgCI7czoyOiLUgyI7czoyOiLUgiI7czoyOiLU
|
||||
hSI7czoyOiLUhCI7czoyOiLUhyI7czoyOiLUhiI7czoyOiLUiSI7czoyOiLUiCI7czoyOiLUiyI7
|
||||
czoyOiLUiiI7czoyOiLUjSI7czoyOiLUjCI7czoyOiLUjyI7czoyOiLUjiI7czoyOiLUkSI7czoy
|
||||
OiLUkCI7czoyOiLUkyI7czoyOiLUkiI7czoyOiLUlSI7czoyOiLUlCI7czoyOiLUlyI7czoyOiLU
|
||||
liI7czoyOiLUmSI7czoyOiLUmCI7czoyOiLUmyI7czoyOiLUmiI7czoyOiLUnSI7czoyOiLUnCI7
|
||||
czoyOiLUnyI7czoyOiLUniI7czoyOiLUoSI7czoyOiLUoCI7czoyOiLUoyI7czoyOiLUoiI7czoy
|
||||
OiLUpSI7czoyOiLUpCI7czoyOiLUpyI7czoyOiLUpiI7czoyOiLVoSI7czoyOiLUsSI7czoyOiLV
|
||||
oiI7czoyOiLUsiI7czoyOiLVoyI7czoyOiLUsyI7czoyOiLVpCI7czoyOiLUtCI7czoyOiLVpSI7
|
||||
czoyOiLUtSI7czoyOiLVpiI7czoyOiLUtiI7czoyOiLVpyI7czoyOiLUtyI7czoyOiLVqCI7czoy
|
||||
OiLUuCI7czoyOiLVqSI7czoyOiLUuSI7czoyOiLVqiI7czoyOiLUuiI7czoyOiLVqyI7czoyOiLU
|
||||
uyI7czoyOiLVrCI7czoyOiLUvCI7czoyOiLVrSI7czoyOiLUvSI7czoyOiLVriI7czoyOiLUviI7
|
||||
czoyOiLVryI7czoyOiLUvyI7czoyOiLVsCI7czoyOiLVgCI7czoyOiLVsSI7czoyOiLVgSI7czoy
|
||||
OiLVsiI7czoyOiLVgiI7czoyOiLVsyI7czoyOiLVgyI7czoyOiLVtCI7czoyOiLVhCI7czoyOiLV
|
||||
tSI7czoyOiLVhSI7czoyOiLVtiI7czoyOiLVhiI7czoyOiLVtyI7czoyOiLVhyI7czoyOiLVuCI7
|
||||
czoyOiLViCI7czoyOiLVuSI7czoyOiLViSI7czoyOiLVuiI7czoyOiLViiI7czoyOiLVuyI7czoy
|
||||
OiLViyI7czoyOiLVvCI7czoyOiLVjCI7czoyOiLVvSI7czoyOiLVjSI7czoyOiLVviI7czoyOiLV
|
||||
jiI7czoyOiLVvyI7czoyOiLVjyI7czoyOiLWgCI7czoyOiLVkCI7czoyOiLWgSI7czoyOiLVkSI7
|
||||
czoyOiLWgiI7czoyOiLVkiI7czoyOiLWgyI7czoyOiLVkyI7czoyOiLWhCI7czoyOiLVlCI7czoy
|
||||
OiLWhSI7czoyOiLVlSI7czoyOiLWhiI7czoyOiLVliI7czozOiLhtbkiO3M6Mzoi6p29IjtzOjM6
|
||||
IuG1vSI7czozOiLisaMiO3M6Mzoi4biBIjtzOjM6IuG4gCI7czozOiLhuIMiO3M6Mzoi4biCIjtz
|
||||
OjM6IuG4hSI7czozOiLhuIQiO3M6Mzoi4biHIjtzOjM6IuG4hiI7czozOiLhuIkiO3M6Mzoi4biI
|
||||
IjtzOjM6IuG4iyI7czozOiLhuIoiO3M6Mzoi4biNIjtzOjM6IuG4jCI7czozOiLhuI8iO3M6Mzoi
|
||||
4biOIjtzOjM6IuG4kSI7czozOiLhuJAiO3M6Mzoi4biTIjtzOjM6IuG4kiI7czozOiLhuJUiO3M6
|
||||
Mzoi4biUIjtzOjM6IuG4lyI7czozOiLhuJYiO3M6Mzoi4biZIjtzOjM6IuG4mCI7czozOiLhuJsi
|
||||
O3M6Mzoi4biaIjtzOjM6IuG4nSI7czozOiLhuJwiO3M6Mzoi4bifIjtzOjM6IuG4niI7czozOiLh
|
||||
uKEiO3M6Mzoi4bigIjtzOjM6IuG4oyI7czozOiLhuKIiO3M6Mzoi4bilIjtzOjM6IuG4pCI7czoz
|
||||
OiLhuKciO3M6Mzoi4bimIjtzOjM6IuG4qSI7czozOiLhuKgiO3M6Mzoi4birIjtzOjM6IuG4qiI7
|
||||
czozOiLhuK0iO3M6Mzoi4bisIjtzOjM6IuG4ryI7czozOiLhuK4iO3M6Mzoi4bixIjtzOjM6IuG4
|
||||
sCI7czozOiLhuLMiO3M6Mzoi4biyIjtzOjM6IuG4tSI7czozOiLhuLQiO3M6Mzoi4bi3IjtzOjM6
|
||||
IuG4tiI7czozOiLhuLkiO3M6Mzoi4bi4IjtzOjM6IuG4uyI7czozOiLhuLoiO3M6Mzoi4bi9Ijtz
|
||||
OjM6IuG4vCI7czozOiLhuL8iO3M6Mzoi4bi+IjtzOjM6IuG5gSI7czozOiLhuYAiO3M6Mzoi4bmD
|
||||
IjtzOjM6IuG5giI7czozOiLhuYUiO3M6Mzoi4bmEIjtzOjM6IuG5hyI7czozOiLhuYYiO3M6Mzoi
|
||||
4bmJIjtzOjM6IuG5iCI7czozOiLhuYsiO3M6Mzoi4bmKIjtzOjM6IuG5jSI7czozOiLhuYwiO3M6
|
||||
Mzoi4bmPIjtzOjM6IuG5jiI7czozOiLhuZEiO3M6Mzoi4bmQIjtzOjM6IuG5kyI7czozOiLhuZIi
|
||||
O3M6Mzoi4bmVIjtzOjM6IuG5lCI7czozOiLhuZciO3M6Mzoi4bmWIjtzOjM6IuG5mSI7czozOiLh
|
||||
uZgiO3M6Mzoi4bmbIjtzOjM6IuG5miI7czozOiLhuZ0iO3M6Mzoi4bmcIjtzOjM6IuG5nyI7czoz
|
||||
OiLhuZ4iO3M6Mzoi4bmhIjtzOjM6IuG5oCI7czozOiLhuaMiO3M6Mzoi4bmiIjtzOjM6IuG5pSI7
|
||||
czozOiLhuaQiO3M6Mzoi4bmnIjtzOjM6IuG5piI7czozOiLhuakiO3M6Mzoi4bmoIjtzOjM6IuG5
|
||||
qyI7czozOiLhuaoiO3M6Mzoi4bmtIjtzOjM6IuG5rCI7czozOiLhua8iO3M6Mzoi4bmuIjtzOjM6
|
||||
IuG5sSI7czozOiLhubAiO3M6Mzoi4bmzIjtzOjM6IuG5siI7czozOiLhubUiO3M6Mzoi4bm0Ijtz
|
||||
OjM6IuG5tyI7czozOiLhubYiO3M6Mzoi4bm5IjtzOjM6IuG5uCI7czozOiLhubsiO3M6Mzoi4bm6
|
||||
IjtzOjM6IuG5vSI7czozOiLhubwiO3M6Mzoi4bm/IjtzOjM6IuG5viI7czozOiLhuoEiO3M6Mzoi
|
||||
4bqAIjtzOjM6IuG6gyI7czozOiLhuoIiO3M6Mzoi4bqFIjtzOjM6IuG6hCI7czozOiLhuociO3M6
|
||||
Mzoi4bqGIjtzOjM6IuG6iSI7czozOiLhuogiO3M6Mzoi4bqLIjtzOjM6IuG6iiI7czozOiLhuo0i
|
||||
O3M6Mzoi4bqMIjtzOjM6IuG6jyI7czozOiLhuo4iO3M6Mzoi4bqRIjtzOjM6IuG6kCI7czozOiLh
|
||||
upMiO3M6Mzoi4bqSIjtzOjM6IuG6lSI7czozOiLhupQiO3M6Mzoi4bqbIjtzOjM6IuG5oCI7czoz
|
||||
OiLhuqEiO3M6Mzoi4bqgIjtzOjM6IuG6oyI7czozOiLhuqIiO3M6Mzoi4bqlIjtzOjM6IuG6pCI7
|
||||
czozOiLhuqciO3M6Mzoi4bqmIjtzOjM6IuG6qSI7czozOiLhuqgiO3M6Mzoi4bqrIjtzOjM6IuG6
|
||||
qiI7czozOiLhuq0iO3M6Mzoi4bqsIjtzOjM6IuG6ryI7czozOiLhuq4iO3M6Mzoi4bqxIjtzOjM6
|
||||
IuG6sCI7czozOiLhurMiO3M6Mzoi4bqyIjtzOjM6IuG6tSI7czozOiLhurQiO3M6Mzoi4bq3Ijtz
|
||||
OjM6IuG6tiI7czozOiLhurkiO3M6Mzoi4bq4IjtzOjM6IuG6uyI7czozOiLhuroiO3M6Mzoi4bq9
|
||||
IjtzOjM6IuG6vCI7czozOiLhur8iO3M6Mzoi4bq+IjtzOjM6IuG7gSI7czozOiLhu4AiO3M6Mzoi
|
||||
4buDIjtzOjM6IuG7giI7czozOiLhu4UiO3M6Mzoi4buEIjtzOjM6IuG7hyI7czozOiLhu4YiO3M6
|
||||
Mzoi4buJIjtzOjM6IuG7iCI7czozOiLhu4siO3M6Mzoi4buKIjtzOjM6IuG7jSI7czozOiLhu4wi
|
||||
O3M6Mzoi4buPIjtzOjM6IuG7jiI7czozOiLhu5EiO3M6Mzoi4buQIjtzOjM6IuG7kyI7czozOiLh
|
||||
u5IiO3M6Mzoi4buVIjtzOjM6IuG7lCI7czozOiLhu5ciO3M6Mzoi4buWIjtzOjM6IuG7mSI7czoz
|
||||
OiLhu5giO3M6Mzoi4bubIjtzOjM6IuG7miI7czozOiLhu50iO3M6Mzoi4bucIjtzOjM6IuG7nyI7
|
||||
czozOiLhu54iO3M6Mzoi4buhIjtzOjM6IuG7oCI7czozOiLhu6MiO3M6Mzoi4buiIjtzOjM6IuG7
|
||||
pSI7czozOiLhu6QiO3M6Mzoi4bunIjtzOjM6IuG7piI7czozOiLhu6kiO3M6Mzoi4buoIjtzOjM6
|
||||
IuG7qyI7czozOiLhu6oiO3M6Mzoi4butIjtzOjM6IuG7rCI7czozOiLhu68iO3M6Mzoi4buuIjtz
|
||||
OjM6IuG7sSI7czozOiLhu7AiO3M6Mzoi4buzIjtzOjM6IuG7siI7czozOiLhu7UiO3M6Mzoi4bu0
|
||||
IjtzOjM6IuG7tyI7czozOiLhu7YiO3M6Mzoi4bu5IjtzOjM6IuG7uCI7czozOiLhu7siO3M6Mzoi
|
||||
4bu6IjtzOjM6IuG7vSI7czozOiLhu7wiO3M6Mzoi4bu/IjtzOjM6IuG7viI7czozOiLhvIAiO3M6
|
||||
Mzoi4byIIjtzOjM6IuG8gSI7czozOiLhvIkiO3M6Mzoi4byCIjtzOjM6IuG8iiI7czozOiLhvIMi
|
||||
O3M6Mzoi4byLIjtzOjM6IuG8hCI7czozOiLhvIwiO3M6Mzoi4byFIjtzOjM6IuG8jSI7czozOiLh
|
||||
vIYiO3M6Mzoi4byOIjtzOjM6IuG8hyI7czozOiLhvI8iO3M6Mzoi4byQIjtzOjM6IuG8mCI7czoz
|
||||
OiLhvJEiO3M6Mzoi4byZIjtzOjM6IuG8kiI7czozOiLhvJoiO3M6Mzoi4byTIjtzOjM6IuG8myI7
|
||||
czozOiLhvJQiO3M6Mzoi4bycIjtzOjM6IuG8lSI7czozOiLhvJ0iO3M6Mzoi4bygIjtzOjM6IuG8
|
||||
qCI7czozOiLhvKEiO3M6Mzoi4bypIjtzOjM6IuG8oiI7czozOiLhvKoiO3M6Mzoi4byjIjtzOjM6
|
||||
IuG8qyI7czozOiLhvKQiO3M6Mzoi4bysIjtzOjM6IuG8pSI7czozOiLhvK0iO3M6Mzoi4bymIjtz
|
||||
OjM6IuG8riI7czozOiLhvKciO3M6Mzoi4byvIjtzOjM6IuG8sCI7czozOiLhvLgiO3M6Mzoi4byx
|
||||
IjtzOjM6IuG8uSI7czozOiLhvLIiO3M6Mzoi4by6IjtzOjM6IuG8syI7czozOiLhvLsiO3M6Mzoi
|
||||
4by0IjtzOjM6IuG8vCI7czozOiLhvLUiO3M6Mzoi4by9IjtzOjM6IuG8tiI7czozOiLhvL4iO3M6
|
||||
Mzoi4by3IjtzOjM6IuG8vyI7czozOiLhvYAiO3M6Mzoi4b2IIjtzOjM6IuG9gSI7czozOiLhvYki
|
||||
O3M6Mzoi4b2CIjtzOjM6IuG9iiI7czozOiLhvYMiO3M6Mzoi4b2LIjtzOjM6IuG9hCI7czozOiLh
|
||||
vYwiO3M6Mzoi4b2FIjtzOjM6IuG9jSI7czozOiLhvZEiO3M6Mzoi4b2ZIjtzOjM6IuG9kyI7czoz
|
||||
OiLhvZsiO3M6Mzoi4b2VIjtzOjM6IuG9nSI7czozOiLhvZciO3M6Mzoi4b2fIjtzOjM6IuG9oCI7
|
||||
czozOiLhvagiO3M6Mzoi4b2hIjtzOjM6IuG9qSI7czozOiLhvaIiO3M6Mzoi4b2qIjtzOjM6IuG9
|
||||
oyI7czozOiLhvasiO3M6Mzoi4b2kIjtzOjM6IuG9rCI7czozOiLhvaUiO3M6Mzoi4b2tIjtzOjM6
|
||||
IuG9piI7czozOiLhva4iO3M6Mzoi4b2nIjtzOjM6IuG9ryI7czozOiLhvbAiO3M6Mzoi4b66Ijtz
|
||||
OjM6IuG9sSI7czozOiLhvrsiO3M6Mzoi4b2yIjtzOjM6IuG/iCI7czozOiLhvbMiO3M6Mzoi4b+J
|
||||
IjtzOjM6IuG9tCI7czozOiLhv4oiO3M6Mzoi4b21IjtzOjM6IuG/iyI7czozOiLhvbYiO3M6Mzoi
|
||||
4b+aIjtzOjM6IuG9tyI7czozOiLhv5siO3M6Mzoi4b24IjtzOjM6IuG/uCI7czozOiLhvbkiO3M6
|
||||
Mzoi4b+5IjtzOjM6IuG9uiI7czozOiLhv6oiO3M6Mzoi4b27IjtzOjM6IuG/qyI7czozOiLhvbwi
|
||||
O3M6Mzoi4b+6IjtzOjM6IuG9vSI7czozOiLhv7siO3M6Mzoi4b6AIjtzOjM6IuG+iCI7czozOiLh
|
||||
voEiO3M6Mzoi4b6JIjtzOjM6IuG+giI7czozOiLhvooiO3M6Mzoi4b6DIjtzOjM6IuG+iyI7czoz
|
||||
OiLhvoQiO3M6Mzoi4b6MIjtzOjM6IuG+hSI7czozOiLhvo0iO3M6Mzoi4b6GIjtzOjM6IuG+jiI7
|
||||
czozOiLhvociO3M6Mzoi4b6PIjtzOjM6IuG+kCI7czozOiLhvpgiO3M6Mzoi4b6RIjtzOjM6IuG+
|
||||
mSI7czozOiLhvpIiO3M6Mzoi4b6aIjtzOjM6IuG+kyI7czozOiLhvpsiO3M6Mzoi4b6UIjtzOjM6
|
||||
IuG+nCI7czozOiLhvpUiO3M6Mzoi4b6dIjtzOjM6IuG+liI7czozOiLhvp4iO3M6Mzoi4b6XIjtz
|
||||
OjM6IuG+nyI7czozOiLhvqAiO3M6Mzoi4b6oIjtzOjM6IuG+oSI7czozOiLhvqkiO3M6Mzoi4b6i
|
||||
IjtzOjM6IuG+qiI7czozOiLhvqMiO3M6Mzoi4b6rIjtzOjM6IuG+pCI7czozOiLhvqwiO3M6Mzoi
|
||||
4b6lIjtzOjM6IuG+rSI7czozOiLhvqYiO3M6Mzoi4b6uIjtzOjM6IuG+pyI7czozOiLhvq8iO3M6
|
||||
Mzoi4b6wIjtzOjM6IuG+uCI7czozOiLhvrEiO3M6Mzoi4b65IjtzOjM6IuG+syI7czozOiLhvrwi
|
||||
O3M6Mzoi4b6+IjtzOjI6Is6ZIjtzOjM6IuG/gyI7czozOiLhv4wiO3M6Mzoi4b+QIjtzOjM6IuG/
|
||||
mCI7czozOiLhv5EiO3M6Mzoi4b+ZIjtzOjM6IuG/oCI7czozOiLhv6giO3M6Mzoi4b+hIjtzOjM6
|
||||
IuG/qSI7czozOiLhv6UiO3M6Mzoi4b+sIjtzOjM6IuG/syI7czozOiLhv7wiO3M6Mzoi4oWOIjtz
|
||||
OjM6IuKEsiI7czozOiLihbAiO3M6Mzoi4oWgIjtzOjM6IuKFsSI7czozOiLihaEiO3M6Mzoi4oWy
|
||||
IjtzOjM6IuKFoiI7czozOiLihbMiO3M6Mzoi4oWjIjtzOjM6IuKFtCI7czozOiLihaQiO3M6Mzoi
|
||||
4oW1IjtzOjM6IuKFpSI7czozOiLihbYiO3M6Mzoi4oWmIjtzOjM6IuKFtyI7czozOiLihaciO3M6
|
||||
Mzoi4oW4IjtzOjM6IuKFqCI7czozOiLihbkiO3M6Mzoi4oWpIjtzOjM6IuKFuiI7czozOiLihaoi
|
||||
O3M6Mzoi4oW7IjtzOjM6IuKFqyI7czozOiLihbwiO3M6Mzoi4oWsIjtzOjM6IuKFvSI7czozOiLi
|
||||
ha0iO3M6Mzoi4oW+IjtzOjM6IuKFriI7czozOiLihb8iO3M6Mzoi4oWvIjtzOjM6IuKGhCI7czoz
|
||||
OiLihoMiO3M6Mzoi4pOQIjtzOjM6IuKStiI7czozOiLik5EiO3M6Mzoi4pK3IjtzOjM6IuKTkiI7
|
||||
czozOiLikrgiO3M6Mzoi4pOTIjtzOjM6IuKSuSI7czozOiLik5QiO3M6Mzoi4pK6IjtzOjM6IuKT
|
||||
lSI7czozOiLikrsiO3M6Mzoi4pOWIjtzOjM6IuKSvCI7czozOiLik5ciO3M6Mzoi4pK9IjtzOjM6
|
||||
IuKTmCI7czozOiLikr4iO3M6Mzoi4pOZIjtzOjM6IuKSvyI7czozOiLik5oiO3M6Mzoi4pOAIjtz
|
||||
OjM6IuKTmyI7czozOiLik4EiO3M6Mzoi4pOcIjtzOjM6IuKTgiI7czozOiLik50iO3M6Mzoi4pOD
|
||||
IjtzOjM6IuKTniI7czozOiLik4QiO3M6Mzoi4pOfIjtzOjM6IuKThSI7czozOiLik6AiO3M6Mzoi
|
||||
4pOGIjtzOjM6IuKToSI7czozOiLik4ciO3M6Mzoi4pOiIjtzOjM6IuKTiCI7czozOiLik6MiO3M6
|
||||
Mzoi4pOJIjtzOjM6IuKTpCI7czozOiLik4oiO3M6Mzoi4pOlIjtzOjM6IuKTiyI7czozOiLik6Yi
|
||||
O3M6Mzoi4pOMIjtzOjM6IuKTpyI7czozOiLik40iO3M6Mzoi4pOoIjtzOjM6IuKTjiI7czozOiLi
|
||||
k6kiO3M6Mzoi4pOPIjtzOjM6IuKwsCI7czozOiLisIAiO3M6Mzoi4rCxIjtzOjM6IuKwgSI7czoz
|
||||
OiLisLIiO3M6Mzoi4rCCIjtzOjM6IuKwsyI7czozOiLisIMiO3M6Mzoi4rC0IjtzOjM6IuKwhCI7
|
||||
czozOiLisLUiO3M6Mzoi4rCFIjtzOjM6IuKwtiI7czozOiLisIYiO3M6Mzoi4rC3IjtzOjM6IuKw
|
||||
hyI7czozOiLisLgiO3M6Mzoi4rCIIjtzOjM6IuKwuSI7czozOiLisIkiO3M6Mzoi4rC6IjtzOjM6
|
||||
IuKwiiI7czozOiLisLsiO3M6Mzoi4rCLIjtzOjM6IuKwvCI7czozOiLisIwiO3M6Mzoi4rC9Ijtz
|
||||
OjM6IuKwjSI7czozOiLisL4iO3M6Mzoi4rCOIjtzOjM6IuKwvyI7czozOiLisI8iO3M6Mzoi4rGA
|
||||
IjtzOjM6IuKwkCI7czozOiLisYEiO3M6Mzoi4rCRIjtzOjM6IuKxgiI7czozOiLisJIiO3M6Mzoi
|
||||
4rGDIjtzOjM6IuKwkyI7czozOiLisYQiO3M6Mzoi4rCUIjtzOjM6IuKxhSI7czozOiLisJUiO3M6
|
||||
Mzoi4rGGIjtzOjM6IuKwliI7czozOiLisYciO3M6Mzoi4rCXIjtzOjM6IuKxiCI7czozOiLisJgi
|
||||
O3M6Mzoi4rGJIjtzOjM6IuKwmSI7czozOiLisYoiO3M6Mzoi4rCaIjtzOjM6IuKxiyI7czozOiLi
|
||||
sJsiO3M6Mzoi4rGMIjtzOjM6IuKwnCI7czozOiLisY0iO3M6Mzoi4rCdIjtzOjM6IuKxjiI7czoz
|
||||
OiLisJ4iO3M6Mzoi4rGPIjtzOjM6IuKwnyI7czozOiLisZAiO3M6Mzoi4rCgIjtzOjM6IuKxkSI7
|
||||
czozOiLisKEiO3M6Mzoi4rGSIjtzOjM6IuKwoiI7czozOiLisZMiO3M6Mzoi4rCjIjtzOjM6IuKx
|
||||
lCI7czozOiLisKQiO3M6Mzoi4rGVIjtzOjM6IuKwpSI7czozOiLisZYiO3M6Mzoi4rCmIjtzOjM6
|
||||
IuKxlyI7czozOiLisKciO3M6Mzoi4rGYIjtzOjM6IuKwqCI7czozOiLisZkiO3M6Mzoi4rCpIjtz
|
||||
OjM6IuKxmiI7czozOiLisKoiO3M6Mzoi4rGbIjtzOjM6IuKwqyI7czozOiLisZwiO3M6Mzoi4rCs
|
||||
IjtzOjM6IuKxnSI7czozOiLisK0iO3M6Mzoi4rGeIjtzOjM6IuKwriI7czozOiLisaEiO3M6Mzoi
|
||||
4rGgIjtzOjM6IuKxpSI7czoyOiLIuiI7czozOiLisaYiO3M6MjoiyL4iO3M6Mzoi4rGoIjtzOjM6
|
||||
IuKxpyI7czozOiLisaoiO3M6Mzoi4rGpIjtzOjM6IuKxrCI7czozOiLisasiO3M6Mzoi4rGzIjtz
|
||||
OjM6IuKxsiI7czozOiLisbYiO3M6Mzoi4rG1IjtzOjM6IuKygSI7czozOiLisoAiO3M6Mzoi4rKD
|
||||
IjtzOjM6IuKygiI7czozOiLisoUiO3M6Mzoi4rKEIjtzOjM6IuKyhyI7czozOiLisoYiO3M6Mzoi
|
||||
4rKJIjtzOjM6IuKyiCI7czozOiLisosiO3M6Mzoi4rKKIjtzOjM6IuKyjSI7czozOiLisowiO3M6
|
||||
Mzoi4rKPIjtzOjM6IuKyjiI7czozOiLispEiO3M6Mzoi4rKQIjtzOjM6IuKykyI7czozOiLispIi
|
||||
O3M6Mzoi4rKVIjtzOjM6IuKylCI7czozOiLispciO3M6Mzoi4rKWIjtzOjM6IuKymSI7czozOiLi
|
||||
spgiO3M6Mzoi4rKbIjtzOjM6IuKymiI7czozOiLisp0iO3M6Mzoi4rKcIjtzOjM6IuKynyI7czoz
|
||||
OiLisp4iO3M6Mzoi4rKhIjtzOjM6IuKyoCI7czozOiLisqMiO3M6Mzoi4rKiIjtzOjM6IuKypSI7
|
||||
czozOiLisqQiO3M6Mzoi4rKnIjtzOjM6IuKypiI7czozOiLisqkiO3M6Mzoi4rKoIjtzOjM6IuKy
|
||||
qyI7czozOiLisqoiO3M6Mzoi4rKtIjtzOjM6IuKyrCI7czozOiLisq8iO3M6Mzoi4rKuIjtzOjM6
|
||||
IuKysSI7czozOiLisrAiO3M6Mzoi4rKzIjtzOjM6IuKysiI7czozOiLisrUiO3M6Mzoi4rK0Ijtz
|
||||
OjM6IuKytyI7czozOiLisrYiO3M6Mzoi4rK5IjtzOjM6IuKyuCI7czozOiLisrsiO3M6Mzoi4rK6
|
||||
IjtzOjM6IuKyvSI7czozOiLisrwiO3M6Mzoi4rK/IjtzOjM6IuKyviI7czozOiLis4EiO3M6Mzoi
|
||||
4rOAIjtzOjM6IuKzgyI7czozOiLis4IiO3M6Mzoi4rOFIjtzOjM6IuKzhCI7czozOiLis4ciO3M6
|
||||
Mzoi4rOGIjtzOjM6IuKziSI7czozOiLis4giO3M6Mzoi4rOLIjtzOjM6IuKziiI7czozOiLis40i
|
||||
O3M6Mzoi4rOMIjtzOjM6IuKzjyI7czozOiLis44iO3M6Mzoi4rORIjtzOjM6IuKzkCI7czozOiLi
|
||||
s5MiO3M6Mzoi4rOSIjtzOjM6IuKzlSI7czozOiLis5QiO3M6Mzoi4rOXIjtzOjM6IuKzliI7czoz
|
||||
OiLis5kiO3M6Mzoi4rOYIjtzOjM6IuKzmyI7czozOiLis5oiO3M6Mzoi4rOdIjtzOjM6IuKznCI7
|
||||
czozOiLis58iO3M6Mzoi4rOeIjtzOjM6IuKzoSI7czozOiLis6AiO3M6Mzoi4rOjIjtzOjM6IuKz
|
||||
oiI7czozOiLis6wiO3M6Mzoi4rOrIjtzOjM6IuKzriI7czozOiLis60iO3M6Mzoi4rOzIjtzOjM6
|
||||
IuKzsiI7czozOiLitIAiO3M6Mzoi4YKgIjtzOjM6IuK0gSI7czozOiLhgqEiO3M6Mzoi4rSCIjtz
|
||||
OjM6IuGCoiI7czozOiLitIMiO3M6Mzoi4YKjIjtzOjM6IuK0hCI7czozOiLhgqQiO3M6Mzoi4rSF
|
||||
IjtzOjM6IuGCpSI7czozOiLitIYiO3M6Mzoi4YKmIjtzOjM6IuK0hyI7czozOiLhgqciO3M6Mzoi
|
||||
4rSIIjtzOjM6IuGCqCI7czozOiLitIkiO3M6Mzoi4YKpIjtzOjM6IuK0iiI7czozOiLhgqoiO3M6
|
||||
Mzoi4rSLIjtzOjM6IuGCqyI7czozOiLitIwiO3M6Mzoi4YKsIjtzOjM6IuK0jSI7czozOiLhgq0i
|
||||
O3M6Mzoi4rSOIjtzOjM6IuGCriI7czozOiLitI8iO3M6Mzoi4YKvIjtzOjM6IuK0kCI7czozOiLh
|
||||
grAiO3M6Mzoi4rSRIjtzOjM6IuGCsSI7czozOiLitJIiO3M6Mzoi4YKyIjtzOjM6IuK0kyI7czoz
|
||||
OiLhgrMiO3M6Mzoi4rSUIjtzOjM6IuGCtCI7czozOiLitJUiO3M6Mzoi4YK1IjtzOjM6IuK0liI7
|
||||
czozOiLhgrYiO3M6Mzoi4rSXIjtzOjM6IuGCtyI7czozOiLitJgiO3M6Mzoi4YK4IjtzOjM6IuK0
|
||||
mSI7czozOiLhgrkiO3M6Mzoi4rSaIjtzOjM6IuGCuiI7czozOiLitJsiO3M6Mzoi4YK7IjtzOjM6
|
||||
IuK0nCI7czozOiLhgrwiO3M6Mzoi4rSdIjtzOjM6IuGCvSI7czozOiLitJ4iO3M6Mzoi4YK+Ijtz
|
||||
OjM6IuK0nyI7czozOiLhgr8iO3M6Mzoi4rSgIjtzOjM6IuGDgCI7czozOiLitKEiO3M6Mzoi4YOB
|
||||
IjtzOjM6IuK0oiI7czozOiLhg4IiO3M6Mzoi4rSjIjtzOjM6IuGDgyI7czozOiLitKQiO3M6Mzoi
|
||||
4YOEIjtzOjM6IuK0pSI7czozOiLhg4UiO3M6Mzoi4rSnIjtzOjM6IuGDhyI7czozOiLitK0iO3M6
|
||||
Mzoi4YONIjtzOjM6IuqZgSI7czozOiLqmYAiO3M6Mzoi6pmDIjtzOjM6IuqZgiI7czozOiLqmYUi
|
||||
O3M6Mzoi6pmEIjtzOjM6IuqZhyI7czozOiLqmYYiO3M6Mzoi6pmJIjtzOjM6IuqZiCI7czozOiLq
|
||||
mYsiO3M6Mzoi6pmKIjtzOjM6IuqZjSI7czozOiLqmYwiO3M6Mzoi6pmPIjtzOjM6IuqZjiI7czoz
|
||||
OiLqmZEiO3M6Mzoi6pmQIjtzOjM6IuqZkyI7czozOiLqmZIiO3M6Mzoi6pmVIjtzOjM6IuqZlCI7
|
||||
czozOiLqmZciO3M6Mzoi6pmWIjtzOjM6IuqZmSI7czozOiLqmZgiO3M6Mzoi6pmbIjtzOjM6IuqZ
|
||||
miI7czozOiLqmZ0iO3M6Mzoi6pmcIjtzOjM6IuqZnyI7czozOiLqmZ4iO3M6Mzoi6pmhIjtzOjM6
|
||||
IuqZoCI7czozOiLqmaMiO3M6Mzoi6pmiIjtzOjM6IuqZpSI7czozOiLqmaQiO3M6Mzoi6pmnIjtz
|
||||
OjM6IuqZpiI7czozOiLqmakiO3M6Mzoi6pmoIjtzOjM6IuqZqyI7czozOiLqmaoiO3M6Mzoi6pmt
|
||||
IjtzOjM6IuqZrCI7czozOiLqmoEiO3M6Mzoi6pqAIjtzOjM6IuqagyI7czozOiLqmoIiO3M6Mzoi
|
||||
6pqFIjtzOjM6IuqahCI7czozOiLqmociO3M6Mzoi6pqGIjtzOjM6IuqaiSI7czozOiLqmogiO3M6
|
||||
Mzoi6pqLIjtzOjM6IuqaiiI7czozOiLqmo0iO3M6Mzoi6pqMIjtzOjM6IuqajyI7czozOiLqmo4i
|
||||
O3M6Mzoi6pqRIjtzOjM6IuqakCI7czozOiLqmpMiO3M6Mzoi6pqSIjtzOjM6IuqalSI7czozOiLq
|
||||
mpQiO3M6Mzoi6pqXIjtzOjM6IuqaliI7czozOiLqnKMiO3M6Mzoi6pyiIjtzOjM6IuqcpSI7czoz
|
||||
OiLqnKQiO3M6Mzoi6pynIjtzOjM6IuqcpiI7czozOiLqnKkiO3M6Mzoi6pyoIjtzOjM6IuqcqyI7
|
||||
czozOiLqnKoiO3M6Mzoi6pytIjtzOjM6IuqcrCI7czozOiLqnK8iO3M6Mzoi6pyuIjtzOjM6Iuqc
|
||||
syI7czozOiLqnLIiO3M6Mzoi6py1IjtzOjM6IuqctCI7czozOiLqnLciO3M6Mzoi6py2IjtzOjM6
|
||||
IuqcuSI7czozOiLqnLgiO3M6Mzoi6py7IjtzOjM6IuqcuiI7czozOiLqnL0iO3M6Mzoi6py8Ijtz
|
||||
OjM6IuqcvyI7czozOiLqnL4iO3M6Mzoi6p2BIjtzOjM6IuqdgCI7czozOiLqnYMiO3M6Mzoi6p2C
|
||||
IjtzOjM6IuqdhSI7czozOiLqnYQiO3M6Mzoi6p2HIjtzOjM6IuqdhiI7czozOiLqnYkiO3M6Mzoi
|
||||
6p2IIjtzOjM6IuqdiyI7czozOiLqnYoiO3M6Mzoi6p2NIjtzOjM6IuqdjCI7czozOiLqnY8iO3M6
|
||||
Mzoi6p2OIjtzOjM6IuqdkSI7czozOiLqnZAiO3M6Mzoi6p2TIjtzOjM6IuqdkiI7czozOiLqnZUi
|
||||
O3M6Mzoi6p2UIjtzOjM6IuqdlyI7czozOiLqnZYiO3M6Mzoi6p2ZIjtzOjM6IuqdmCI7czozOiLq
|
||||
nZsiO3M6Mzoi6p2aIjtzOjM6IuqdnSI7czozOiLqnZwiO3M6Mzoi6p2fIjtzOjM6IuqdniI7czoz
|
||||
OiLqnaEiO3M6Mzoi6p2gIjtzOjM6IuqdoyI7czozOiLqnaIiO3M6Mzoi6p2lIjtzOjM6IuqdpCI7
|
||||
czozOiLqnaciO3M6Mzoi6p2mIjtzOjM6IuqdqSI7czozOiLqnagiO3M6Mzoi6p2rIjtzOjM6Iuqd
|
||||
qiI7czozOiLqna0iO3M6Mzoi6p2sIjtzOjM6IuqdryI7czozOiLqna4iO3M6Mzoi6p26IjtzOjM6
|
||||
IuqduSI7czozOiLqnbwiO3M6Mzoi6p27IjtzOjM6IuqdvyI7czozOiLqnb4iO3M6Mzoi6p6BIjtz
|
||||
OjM6IuqegCI7czozOiLqnoMiO3M6Mzoi6p6CIjtzOjM6IuqehSI7czozOiLqnoQiO3M6Mzoi6p6H
|
||||
IjtzOjM6IuqehiI7czozOiLqnowiO3M6Mzoi6p6LIjtzOjM6IuqekSI7czozOiLqnpAiO3M6Mzoi
|
||||
6p6TIjtzOjM6IuqekiI7czozOiLqnqEiO3M6Mzoi6p6gIjtzOjM6IuqeoyI7czozOiLqnqIiO3M6
|
||||
Mzoi6p6lIjtzOjM6IuqepCI7czozOiLqnqciO3M6Mzoi6p6mIjtzOjM6IuqeqSI7czozOiLqnqgi
|
||||
O3M6Mzoi772BIjtzOjM6Iu+8oSI7czozOiLvvYIiO3M6Mzoi77yiIjtzOjM6Iu+9gyI7czozOiLv
|
||||
vKMiO3M6Mzoi772EIjtzOjM6Iu+8pCI7czozOiLvvYUiO3M6Mzoi77ylIjtzOjM6Iu+9hiI7czoz
|
||||
OiLvvKYiO3M6Mzoi772HIjtzOjM6Iu+8pyI7czozOiLvvYgiO3M6Mzoi77yoIjtzOjM6Iu+9iSI7
|
||||
czozOiLvvKkiO3M6Mzoi772KIjtzOjM6Iu+8qiI7czozOiLvvYsiO3M6Mzoi77yrIjtzOjM6Iu+9
|
||||
jCI7czozOiLvvKwiO3M6Mzoi772NIjtzOjM6Iu+8rSI7czozOiLvvY4iO3M6Mzoi77yuIjtzOjM6
|
||||
Iu+9jyI7czozOiLvvK8iO3M6Mzoi772QIjtzOjM6Iu+8sCI7czozOiLvvZEiO3M6Mzoi77yxIjtz
|
||||
OjM6Iu+9kiI7czozOiLvvLIiO3M6Mzoi772TIjtzOjM6Iu+8syI7czozOiLvvZQiO3M6Mzoi77y0
|
||||
IjtzOjM6Iu+9lSI7czozOiLvvLUiO3M6Mzoi772WIjtzOjM6Iu+8tiI7czozOiLvvZciO3M6Mzoi
|
||||
77y3IjtzOjM6Iu+9mCI7czozOiLvvLgiO3M6Mzoi772ZIjtzOjM6Iu+8uSI7czozOiLvvZoiO3M6
|
||||
Mzoi77y6IjtzOjQ6IvCQkKgiO3M6NDoi8JCQgCI7czo0OiLwkJCpIjtzOjQ6IvCQkIEiO3M6NDoi
|
||||
8JCQqiI7czo0OiLwkJCCIjtzOjQ6IvCQkKsiO3M6NDoi8JCQgyI7czo0OiLwkJCsIjtzOjQ6IvCQ
|
||||
kIQiO3M6NDoi8JCQrSI7czo0OiLwkJCFIjtzOjQ6IvCQkK4iO3M6NDoi8JCQhiI7czo0OiLwkJCv
|
||||
IjtzOjQ6IvCQkIciO3M6NDoi8JCQsCI7czo0OiLwkJCIIjtzOjQ6IvCQkLEiO3M6NDoi8JCQiSI7
|
||||
czo0OiLwkJCyIjtzOjQ6IvCQkIoiO3M6NDoi8JCQsyI7czo0OiLwkJCLIjtzOjQ6IvCQkLQiO3M6
|
||||
NDoi8JCQjCI7czo0OiLwkJC1IjtzOjQ6IvCQkI0iO3M6NDoi8JCQtiI7czo0OiLwkJCOIjtzOjQ6
|
||||
IvCQkLciO3M6NDoi8JCQjyI7czo0OiLwkJC4IjtzOjQ6IvCQkJAiO3M6NDoi8JCQuSI7czo0OiLw
|
||||
kJCRIjtzOjQ6IvCQkLoiO3M6NDoi8JCQkiI7czo0OiLwkJC7IjtzOjQ6IvCQkJMiO3M6NDoi8JCQ
|
||||
vCI7czo0OiLwkJCUIjtzOjQ6IvCQkL0iO3M6NDoi8JCQlSI7czo0OiLwkJC+IjtzOjQ6IvCQkJYi
|
||||
O3M6NDoi8JCQvyI7czo0OiLwkJCXIjtzOjQ6IvCQkYAiO3M6NDoi8JCQmCI7czo0OiLwkJGBIjtz
|
||||
OjQ6IvCQkJkiO3M6NDoi8JCRgiI7czo0OiLwkJCaIjtzOjQ6IvCQkYMiO3M6NDoi8JCQmyI7czo0
|
||||
OiLwkJGEIjtzOjQ6IvCQkJwiO3M6NDoi8JCRhSI7czo0OiLwkJCdIjtzOjQ6IvCQkYYiO3M6NDoi
|
||||
8JCQniI7czo0OiLwkJGHIjtzOjQ6IvCQkJ8iO3M6NDoi8JCRiCI7czo0OiLwkJCgIjtzOjQ6IvCQ
|
||||
kYkiO3M6NDoi8JCQoSI7czo0OiLwkJGKIjtzOjQ6IvCQkKIiO3M6NDoi8JCRiyI7czo0OiLwkJCj
|
||||
IjtzOjQ6IvCQkYwiO3M6NDoi8JCQpCI7czo0OiLwkJGNIjtzOjQ6IvCQkKUiO3M6NDoi8JCRjiI7
|
||||
czo0OiLwkJCmIjtzOjQ6IvCQkY8iO3M6NDoi8JCQpyI7fQ=='));
|
||||
$map = $upper;
|
||||
|
||||
static $ulen_mask = array("\xC0" => 2, "\xD0" => 2, "\xE0" => 3, "\xF0" => 4);
|
||||
|
||||
$i = 0;
|
||||
$len = strlen($s);
|
||||
|
||||
while ($i < $len)
|
||||
{
|
||||
$ulen = $s[$i] < "\x80" ? 1 : $ulen_mask[$s[$i] & "\xF0"];
|
||||
$uchr = substr($s, $i, $ulen);
|
||||
$i += $ulen;
|
||||
|
||||
if (isset($map[$uchr]))
|
||||
{
|
||||
$uchr = $map[$uchr];
|
||||
$nlen = strlen($uchr);
|
||||
|
||||
if ($nlen == $ulen)
|
||||
{
|
||||
$nlen = $i;
|
||||
do $s[--$nlen] = $uchr[--$ulen];
|
||||
while ($ulen);
|
||||
}
|
||||
else
|
||||
{
|
||||
$s = substr_replace($s, $uchr, $i - $ulen, $ulen);
|
||||
$len += $nlen - $ulen;
|
||||
$i += $nlen - $ulen;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (INF === $encoding) return $s;
|
||||
else return function_exists('iconv') ? iconv('UTF-8', $encoding, $s) : $s;
|
||||
}
|
||||
}
|
||||
|
||||
if (!function_exists('mb_strcut'))
|
||||
{
|
||||
function mb_strcut($str, $start, $length = null, $encoding = '')
|
||||
{
|
||||
$match = array();
|
||||
// use the regex unicode support to separate the UTF-8 characters into an array
|
||||
preg_match_all( '/./us', $str, $match );
|
||||
$chars = is_null( $length )? array_slice( $match[0], $start ) : array_slice( $match[0], $start, $length );
|
||||
return implode( '', $chars );
|
||||
}
|
||||
}
|
||||
|
||||
if (!function_exists('mb_detect_encoding'))
|
||||
{
|
||||
function mb_detect_encoding($str, $encoding_list = INF, $strict = false)
|
||||
{
|
||||
if (INF === $encoding_list) $encoding_list = 'UTF-8';
|
||||
else
|
||||
{
|
||||
if (! is_array($encoding_list)) $encoding_list = array_map('trim', explode(',', $encoding_list));
|
||||
$encoding_list = array_map('strtoupper', $encoding_list);
|
||||
}
|
||||
|
||||
foreach ($encoding_list as $enc)
|
||||
{
|
||||
switch ($enc)
|
||||
{
|
||||
case 'ASCII':
|
||||
if (! preg_match('/[\x80-\xFF]/', $str)) return $enc;
|
||||
break;
|
||||
|
||||
case 'UTF8':
|
||||
case 'UTF-8':
|
||||
if (preg_match('//u', $str)) return $enc;
|
||||
break;
|
||||
|
||||
default:
|
||||
return strncmp($enc, 'ISO-8859-', 9) ? false : $enc;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!function_exists('mb_check_encoding'))
|
||||
{
|
||||
function mb_check_encoding($var = INF, $encoding = INF)
|
||||
{
|
||||
if (INF === $encoding)
|
||||
{
|
||||
if (INF === $var) return false;
|
||||
$encoding = 'UTF-8';
|
||||
}
|
||||
|
||||
return false !== mb_detect_encoding($var, array($encoding), true);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,555 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace RainLoop\Common;
|
||||
|
||||
abstract class PdoAbstract
|
||||
{
|
||||
/**
|
||||
* @var \PDO
|
||||
*/
|
||||
protected $oPDO = null;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $bExplain = false;
|
||||
|
||||
/**
|
||||
* @var \MailSo\Log\Logger
|
||||
*/
|
||||
protected $oLogger;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $sDbType;
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function IsSupported()
|
||||
{
|
||||
return !!\class_exists('PDO');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \MailSo\Log\Logger $oLogger
|
||||
*/
|
||||
public function SetLogger($oLogger)
|
||||
{
|
||||
$this->oLogger = $oLogger instanceof \MailSo\Log\Logger ? $oLogger : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
protected function getPdoAccessData()
|
||||
{
|
||||
return array('', '', '', '');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \PDO
|
||||
*
|
||||
* @throws \Exception
|
||||
*/
|
||||
protected function getPDO()
|
||||
{
|
||||
if ($this->oPDO)
|
||||
{
|
||||
return $this->oPDO;
|
||||
}
|
||||
|
||||
if (!\class_exists('PDO'))
|
||||
{
|
||||
throw new \Exception('Class PDO does not exist');
|
||||
}
|
||||
|
||||
$sType = $sDsn = $sDbLogin = $sDbPassword = '';
|
||||
list($sType, $sDsn, $sDbLogin, $sDbPassword) = $this->getPdoAccessData();
|
||||
if (!\in_array($sType, array('mysql', 'sqlite', 'pgsql')))
|
||||
{
|
||||
throw new \Exception('Unknown PDO SQL connection type');
|
||||
}
|
||||
|
||||
$this->sDbType = $sType;
|
||||
|
||||
$oPdo = false;
|
||||
try
|
||||
{
|
||||
$oPdo = @new \PDO($sDsn, $sDbLogin, $sDbPassword);
|
||||
if ($oPdo)
|
||||
{
|
||||
$oPdo->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
|
||||
if ('mysql' === $sType && 'mysql' === $oPdo->getAttribute(\PDO::ATTR_DRIVER_NAME))
|
||||
{
|
||||
$oPdo->exec('SET NAMES utf8 COLLATE utf8_general_ci');
|
||||
// $oPdo->exec('SET NAMES utf8');
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (\Exception $oException)
|
||||
{
|
||||
throw $oException;
|
||||
}
|
||||
|
||||
if ($oPdo)
|
||||
{
|
||||
$this->oPDO = $oPdo;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new \Exception('PDO = false');
|
||||
}
|
||||
|
||||
return $oPdo;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sTabelName = null
|
||||
* @param string $sColumnName = null
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function lastInsertId($sTabelName = null, $sColumnName = null)
|
||||
{
|
||||
$mName = null;
|
||||
if ('pgsql' === $this->sDbType &&
|
||||
null !== $sTabelName && $sColumnName !== null)
|
||||
{
|
||||
$mName = \strtolower($sTabelName.'_'.$sColumnName.'_seq');
|
||||
}
|
||||
|
||||
return null === $mName ? $this->getPDO()->lastInsertId() : $this->getPDO()->lastInsertId($mName);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
protected function beginTransaction()
|
||||
{
|
||||
return $this->getPDO()->beginTransaction();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
protected function commit()
|
||||
{
|
||||
return $this->getPDO()->commit();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
protected function rollBack()
|
||||
{
|
||||
return $this->getPDO()->rollBack();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sSql
|
||||
* @param array $aParams
|
||||
* @param bool $bMultiplyParams = false
|
||||
*
|
||||
* @return \PDOStatement|null
|
||||
*/
|
||||
protected function prepareAndExecute($sSql, $aParams = array(), $bMultiplyParams = false)
|
||||
{
|
||||
if ($this->bExplain && !$bMultiplyParams)
|
||||
{
|
||||
$this->prepareAndExplain($sSql, $aParams);
|
||||
}
|
||||
|
||||
$mResult = null;
|
||||
|
||||
$this->writeLog($sSql);
|
||||
$oStmt = $this->getPDO()->prepare($sSql);
|
||||
if ($oStmt)
|
||||
{
|
||||
$aRootParams = $bMultiplyParams ? $aParams : array($aParams);
|
||||
foreach ($aRootParams as $aSubParams)
|
||||
{
|
||||
foreach ($aSubParams as $sName => $aValue)
|
||||
{
|
||||
$oStmt->bindValue($sName, $aValue[0], $aValue[1]);
|
||||
}
|
||||
|
||||
$mResult = $oStmt->execute() && !$bMultiplyParams ? $oStmt : null;
|
||||
}
|
||||
}
|
||||
|
||||
return $mResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sSql
|
||||
* @param array $aParams
|
||||
*/
|
||||
protected function prepareAndExplain($sSql, $aParams = array())
|
||||
{
|
||||
$mResult = null;
|
||||
if (0 === strpos($sSql, 'SELECT '))
|
||||
{
|
||||
$sSql = 'EXPLAIN '.$sSql;
|
||||
$this->writeLog($sSql);
|
||||
$oStmt = $this->getPDO()->prepare($sSql);
|
||||
if ($oStmt)
|
||||
{
|
||||
foreach ($aParams as $sName => $aValue)
|
||||
{
|
||||
$oStmt->bindValue($sName, $aValue[0], $aValue[1]);
|
||||
}
|
||||
|
||||
$mResult = $oStmt->execute() ? $oStmt : null;
|
||||
}
|
||||
}
|
||||
|
||||
if ($mResult)
|
||||
{
|
||||
$aFetch = $mResult->fetchAll(\PDO::FETCH_ASSOC);
|
||||
$this->oLogger->WriteDump($aFetch);
|
||||
|
||||
unset($aFetch);
|
||||
$mResult->closeCursor();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $mData
|
||||
*/
|
||||
protected function writeLog($mData)
|
||||
{
|
||||
if ($this->oLogger)
|
||||
{
|
||||
$this->oLogger->WriteMixed($mData, \MailSo\Log\Enumerations\Type::INFO, 'SQL');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sEmail
|
||||
* @param bool $bSkipInsert = false
|
||||
* @param bool $bCache = true
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
protected function getUserId($sEmail, $bSkipInsert = false, $bCache = true)
|
||||
{
|
||||
static $aCache = array();
|
||||
if ($bCache && isset($aCache[$sEmail]))
|
||||
{
|
||||
return $aCache[$sEmail];
|
||||
}
|
||||
|
||||
$sEmail = \MailSo\Base\Utils::IdnToAscii(\trim($sEmail), true);
|
||||
if (empty($sEmail))
|
||||
{
|
||||
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)
|
||||
)
|
||||
);
|
||||
|
||||
$mRow = $oStmt->fetch(\PDO::FETCH_ASSOC);
|
||||
if ($mRow && isset($mRow['id_user']) && \is_numeric($mRow['id_user']))
|
||||
{
|
||||
$iResult = (int) $mRow['id_user'];
|
||||
if (0 >= $iResult)
|
||||
{
|
||||
throw new \Exception('id_user <= 0');
|
||||
}
|
||||
|
||||
if ($bCache)
|
||||
{
|
||||
$aCache[$sEmail] = $iResult;
|
||||
}
|
||||
|
||||
return $iResult;
|
||||
}
|
||||
|
||||
if (!$bSkipInsert)
|
||||
{
|
||||
$oStmt->closeCursor();
|
||||
|
||||
$oStmt = $this->prepareAndExecute('INSERT INTO rainloop_users (rl_email) VALUES (:rl_email)',
|
||||
array(':rl_email' => array($sEmail, \PDO::PARAM_STR))
|
||||
);
|
||||
|
||||
return $this->getUserId($sEmail, true);
|
||||
}
|
||||
|
||||
throw new \Exception('id_user = 0');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sValue
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function quoteValue($sValue)
|
||||
{
|
||||
$oPdo = $this->getPDO();
|
||||
return $oPdo ? $oPdo->quote((string) $sValue, \PDO::PARAM_STR) : '\'\'';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sName
|
||||
* @param bool $bReturnIntValue = true
|
||||
*
|
||||
* @return int|string|bool
|
||||
*/
|
||||
protected function getSystemValue($sName, $bReturnIntValue = true)
|
||||
{
|
||||
$oPdo = $this->getPDO();
|
||||
if ($oPdo)
|
||||
{
|
||||
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);
|
||||
$sKey = $bReturnIntValue ? 'value_int' : 'value_str';
|
||||
if ($mRow && isset($mRow[0][$sKey]))
|
||||
{
|
||||
return $bReturnIntValue ? (int) $mRow[0][$sKey] : (string) $mRow[0][$sKey];
|
||||
}
|
||||
|
||||
return $bReturnIntValue ? 0 : '';
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sName
|
||||
*
|
||||
* @return int|string|bool
|
||||
*/
|
||||
protected function getVersion($sName)
|
||||
{
|
||||
return $this->getSystemValue($sName.'_version', true);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sName
|
||||
* @param int $iVersion
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function setVersion($sName, $iVersion)
|
||||
{
|
||||
$bResult = false;
|
||||
$oPdo = $this->getPDO();
|
||||
if ($oPdo)
|
||||
{
|
||||
$sQuery = 'DELETE FROM rainloop_system WHERE sys_name = ? AND value_int <= ?;';
|
||||
$this->writeLog($sQuery);
|
||||
|
||||
$oStmt = $oPdo->prepare($sQuery);
|
||||
$bResult = !!$oStmt->execute(array($sName.'_version', $iVersion));
|
||||
if ($bResult)
|
||||
{
|
||||
$sQuery = 'INSERT INTO rainloop_system (sys_name, value_int) VALUES (?, ?);';
|
||||
$this->writeLog($sQuery);
|
||||
|
||||
$oStmt = $oPdo->prepare($sQuery);
|
||||
if ($oStmt)
|
||||
{
|
||||
$bResult = !!$oStmt->execute(array($sName.'_version', $iVersion));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $bResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $bWatchVersion = true
|
||||
*
|
||||
* @throws \Exception
|
||||
*/
|
||||
protected function initSystemTables()
|
||||
{
|
||||
$bResult = true;
|
||||
|
||||
$oPdo = $this->getPDO();
|
||||
if ($oPdo)
|
||||
{
|
||||
$aQ = array();
|
||||
switch ($this->sDbType)
|
||||
{
|
||||
case 'mysql':
|
||||
$aQ[] = 'CREATE TABLE IF NOT EXISTS rainloop_system (
|
||||
sys_name varchar(50) NOT NULL,
|
||||
value_int int UNSIGNED NOT NULL DEFAULT 0,
|
||||
value_str varchar(128) NOT NULL DEFAULT \'\',
|
||||
INDEX sys_name_rainloop_system_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 UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
rl_email varchar(128) NOT NULL DEFAULT \'\',
|
||||
PRIMARY KEY(id_user),
|
||||
INDEX rl_email_rainloop_users_index (rl_email)
|
||||
) /*!40000 ENGINE=INNODB */;';
|
||||
break;
|
||||
|
||||
case 'pgsql':
|
||||
$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_rainloop_system_index ON rainloop_system (sys_name);';
|
||||
$aQ[] = 'CREATE SEQUENCE id_user START WITH 1 INCREMENT BY 1 NO MAXVALUE NO MINVALUE CACHE 1;';
|
||||
$aQ[] = 'CREATE TABLE rainloop_users (
|
||||
id_user integer DEFAULT nextval(\'id_user\'::text) PRIMARY KEY,
|
||||
rl_email varchar(128) NOT NULL DEFAULT \'\'
|
||||
);';
|
||||
$aQ[] = 'CREATE INDEX rl_email_rainloop_users_index ON rainloop_users (rl_email);';
|
||||
break;
|
||||
|
||||
case 'sqlite':
|
||||
$aQ[] = 'CREATE TABLE rainloop_system (
|
||||
sys_name text NOT NULL,
|
||||
value_int integer NOT NULL DEFAULT 0,
|
||||
value_str text NOT NULL DEFAULT \'\'
|
||||
);';
|
||||
$aQ[] = 'CREATE INDEX sys_name_rainloop_system_index ON rainloop_system (sys_name);';
|
||||
$aQ[] = 'CREATE TABLE rainloop_users (
|
||||
id_user integer NOT NULL PRIMARY KEY,
|
||||
rl_email text NOT NULL DEFAULT \'\'
|
||||
);';
|
||||
$aQ[] = 'CREATE INDEX rl_email_rainloop_users_index ON rainloop_users (rl_email);';
|
||||
break;
|
||||
}
|
||||
|
||||
if (0 < \count($aQ))
|
||||
{
|
||||
try
|
||||
{
|
||||
foreach ($aQ as $sQuery)
|
||||
{
|
||||
if ($bResult)
|
||||
{
|
||||
$this->writeLog($sQuery);
|
||||
$bResult = false !== $oPdo->exec($sQuery);
|
||||
if (!$bResult)
|
||||
{
|
||||
$this->writeLog('Result=false');
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->writeLog('Result=true');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (\Exception $oException)
|
||||
{
|
||||
$this->writeLog($oException);
|
||||
throw $oException;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $bResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sName
|
||||
* @param array $aData = array()
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function dataBaseUpgrade($sName, $aData = array())
|
||||
{
|
||||
$iFromVersion = null;
|
||||
try
|
||||
{
|
||||
$iFromVersion = $this->getVersion($sName);
|
||||
}
|
||||
catch (\PDOException $oException)
|
||||
{
|
||||
$this->writeLog($oException);
|
||||
|
||||
try
|
||||
{
|
||||
$this->initSystemTables();
|
||||
|
||||
$iFromVersion = $this->getVersion($sName);
|
||||
}
|
||||
catch (\PDOException $oSubException)
|
||||
{
|
||||
$this->writeLog($oSubException);
|
||||
throw $oSubException;
|
||||
}
|
||||
}
|
||||
|
||||
if (\is_int($iFromVersion) && 0 <= $iFromVersion)
|
||||
{
|
||||
$oPdo = false;
|
||||
$bResult = false;
|
||||
|
||||
foreach ($aData as $iVersion => $aQuery)
|
||||
{
|
||||
if (0 === \count($aQuery))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!$oPdo)
|
||||
{
|
||||
$oPdo = $this->getPDO();
|
||||
$bResult = true;
|
||||
}
|
||||
|
||||
if ($iFromVersion < $iVersion && $oPdo)
|
||||
{
|
||||
try
|
||||
{
|
||||
foreach ($aQuery as $sQuery)
|
||||
{
|
||||
$this->writeLog($sQuery);
|
||||
$bExec = $oPdo->exec($sQuery);
|
||||
if (false === $bExec)
|
||||
{
|
||||
$this->writeLog('Result: false');
|
||||
|
||||
$bResult = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (\Exception $oException)
|
||||
{
|
||||
$this->writeLog($oException);
|
||||
throw $oException;
|
||||
}
|
||||
|
||||
if (!$bResult)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
$this->setVersion($sName, $iVersion);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $bResult;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,127 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace RainLoop\Common;
|
||||
|
||||
class RainLoopFacebookRedirectLoginHelper extends \Facebook\FacebookRedirectLoginHelper
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $rlAppId;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $rlUserHash;
|
||||
|
||||
/**
|
||||
* @var mixed
|
||||
*/
|
||||
private $rlAccount;
|
||||
|
||||
/**
|
||||
* @var mixed
|
||||
*/
|
||||
private $rlStorageProvaider;
|
||||
|
||||
public function __construct($redirectUrl, $appId = null, $appSecret = null)
|
||||
{
|
||||
parent::__construct($redirectUrl, $appId, $appSecret);
|
||||
|
||||
$this->rlAppId = '';
|
||||
$this->rlUserHash = '';
|
||||
$this->rlAccount = null;
|
||||
$this->rlStorageProvaider = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function GetRLAppId()
|
||||
{
|
||||
return $this->rlAppId;
|
||||
}
|
||||
|
||||
public function initRainLoopData($config)
|
||||
{
|
||||
if (!empty($config['rlAppId']))
|
||||
{
|
||||
$this->rlAppId = $config['rlAppId'];
|
||||
}
|
||||
|
||||
if (!empty($config['rlStorageProvaider']))
|
||||
{
|
||||
$this->rlStorageProvaider = $config['rlStorageProvaider'];
|
||||
}
|
||||
|
||||
if (!empty($config['rlAccount']))
|
||||
{
|
||||
$this->rlAccount = $config['rlAccount'];
|
||||
}
|
||||
|
||||
if (!empty($config['rlUserHash']))
|
||||
{
|
||||
$this->rlUserHash = (string) $config['rlUserHash'];
|
||||
}
|
||||
|
||||
if (!class_exists('\\RainLoop\\Providers\\Storage\\Enumerations\\StorageType') || '' === $this->rlUserHash)
|
||||
{
|
||||
$this->rlStorageProvaider = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores a state string in session storage for CSRF protection.
|
||||
* Developers should subclass and override this method if they want to store
|
||||
* this state in a different location.
|
||||
*
|
||||
* @param string $state
|
||||
*
|
||||
* @throws FacebookSDKException
|
||||
*/
|
||||
protected function storeState($state)
|
||||
{
|
||||
if ($this->rlStorageProvaider)
|
||||
{
|
||||
$this->rlStorageProvaider->Put(
|
||||
$this->rlAccount ? $this->rlAccount : null,
|
||||
$this->rlAccount ? \RainLoop\Providers\Storage\Enumerations\StorageType::USER :
|
||||
\RainLoop\Providers\Storage\Enumerations\StorageType::NOBODY,
|
||||
$this->generateSessionVariableName(), $state);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads a state string from session storage for CSRF validation. May return
|
||||
* null if no object exists. Developers should subclass and override this
|
||||
* method if they want to load the state from a different location.
|
||||
*
|
||||
* @return string|null
|
||||
*
|
||||
* @throws FacebookSDKException
|
||||
*/
|
||||
protected function loadState()
|
||||
{
|
||||
if ($this->rlStorageProvaider)
|
||||
{
|
||||
$state = $this->rlStorageProvaider->Get(
|
||||
$this->rlAccount ? $this->rlAccount : null,
|
||||
$this->rlAccount ? \RainLoop\Providers\Storage\Enumerations\StorageType::USER :
|
||||
\RainLoop\Providers\Storage\Enumerations\StorageType::NOBODY,
|
||||
$this->generateSessionVariableName(), false);
|
||||
|
||||
if (false !== $state)
|
||||
{
|
||||
$this->state = $state;
|
||||
return $this->state;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private function generateSessionVariableName()
|
||||
{
|
||||
return implode('/', array('Fackebook', \md5($this->rlUserHash), 'Storage'));
|
||||
}
|
||||
}
|
||||
|
|
@ -1,290 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace RainLoop\Config;
|
||||
|
||||
abstract class AbstractConfig
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sFile;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $aData;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $bUseApcCache;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sFileHeader;
|
||||
|
||||
/**
|
||||
* @param string $sFileName
|
||||
* @param string $sFileHeader = ''
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($sFileName, $sFileHeader = '')
|
||||
{
|
||||
$this->sFile = \APP_PRIVATE_DATA.'configs/'.$sFileName;
|
||||
$this->sFileHeader = $sFileHeader;
|
||||
$this->aData = $this->defaultValues();
|
||||
|
||||
$this->bUseApcCache = APP_USE_APC_CACHE &&
|
||||
\MailSo\Base\Utils::FunctionExistsAndEnabled(array('apc_fetch', 'apc_store'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
protected abstract function defaultValues();
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function IsInited()
|
||||
{
|
||||
return \is_array($this->aData) && 0 < \count($this->aData);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sSection
|
||||
* @param string $sName
|
||||
* @param mixed $mDefault = null
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function Get($sSection, $sName, $mDefault = null)
|
||||
{
|
||||
$mResult = $mDefault;
|
||||
if (isset($this->aData[$sSection][$sName][0]))
|
||||
{
|
||||
$mResult = $this->aData[$sSection][$sName][0];
|
||||
}
|
||||
return $mResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sSectionKey
|
||||
* @param string $sParamKey
|
||||
* @param mixed $mParamValue
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function Set($sSectionKey, $sParamKey, $mParamValue)
|
||||
{
|
||||
if (isset($this->aData[$sSectionKey][$sParamKey][0]))
|
||||
{
|
||||
$sType = \gettype($this->aData[$sSectionKey][$sParamKey][0]);
|
||||
switch ($sType)
|
||||
{
|
||||
default:
|
||||
case 'string':
|
||||
$this->aData[$sSectionKey][$sParamKey][0] = (string) $mParamValue;
|
||||
break;
|
||||
case 'int':
|
||||
case 'integer':
|
||||
$this->aData[$sSectionKey][$sParamKey][0] = (int) $mParamValue;
|
||||
break;
|
||||
case 'bool':
|
||||
case 'boolean':
|
||||
$this->aData[$sSectionKey][$sParamKey][0] = (bool) $mParamValue;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if ('custom' === $sSectionKey)
|
||||
{
|
||||
$this->aData[$sSectionKey][$sParamKey] = array((string) $mParamValue);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
private function cacheKey()
|
||||
{
|
||||
return 'config:'.\sha1($this->sFile).':';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
private function loadDataFromCache()
|
||||
{
|
||||
if ($this->bUseApcCache)
|
||||
{
|
||||
$iMTime = @\filemtime($this->sFile);
|
||||
if (\is_int($iMTime) && 0 < $iMTime)
|
||||
{
|
||||
$sKey = $this->cacheKey();
|
||||
|
||||
$iTime = \apc_fetch($sKey.'time');
|
||||
if ($iTime && $iMTime === (int) $iTime)
|
||||
{
|
||||
$aFetchData = \apc_fetch($sKey.'data');
|
||||
if (\is_array($aFetchData))
|
||||
{
|
||||
$this->aData = $aFetchData;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
private function storeDataToCache()
|
||||
{
|
||||
if ($this->bUseApcCache)
|
||||
{
|
||||
$iMTime = @\filemtime($this->sFile);
|
||||
if (\is_int($iMTime) && 0 < $iMTime)
|
||||
{
|
||||
$sKey = $this->cacheKey();
|
||||
|
||||
\apc_store($sKey.'time', $iMTime);
|
||||
\apc_store($sKey.'data', $this->aData);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
private function clearCache()
|
||||
{
|
||||
if ($this->bUseApcCache)
|
||||
{
|
||||
$sKey = $this->cacheKey();
|
||||
|
||||
\apc_delete($sKey.'time');
|
||||
\apc_delete($sKey.'data');
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function Load()
|
||||
{
|
||||
if (\file_exists($this->sFile) && \is_readable($this->sFile))
|
||||
{
|
||||
if ($this->loadDataFromCache())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
$aData = @\parse_ini_file($this->sFile, true);
|
||||
if (\is_array($aData) && 0 < count($aData))
|
||||
{
|
||||
foreach ($aData as $sSectionKey => $aSectionValue)
|
||||
{
|
||||
if (\is_array($aSectionValue))
|
||||
{
|
||||
foreach ($aSectionValue as $sParamKey => $mParamValue)
|
||||
{
|
||||
$this->Set($sSectionKey, $sParamKey, $mParamValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$this->storeDataToCache();
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function Save()
|
||||
{
|
||||
if (\file_exists($this->sFile) && !\is_writable($this->sFile))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
$sNewLine = "\n";
|
||||
|
||||
$aResultLines = array();
|
||||
|
||||
foreach ($this->aData as $sSectionKey => $aSectionValue)
|
||||
{
|
||||
if (\is_array($aSectionValue))
|
||||
{
|
||||
$aResultLines[] = '';
|
||||
$aResultLines[] = '['.$sSectionKey.']';
|
||||
$bFirst = true;
|
||||
|
||||
foreach ($aSectionValue as $sParamKey => $mParamValue)
|
||||
{
|
||||
if (\is_array($mParamValue))
|
||||
{
|
||||
if (!empty($mParamValue[1]))
|
||||
{
|
||||
$sDesk = \str_replace("\r", '', $mParamValue[1]);
|
||||
$aDesk = \explode("\n", $sDesk);
|
||||
$aDesk = \array_map(function (&$sLine) {
|
||||
return '; '.$sLine;
|
||||
}, $aDesk);
|
||||
|
||||
if (!$bFirst)
|
||||
{
|
||||
$aResultLines[] = '';
|
||||
}
|
||||
|
||||
$aResultLines[] = \implode($sNewLine, $aDesk);
|
||||
}
|
||||
|
||||
$bFirst = false;
|
||||
|
||||
$sValue = '""';
|
||||
switch (\gettype($mParamValue[0]))
|
||||
{
|
||||
default:
|
||||
case 'string':
|
||||
$sValue = '"'.$mParamValue[0].'"';
|
||||
break;
|
||||
case 'int':
|
||||
case 'integer':
|
||||
$sValue = $mParamValue[0];
|
||||
break;
|
||||
case 'bool':
|
||||
case 'boolean':
|
||||
$sValue = $mParamValue[0] ? 'On' : 'Off';
|
||||
break;
|
||||
}
|
||||
|
||||
$aResultLines[] = $sParamKey.' = '.$sValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$this->clearCache();
|
||||
return false !== \file_put_contents($this->sFile,
|
||||
(0 < \strlen($this->sFileHeader) ? $this->sFileHeader : '').
|
||||
$sNewLine.\implode($sNewLine, $aResultLines));
|
||||
}
|
||||
}
|
||||
|
|
@ -1,275 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace RainLoop\Config;
|
||||
|
||||
class Application extends \RainLoop\Config\AbstractConfig
|
||||
{
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct('application.ini',
|
||||
'; RainLoop Webmail configuration file
|
||||
; Please don\'t add custom parameters here, those will be overwritten');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sPassword
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function SetPassword($sPassword)
|
||||
{
|
||||
return $this->Set('security', 'admin_password', \md5(APP_SALT.$sPassword.APP_SALT));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sPassword
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function ValidatePassword($sPassword)
|
||||
{
|
||||
$sPassword = (string) $sPassword;
|
||||
$sConfigPassword = (string) $this->Get('security', 'admin_password', '');
|
||||
|
||||
return 0 < \strlen($sPassword) &&
|
||||
($sPassword === $sConfigPassword || \md5(APP_SALT.$sPassword.APP_SALT) === $sConfigPassword);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function Save()
|
||||
{
|
||||
$this->Set('version', 'current', APP_VERSION);
|
||||
$this->Set('version', 'saved', \gmdate('r'));
|
||||
|
||||
return parent::Save();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
protected function defaultValues()
|
||||
{
|
||||
return array(
|
||||
'webmail' => array(
|
||||
|
||||
'title' => array('RainLoop Webmail', 'Text displayed as page title'),
|
||||
'loading_description' => array('RainLoop', 'Text displayed on startup'),
|
||||
|
||||
'theme' => array('Default', 'Theme used by default'),
|
||||
'allow_themes' => array(true, 'Allow theme selection on settings screen'),
|
||||
|
||||
'language' => array('en', 'Language used by default'),
|
||||
'allow_languages_on_settings' => array(true, 'Allow language selection on settings screen'),
|
||||
|
||||
'allow_additional_accounts' => array(true, ''),
|
||||
'allow_identities' => array(true, ''),
|
||||
|
||||
'messages_per_page' => array(20, ' Number of messages displayed on page by default'),
|
||||
|
||||
'editor_default_type' => array('Html', 'Editor mode used by default (Html or Plain)'),
|
||||
|
||||
'attachment_size_limit' => array(25,
|
||||
'File size limit (MB) for file upload on compose screen
|
||||
0 for unlimited.')
|
||||
),
|
||||
|
||||
'branding' => array(
|
||||
'login_logo' => array(''),
|
||||
'login_desc' => array(''),
|
||||
'login_css' => array('')
|
||||
),
|
||||
|
||||
'contacts' => array(
|
||||
'enable' => array(false, 'Enable contacts'),
|
||||
'allow_sharing' => array(true),
|
||||
'allow_sync' => array(false),
|
||||
'sync_interval' => array(20),
|
||||
'type' => array('sqlite', ''),
|
||||
'pdo_dsn' => array('mysql:host=127.0.0.1;port=3306;dbname=rainloop', ''),
|
||||
'pdo_user' => array('root', ''),
|
||||
'pdo_password' => array('', ''),
|
||||
'suggestions_limit' => array(30)
|
||||
),
|
||||
|
||||
'security' => array(
|
||||
'csrf_protection' => array(true,
|
||||
'Enable CSRF protection (http://en.wikipedia.org/wiki/Cross-site_request_forgery)'),
|
||||
|
||||
'custom_server_signature' => array('RainLoop'),
|
||||
'x_frame_options_header' => array(''),
|
||||
'openpgp' => array(false),
|
||||
'use_rsa_encryption' => array(false),
|
||||
'admin_login' => array('admin', 'Login and password for web admin panel'),
|
||||
'admin_password' => array('12345'),
|
||||
'allow_admin_panel' => array(true, 'Access settings'),
|
||||
'allow_two_factor_auth' => array(false),
|
||||
'allow_universal_login' => array(true),
|
||||
'admin_panel_host' => array(''),
|
||||
'core_install_access_domain' => array('')
|
||||
),
|
||||
|
||||
'ssl' => array(
|
||||
'verify_certificate' => array(false, 'Require verification of SSL certificate used.'),
|
||||
'cafile' => array('', 'Location of Certificate Authority file on local filesystem (/etc/ssl/certs/ca-certificates.crt)'),
|
||||
),
|
||||
|
||||
'login' => array(
|
||||
|
||||
'default_domain' => array('', ''),
|
||||
|
||||
'allow_languages_on_login' => array(true,
|
||||
'Allow language selection on webmail login screen'),
|
||||
|
||||
'determine_user_language' => array(true, ''),
|
||||
'determine_user_domain' => array(false, ''),
|
||||
|
||||
'sign_me_auto' => array(\RainLoop\Enumerations\SignMeType::DEFAILT_OFF,
|
||||
'This option allows webmail to remember the logged in user
|
||||
once they closed the browser window.
|
||||
|
||||
Values:
|
||||
"DefaultOff" - can be used, disabled by default;
|
||||
"DefaultOn" - can be used, enabled by default;
|
||||
"Unused" - cannot be used')
|
||||
),
|
||||
|
||||
'plugins' => array(
|
||||
'enable' => array(false, 'Enable plugin support'),
|
||||
'enabled_list' => array('', 'List of enabled plugins'),
|
||||
),
|
||||
|
||||
'logs' => array(
|
||||
|
||||
'enable' => array(false, 'Enable logging'),
|
||||
|
||||
'write_on_error_only' => array(false, 'Logs entire request only if error occured (php requred)'),
|
||||
'write_on_php_error_only' => array(false, 'Logs entire request only if php error occured'),
|
||||
'write_on_timeout_only' => array(0, 'Logs entire request only if request timeout (in seconds) occured.'),
|
||||
|
||||
'hide_passwords' => array(true, 'Required for development purposes only.
|
||||
Disabling this option is not recommended.'),
|
||||
|
||||
'filename' => array('log-{date:Y-m-d}.txt',
|
||||
'Log filename.
|
||||
For security reasons, some characters are removed from filename.
|
||||
Allows for pattern-based folder creation (see examples below).
|
||||
|
||||
Patterns:
|
||||
{date:Y-m-d} - Replaced by pattern-based date
|
||||
Detailed info: http://www.php.net/manual/en/function.date.php
|
||||
{user:email} - Replaced by user\'s email address
|
||||
If user is not logged in, value is set to "unknown"
|
||||
{user:login} - Replaced by user\'s login (the user part of an email)
|
||||
If user is not logged in, value is set to "unknown"
|
||||
{user:domain} - Replaced by user\'s domain name (the domain part of an email)
|
||||
If user is not logged in, value is set to "unknown"
|
||||
{user:uid} - Replaced by user\'s UID regardless of account currently used
|
||||
{user:ip} - Replaced by user\'s IP address
|
||||
|
||||
Examples:
|
||||
filename = "log-{date:Y-m-d}.txt"
|
||||
filename = "{date:Y-m-d}/{user:domain}/{user:email}_{user:uid}.log"
|
||||
filename = "{user:email}-{date:Y-m-d}.txt"')
|
||||
),
|
||||
|
||||
'debug' => array(
|
||||
'enable' => array(false, 'Special option required for development purposes')
|
||||
),
|
||||
|
||||
'version' => array(
|
||||
'current' => array(''),
|
||||
'saved' => array('')
|
||||
),
|
||||
|
||||
'social' => array(
|
||||
'google_enable' => array(false, 'Google'),
|
||||
'google_client_id' => array(''),
|
||||
'google_client_secret' => array(''),
|
||||
'google_api_key' => array(''),
|
||||
|
||||
'fb_enable' => array(false, 'Facebook'),
|
||||
'fb_app_id' => array(''),
|
||||
'fb_app_secret' => array(''),
|
||||
|
||||
'twitter_enable' => array(false, 'Twitter'),
|
||||
'twitter_consumer_key' => array(''),
|
||||
'twitter_consumer_secret' => array(''),
|
||||
|
||||
'dropbox_enable' => array(false, 'Dropbox'),
|
||||
'dropbox_api_key' => array('')
|
||||
),
|
||||
|
||||
'cache' => array(
|
||||
'enable' => array(true,
|
||||
'The section controls caching of the entire application.
|
||||
|
||||
Enables caching in the system'),
|
||||
|
||||
'index' => array('v1', 'Additional caching key. If changed, cache is purged'),
|
||||
|
||||
'fast_cache_driver' => array('files', 'Can be: files, APC, memcache'),
|
||||
'fast_cache_index' => array('v1', 'Additional caching key. If changed, fast cache is purged'),
|
||||
|
||||
'http' => array(true, 'Browser-level cache. If enabled, caching is maintainted without using files'),
|
||||
'server_uids' => array(true, 'Caching message UIDs when searching and sorting (threading)')
|
||||
),
|
||||
|
||||
'labs' => array(
|
||||
'ignore_folders_subscription' => array(false,
|
||||
'Experimental settings. Handle with care.
|
||||
'),
|
||||
'check_new_password_strength' => array(true),
|
||||
'allow_gravatar' => array(true),
|
||||
'allow_prefetch' => array(true),
|
||||
'allow_smart_html_links' => array(true),
|
||||
'cache_system_data' => array(true),
|
||||
'date_from_headers' => array(false),
|
||||
'autocreate_system_folders' => array(true),
|
||||
'allow_message_append' => array(false),
|
||||
'disable_iconv_if_mbstring_supported' => array(false),
|
||||
'login_fault_delay' => array(1),
|
||||
'log_ajax_response_write_limit' => array(300),
|
||||
'allow_html_editor_source_button' => array(false),
|
||||
'hide_dangerous_actions' => array(false),
|
||||
'use_app_debug_js' => array(false),
|
||||
'use_app_debug_css' => array(false),
|
||||
'use_imap_sort' => array(true),
|
||||
'use_imap_esearch_esort' => array(true),
|
||||
'use_imap_force_selection' => array(false),
|
||||
'use_imap_list_subscribe' => array(true),
|
||||
'use_imap_thread' => array(true),
|
||||
'use_imap_move' => array(true),
|
||||
'use_imap_auth_plain' => array(false),
|
||||
'use_imap_expunge_all_on_delete' => array(false),
|
||||
'imap_forwarded_flag' => array('$Forwarded'),
|
||||
'imap_read_receipt_flag' => array('$ReadReceipt'),
|
||||
'imap_body_text_limit' => array(555000),
|
||||
'imap_message_list_fast_simple_search' => array(true),
|
||||
'imap_message_list_count_limit_trigger' => array(0),
|
||||
'imap_message_list_date_filter' => array(0),
|
||||
'imap_large_thread_limit' => array(100),
|
||||
'smtp_show_server_errors' => array(false),
|
||||
'curl_proxy' => array(''),
|
||||
'curl_proxy_auth' => array(''),
|
||||
'in_iframe' => array(false),
|
||||
'force_https' => array(false),
|
||||
'custom_login_link' => array(''),
|
||||
'custom_logout_link' => array(''),
|
||||
'allow_external_login' => array(false),
|
||||
'allow_external_sso' => array(false),
|
||||
'external_sso_key' => array(''),
|
||||
'fast_cache_memcache_host' => array('127.0.0.1'),
|
||||
'fast_cache_memcache_port' => array(11211),
|
||||
'fast_cache_memcache_expire' => array(43200),
|
||||
'use_local_proxy_for_external_images' => array(false),
|
||||
'dev_email' => array(''),
|
||||
'dev_password' => array('')
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,59 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace RainLoop\Config;
|
||||
|
||||
class Plugin extends \RainLoop\Config\AbstractConfig
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $aMap;
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($sPluginName, $aMap = array())
|
||||
{
|
||||
$this->aMap = is_array($aMap) ? $this->convertConfigMap($aMap) : array();
|
||||
|
||||
parent::__construct('plugin-'.$sPluginName.'.ini', '; RainLoop Webmail plugin ('.$sPluginName.')');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $aMap
|
||||
* @return array
|
||||
*/
|
||||
private function convertConfigMap($aMap)
|
||||
{
|
||||
if (0 < count($aMap))
|
||||
{
|
||||
$aResultMap = array();
|
||||
foreach ($aMap as /* @var $oProperty \RainLoop\Plugins\Property */ $oProperty)
|
||||
{
|
||||
if ($oProperty)
|
||||
{
|
||||
$mValue = $oProperty->DefaultValue();
|
||||
$sValue = is_array($mValue) && isset($mValue[0]) ? $mValue[0] : $mValue;
|
||||
$aResultMap[$oProperty->Name()] = array($sValue, '');
|
||||
}
|
||||
}
|
||||
|
||||
if (0 < count($aResultMap))
|
||||
{
|
||||
return array(
|
||||
'plugin' => $aResultMap
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
protected function defaultValues()
|
||||
{
|
||||
return $this->aMap;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,464 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace RainLoop;
|
||||
|
||||
use MailSo\Net\Enumerations\ConnectionSecurityType;
|
||||
|
||||
class Domain
|
||||
{
|
||||
const DEFAULT_FORWARDED_FLAG = '$Forwarded';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sName;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sIncHost;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $iIncPort;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $iIncSecure;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $bIncVerifySsl;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $bIncShortLogin;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sOutHost;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $iOutPort;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $iOutSecure;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $bOutVerifySsl;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $bOutShortLogin;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $bOutAuth;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sWhiteList;
|
||||
|
||||
/**
|
||||
* @param string $sName
|
||||
* @param string $sIncHost
|
||||
* @param int $iIncPort
|
||||
* @param int $iIncSecure
|
||||
* @param bool $bIncVerifySsl
|
||||
* @param bool $bIncShortLogin
|
||||
* @param string $sOutHost
|
||||
* @param int $iOutPort
|
||||
* @param int $iOutSecure
|
||||
* @param bool $bOutVerifySsl
|
||||
* @param bool $bOutShortLogin
|
||||
* @param bool $bOutAuth
|
||||
* @param string $sWhiteList = ''
|
||||
*/
|
||||
private function __construct($sName, $sIncHost, $iIncPort, $iIncSecure, $bIncVerifySsl, $bIncShortLogin,
|
||||
$sOutHost, $iOutPort, $iOutSecure, $bOutVerifySsl, $bOutShortLogin, $bOutAuth, $sWhiteList = '')
|
||||
{
|
||||
$this->sName = $sName;
|
||||
$this->sIncHost = $sIncHost;
|
||||
$this->iIncPort = $iIncPort;
|
||||
$this->iIncSecure = $iIncSecure;
|
||||
$this->bIncVerifySsl = !!$bIncVerifySsl;
|
||||
$this->bIncShortLogin = $bIncShortLogin;
|
||||
$this->sOutHost = $sOutHost;
|
||||
$this->iOutPort = $iOutPort;
|
||||
$this->iOutSecure = $iOutSecure;
|
||||
$this->bOutVerifySsl = !!$bOutVerifySsl;
|
||||
$this->bOutShortLogin = $bOutShortLogin;
|
||||
$this->bOutAuth = $bOutAuth;
|
||||
$this->sWhiteList = \trim($sWhiteList);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sName
|
||||
* @param string $sIncHost
|
||||
* @param int $iIncPort
|
||||
* @param int $iIncSecure
|
||||
* @param bool $bIncVerifySsl
|
||||
* @param bool $bIncShortLogin
|
||||
* @param string $sOutHost
|
||||
* @param int $iOutPort
|
||||
* @param int $iOutSecure
|
||||
* @param bool $bOutVerifySsl
|
||||
* @param bool $bOutShortLogin
|
||||
* @param bool $bOutAuth
|
||||
* @param string $sWhiteList = ''
|
||||
*
|
||||
* @return \RainLoop\Domain
|
||||
*/
|
||||
public static function NewInstance($sName,
|
||||
$sIncHost, $iIncPort, $iIncSecure, $bIncVerifySsl, $bIncShortLogin,
|
||||
$sOutHost, $iOutPort, $iOutSecure, $bOutVerifySsl, $bOutShortLogin, $bOutAuth,
|
||||
$sWhiteList = '')
|
||||
{
|
||||
return new self($sName,
|
||||
$sIncHost, $iIncPort, $iIncSecure, $bIncVerifySsl, $bIncShortLogin,
|
||||
$sOutHost, $iOutPort, $iOutSecure, $bOutVerifySsl, $bOutShortLogin, $bOutAuth,
|
||||
$sWhiteList);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sName
|
||||
* @param array $aDomain
|
||||
*
|
||||
* @return \RainLoop\Domain|null
|
||||
*/
|
||||
public static function NewInstanceFromDomainConfigArray($sName, $aDomain)
|
||||
{
|
||||
$oDomain = null;
|
||||
|
||||
if (0 < \strlen($sName) && \is_array($aDomain) && 0 < \strlen($aDomain['imap_host']) && 0 < \strlen($aDomain['imap_port']) &&
|
||||
0 < \strlen($aDomain['smtp_host']) && 0 < \strlen($aDomain['smtp_port']))
|
||||
{
|
||||
$sIncHost = (string) $aDomain['imap_host'];
|
||||
$iIncPort = (int) $aDomain['imap_port'];
|
||||
$iIncSecure = self::StrConnectionSecurityTypeToCons(
|
||||
!empty($aDomain['imap_secure']) ? $aDomain['imap_secure'] : '');
|
||||
|
||||
$bIncVerifySsl = isset($aDomain['imap_verify_ssl']) ? (bool) $aDomain['smtp_verify_ssl'] : false;;
|
||||
|
||||
$sOutHost = (string) $aDomain['smtp_host'];
|
||||
$iOutPort = (int) $aDomain['smtp_port'];
|
||||
$iOutSecure = self::StrConnectionSecurityTypeToCons(
|
||||
!empty($aDomain['smtp_secure']) ? $aDomain['smtp_secure'] : '');
|
||||
|
||||
$bOutVerifySsl = isset($aDomain['smtp_verify_ssl']) ? (bool) $aDomain['smtp_verify_ssl'] : false;
|
||||
|
||||
$bOutAuth = isset($aDomain['smtp_auth']) ? (bool) $aDomain['smtp_auth'] : true;
|
||||
$sWhiteList = (string) (isset($aDomain['white_list']) ? $aDomain['white_list'] : '');
|
||||
|
||||
$bIncShortLogin = isset($aDomain['imap_short_login']) ? (bool) $aDomain['imap_short_login'] : false;
|
||||
$bOutShortLogin = isset($aDomain['smtp_short_login']) ? (bool) $aDomain['smtp_short_login'] : false;
|
||||
|
||||
$oDomain = self::NewInstance($sName,
|
||||
$sIncHost, $iIncPort, $iIncSecure, $bIncVerifySsl, $bIncShortLogin,
|
||||
$sOutHost, $iOutPort, $iOutSecure, $bOutVerifySsl, $bOutShortLogin, $bOutAuth,
|
||||
$sWhiteList);
|
||||
}
|
||||
|
||||
return $oDomain;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sStr
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function encodeIniString($sStr)
|
||||
{
|
||||
return str_replace('"', '\\"', $sStr);
|
||||
}
|
||||
|
||||
public function Normalize()
|
||||
{
|
||||
$this->sIncHost = \trim($this->sIncHost);
|
||||
$this->sOutHost = \trim($this->sOutHost);
|
||||
$this->sWhiteList = \trim($this->sWhiteList);
|
||||
|
||||
if ($this->iIncPort <= 0)
|
||||
{
|
||||
$this->iIncPort = 143;
|
||||
}
|
||||
|
||||
if ($this->iOutPort <= 0)
|
||||
{
|
||||
$this->iOutPort = 25;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function ToIniString()
|
||||
{
|
||||
$this->Normalize();
|
||||
return implode("\n", array(
|
||||
'imap_host = "'.$this->encodeIniString($this->sIncHost).'"',
|
||||
'imap_port = '.$this->iIncPort,
|
||||
'imap_secure = "'.self::ConstConnectionSecurityTypeToStr($this->iIncSecure).'"',
|
||||
'imap_verify_ssl = '.($this->bIncVerifySsl ? 'On' : 'Off'),
|
||||
'imap_short_login = '.($this->bIncShortLogin ? 'On' : 'Off'),
|
||||
'smtp_host = "'.$this->encodeIniString($this->sOutHost).'"',
|
||||
'smtp_port = '.$this->iOutPort,
|
||||
'smtp_secure = "'.self::ConstConnectionSecurityTypeToStr($this->iOutSecure).'"',
|
||||
'smtp_verify_ssl = '.($this->bOutVerifySsl ? 'On' : 'Off'),
|
||||
'smtp_short_login = '.($this->bOutShortLogin ? 'On' : 'Off'),
|
||||
'smtp_auth = '.($this->bOutAuth ? 'On' : 'Off'),
|
||||
'white_list = "'.$this->encodeIniString($this->sWhiteList).'"'
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sType
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public static function StrConnectionSecurityTypeToCons($sType)
|
||||
{
|
||||
$iSecurityType = ConnectionSecurityType::NONE;
|
||||
switch (strtoupper($sType))
|
||||
{
|
||||
case 'SSL':
|
||||
$iSecurityType = ConnectionSecurityType::SSL;
|
||||
break;
|
||||
case 'TLS':
|
||||
$iSecurityType = ConnectionSecurityType::STARTTLS;
|
||||
break;
|
||||
}
|
||||
return $iSecurityType;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $iSecurityType
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function ConstConnectionSecurityTypeToStr($iSecurityType)
|
||||
{
|
||||
$sType = 'None';
|
||||
switch ($iSecurityType)
|
||||
{
|
||||
case ConnectionSecurityType::SSL:
|
||||
$sType = 'SSL';
|
||||
break;
|
||||
case ConnectionSecurityType::STARTTLS:
|
||||
$sType = 'TLS';
|
||||
break;
|
||||
}
|
||||
|
||||
return $sType;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sIncHost
|
||||
* @param int $iIncPort
|
||||
* @param int $iIncSecure
|
||||
* @param bool $bIncVerifySsl
|
||||
* @param bool $bIncShortLogin
|
||||
* @param string $sOutHost
|
||||
* @param int $iOutPort
|
||||
* @param int $iOutSecure
|
||||
* @param bool $bOutVerifySsl
|
||||
* @param bool $bOutShortLogin
|
||||
* @param bool $bOutAuth
|
||||
* @param string $sWhiteList = ''
|
||||
*
|
||||
* @return \RainLoop\Domain
|
||||
*/
|
||||
public function UpdateInstance(
|
||||
$sIncHost, $iIncPort, $iIncSecure, $bIncVerifySsl, $bIncShortLogin,
|
||||
$sOutHost, $iOutPort, $iOutSecure, $bOutVerifySsl, $bOutShortLogin, $bOutAuth,
|
||||
$sWhiteList = '')
|
||||
{
|
||||
$this->sIncHost = \MailSo\Base\Utils::IdnToAscii($sIncHost);
|
||||
$this->iIncPort = $iIncPort;
|
||||
$this->iIncSecure = $iIncSecure;
|
||||
$this->bIncVerifySsl = !!$bIncVerifySsl;
|
||||
$this->bIncShortLogin = $bIncShortLogin;
|
||||
$this->sOutHost = \MailSo\Base\Utils::IdnToAscii($sOutHost);
|
||||
$this->iOutPort = $iOutPort;
|
||||
$this->iOutSecure = $iOutSecure;
|
||||
$this->bOutVerifySsl = !!$bOutVerifySsl;
|
||||
$this->bOutShortLogin = $bOutShortLogin;
|
||||
$this->bOutAuth = $bOutAuth;
|
||||
$this->sWhiteList = \trim($sWhiteList);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function Name()
|
||||
{
|
||||
return $this->sName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sRealDomainName = ''
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function IncHost($sRealDomainName = '')
|
||||
{
|
||||
return 0 < \strlen($sRealDomainName) ? \str_replace('{domain:name}', $sRealDomainName, $this->sIncHost) : $this->sIncHost;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function IncPort()
|
||||
{
|
||||
return $this->iIncPort;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function IncSecure()
|
||||
{
|
||||
return $this->iIncSecure;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool|null $bGlobalVerify = null
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function IncVerifySsl($bGlobalVerify = null)
|
||||
{
|
||||
return null === $bGlobalVerify ? $this->bIncVerifySsl : !!$bGlobalVerify;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function IncShortLogin()
|
||||
{
|
||||
return $this->bIncShortLogin;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sRealDomainName = ''
|
||||
* @return string
|
||||
*/
|
||||
public function OutHost($sRealDomainName = '')
|
||||
{
|
||||
return 0 < \strlen($sRealDomainName) ? \str_replace('{domain:name}', $sRealDomainName, $this->sOutHost) : $this->sOutHost;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function OutPort()
|
||||
{
|
||||
return $this->iOutPort;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function OutSecure()
|
||||
{
|
||||
return $this->iOutSecure;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool|null $bGlobalVerify = null
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function OutVerifySsl($bGlobalVerify = null)
|
||||
{
|
||||
return null === $bGlobalVerify ? $this->bOutVerifySsl : !!$bGlobalVerify;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function OutShortLogin()
|
||||
{
|
||||
return $this->bOutShortLogin;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function OutAuth()
|
||||
{
|
||||
return $this->bOutAuth;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function WhiteList()
|
||||
{
|
||||
return $this->sWhiteList;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sEmail
|
||||
* @param string $sLogin = ''
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function ValidateWhiteList($sEmail, $sLogin = '')
|
||||
{
|
||||
$sW = \trim($this->sWhiteList);
|
||||
if (0 < strlen($sW))
|
||||
{
|
||||
$sEmail = \MailSo\Base\Utils::IdnToUtf8($sEmail, true);
|
||||
$sLogin = \MailSo\Base\Utils::IdnToUtf8($sLogin);
|
||||
|
||||
$sW = \preg_replace('/([^\s]+)@[^\s]*/', '$1', $sW);
|
||||
$sW = ' '.\trim(\preg_replace('/[\s;,\r\n\t]+/', ' ', $sW)).' ';
|
||||
|
||||
$sUserPart = \MailSo\Base\Utils::GetAccountNameFromEmail(0 < \strlen($sLogin) ? $sLogin : $sEmail);
|
||||
return false !== \strpos($sW, ' '.$sUserPart.' ');
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $bAjax = false
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function ToSimpleJSON($bAjax = false)
|
||||
{
|
||||
return array(
|
||||
'Name' => $bAjax ? \MailSo\Base\Utils::IdnToUtf8($this->Name()) : $this->Name(),
|
||||
'IncHost' => $bAjax ? \MailSo\Base\Utils::IdnToUtf8($this->IncHost()) : $this->IncHost(),
|
||||
'IncPort' => $this->IncPort(),
|
||||
'IncSecure' => $this->IncSecure(),
|
||||
'IncVerifySsl' => $this->IncVerifySsl(),
|
||||
'IncShortLogin' => $this->IncShortLogin(),
|
||||
'OutHost' => $bAjax ? \MailSo\Base\Utils::IdnToUtf8($this->OutHost()) : $this->OutHost(),
|
||||
'OutPort' => $this->OutPort(),
|
||||
'OutSecure' => $this->OutSecure(),
|
||||
'OutVerifySsl' => $this->OutVerifySsl(),
|
||||
'OutShortLogin' => $this->OutShortLogin(),
|
||||
'OutAuth' => $this->OutAuth(),
|
||||
'WhiteList' => $this->WhiteList()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,16 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace RainLoop\Enumerations;
|
||||
|
||||
class Capa
|
||||
{
|
||||
const PREM = 'PREM';
|
||||
const TWO_FACTOR = 'TWO_FACTOR';
|
||||
const OPEN_PGP = 'OPEN_PGP';
|
||||
const PREFETCH = 'PREFETCH';
|
||||
const GRAVATAR = 'GRAVATAR';
|
||||
const THEMES = 'THEMES';
|
||||
const FILTERS = 'FILTERS';
|
||||
const ADDITIONAL_ACCOUNTS = 'ADDITIONAL_ACCOUNTS';
|
||||
const ADDITIONAL_IDENTITIES = 'ADDITIONAL_IDENTITIES';
|
||||
}
|
||||
|
|
@ -1,10 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace RainLoop\Enumerations;
|
||||
|
||||
class InterfaceAnimation
|
||||
{
|
||||
const NONE = 'None';
|
||||
const NORMAL = 'Normal';
|
||||
const FULL = 'Full';
|
||||
}
|
||||
|
|
@ -1,10 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace RainLoop\Enumerations;
|
||||
|
||||
class Layout
|
||||
{
|
||||
const NO_PREVIW = 0;
|
||||
const SIDE_PREVIEW = 1;
|
||||
const BOTTOM_PREVIEW = 2;
|
||||
}
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace RainLoop\Enumerations;
|
||||
|
||||
class PluginPropertyType
|
||||
{
|
||||
const STRING = 0;
|
||||
const INT = 1;
|
||||
const STRING_TEXT = 2;
|
||||
const PASSWORD = 3;
|
||||
const SELECTION = 4;
|
||||
const BOOL = 5;
|
||||
}
|
||||
|
|
@ -1,10 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace RainLoop\Enumerations;
|
||||
|
||||
class SignMeType
|
||||
{
|
||||
const DEFAILT_OFF = 'DefaultOff';
|
||||
const DEFAILT_ON = 'DefaultOn';
|
||||
const UNUSED = 'Unused';
|
||||
}
|
||||
|
|
@ -1,9 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace RainLoop\Enumerations;
|
||||
|
||||
class TimeFormat
|
||||
{
|
||||
const F12 = '12';
|
||||
const F24 = '24';
|
||||
}
|
||||
|
|
@ -1,16 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace RainLoop\Enumerations;
|
||||
|
||||
class UploadClientError
|
||||
{
|
||||
const NORMAL = 0;
|
||||
const FILE_IS_TOO_BIG = 1;
|
||||
const FILE_PARTIALLY_UPLOADED = 2;
|
||||
const FILE_NO_UPLOADED = 3;
|
||||
const MISSING_TEMP_FOLDER = 4;
|
||||
const FILE_ON_SAVING_ERROR = 5;
|
||||
const FILE_TYPE = 98;
|
||||
const UNKNOWN = 99;
|
||||
}
|
||||
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace RainLoop\Enumerations;
|
||||
|
||||
class UploadError
|
||||
{
|
||||
const UNKNOWN = 1000;
|
||||
const CONFIG_SIZE = 1001;
|
||||
const ON_SAVING = 1002;
|
||||
const EMPTY_FILES_DATA = 1003;
|
||||
const FILE_TYPE = 1004;
|
||||
}
|
||||
|
||||
|
|
@ -1,15 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace RainLoop\Exceptions;
|
||||
|
||||
/**
|
||||
* @category RainLoop
|
||||
* @package Exceptions
|
||||
*/
|
||||
class ClientException extends Exception
|
||||
{
|
||||
public function __construct($iCode, $oPrevious = null)
|
||||
{
|
||||
parent::__construct(\RainLoop\Notifications::GetNotificationsMessage($iCode, $oPrevious), $iCode, $oPrevious);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace RainLoop\Exceptions;
|
||||
|
||||
class Exception extends \Exception {}
|
||||
|
|
@ -1,9 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace RainLoop\Exceptions;
|
||||
|
||||
/**
|
||||
* @category RainLoop
|
||||
* @package Exceptions
|
||||
*/
|
||||
class InvalidArgumentException extends Exception {}
|
||||
|
|
@ -1,9 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace RainLoop\Exceptions;
|
||||
|
||||
/**
|
||||
* @category RainLoop
|
||||
* @package Exceptions
|
||||
*/
|
||||
class RuntimeException extends Exception {}
|
||||
|
|
@ -1,179 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace RainLoop;
|
||||
|
||||
class Identity
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sId;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sEmail;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sName;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sReplyTo;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sBcc;
|
||||
|
||||
/**
|
||||
* @param string $sId
|
||||
* @param string $sEmail
|
||||
* @param string $sName
|
||||
* @param string $sReplyTo
|
||||
* @param string $sBcc
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function __construct($sId, $sEmail, $sName, $sReplyTo, $sBcc)
|
||||
{
|
||||
$this->sId = $sId;
|
||||
$this->sEmail = \MailSo\Base\Utils::IdnToAscii($sEmail, true);
|
||||
$this->sName = \trim($sName);
|
||||
$this->sReplyTo = \trim($sReplyTo);
|
||||
$this->sBcc = \trim($sBcc);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sId
|
||||
* @param string $sEmail
|
||||
* @param string $sName = ''
|
||||
* @param string $sReplyTo = ''
|
||||
* @param string $sBcc = ''
|
||||
*
|
||||
* @return \RainLoop\Identity
|
||||
*/
|
||||
public static function NewInstance($sId, $sEmail, $sName = '', $sReplyTo = '', $sBcc = '')
|
||||
{
|
||||
return new self($sId, $sEmail, $sName, $sReplyTo, $sBcc);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function Id()
|
||||
{
|
||||
return $this->sId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sId
|
||||
*
|
||||
* @return \RainLoop\Identity
|
||||
*/
|
||||
public function SetId($sId)
|
||||
{
|
||||
$this->sId = $sId;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function Email()
|
||||
{
|
||||
return $this->sEmail;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sEmail
|
||||
*
|
||||
* @return \RainLoop\Identity
|
||||
*/
|
||||
public function SetEmail($sEmail)
|
||||
{
|
||||
$this->sEmail = \MailSo\Base\Utils::IdnToAscii($sEmail, true);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function Name()
|
||||
{
|
||||
return $this->sName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sName
|
||||
*
|
||||
* @return \RainLoop\Identity
|
||||
*/
|
||||
public function SetName($sName)
|
||||
{
|
||||
$this->sName = $sName;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function ReplyTo()
|
||||
{
|
||||
return $this->sReplyTo;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sReplyTo
|
||||
*
|
||||
* @return \RainLoop\Identity
|
||||
*/
|
||||
public function SetReplyTo($sReplyTo)
|
||||
{
|
||||
$this->sReplyTo = $sReplyTo;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function Bcc()
|
||||
{
|
||||
return $this->sBcc;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sBcc
|
||||
*
|
||||
* @return \RainLoop\Identity
|
||||
*/
|
||||
public function SetBcc($sBcc)
|
||||
{
|
||||
$this->sBcc = $sBcc;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $bAjax = false
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function ToSimpleJSON($bAjax = false)
|
||||
{
|
||||
return array(
|
||||
'Id' => $this->Id(),
|
||||
'Email' => $bAjax ? \MailSo\Base\Utils::IdnToUtf8($this->Email()) : $this->Email(),
|
||||
'Name' => $this->Name(),
|
||||
'ReplyTo' => $this->ReplyTo(),
|
||||
'Bcc' => $this->Bcc()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,142 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace RainLoop;
|
||||
|
||||
class KeyPathHelper
|
||||
{
|
||||
/**
|
||||
* @param string $sEmail
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
static public function TwoFactorAuthUserData($sEmail)
|
||||
{
|
||||
return 'TwoFactorAuth/User/'.$sEmail.'/Data/';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sEmail
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
static public function WebmailAccounts($sEmail)
|
||||
{
|
||||
return 'Webmail/Accounts/'.$sEmail.'/Array';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sSsoHash
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
static public function SsoCacherKey($sSsoHash)
|
||||
{
|
||||
return '/Sso/Data/'.$sSsoHash.'/Login/';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sHash
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
static public function RsaCacherKey($sHash)
|
||||
{
|
||||
return '/Rsa/Data/'.$sHash.'/';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sSignMeToken
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
static public function SignMeUserToken($sSignMeToken)
|
||||
{
|
||||
return '/SignMe/UserToken/'.$sSignMeToken;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sDomain
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
static public function LicensingDomainKeyValue($sDomain)
|
||||
{
|
||||
return '/Licensing/DomainKey/Value/'.$sDomain;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sRepo
|
||||
* @param string $sRepoFile
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
static public function RepositoryCacheFile($sRepo, $sRepoFile)
|
||||
{
|
||||
return '/RepositoryCache/Repo/'.$sRepo.'/File/'.$sRepoFile;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sRepo
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
static public function RepositoryCacheCore($sRepo)
|
||||
{
|
||||
return '/RepositoryCache/CoreRepo/'.$sRepo;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sEmail
|
||||
* @param string $sFolderFullName
|
||||
* @param string $sUid
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
static public function ReadReceiptCache($sEmail, $sFolderFullName, $sUid)
|
||||
{
|
||||
return '/ReadReceipt/'.$sEmail.'/'.$sFolderFullName.'/'.$sUid;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sLanguage
|
||||
* @param string $sPluginsHash
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
static public function LangCache($sLanguage, $sPluginsHash)
|
||||
{
|
||||
return '/LangCache/'.$sPluginsHash.'/'.$sLanguage.'/'.APP_VERSION.'/';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $bAdmin
|
||||
* @param string $sPluginsHash
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
static public function TemplatesCache($bAdmin, $sPluginsHash)
|
||||
{
|
||||
return '/TemplatesCache/'.$sPluginsHash.'/'.($bAdmin ? 'Admin' : 'App').'/'.APP_VERSION.'/';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sPluginsHash
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
static public function PluginsJsCache($sPluginsHash)
|
||||
{
|
||||
return '/PluginsJsCache/'.$sPluginsHash.'/'.APP_VERSION.'/';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sTheme
|
||||
* @param string $sPluginsHash
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
static public function CssCache($sTheme, $sPluginsHash)
|
||||
{
|
||||
return '/CssCache/'.$sPluginsHash.'/'.$sTheme.'/'.APP_VERSION.'/';
|
||||
}
|
||||
}
|
||||
|
|
@ -1,141 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace RainLoop;
|
||||
|
||||
class Notifications
|
||||
{
|
||||
const InvalidToken = 101;
|
||||
const AuthError = 102;
|
||||
const AccessError = 103;
|
||||
const ConnectionError = 104;
|
||||
const CaptchaError = 105;
|
||||
const SocialFacebookLoginAccessDisable = 106;
|
||||
const SocialTwitterLoginAccessDisable = 107;
|
||||
const SocialGoogleLoginAccessDisable = 108;
|
||||
const DomainNotAllowed = 109;
|
||||
const AccountNotAllowed = 110;
|
||||
|
||||
const AccountTwoFactorAuthRequired = 120;
|
||||
const AccountTwoFactorAuthError = 121;
|
||||
|
||||
const CouldNotSaveNewPassword = 130;
|
||||
const CurrentPasswordIncorrect = 131;
|
||||
const NewPasswordShort = 132;
|
||||
const NewPasswordWeak = 133;
|
||||
const NewPasswordForbidden = 134;
|
||||
|
||||
const ContactsSyncError = 140;
|
||||
|
||||
const CantGetMessageList = 201;
|
||||
const CantGetMessage = 202;
|
||||
const CantDeleteMessage = 203;
|
||||
const CantMoveMessage = 204;
|
||||
const CantCopyMessage = 205;
|
||||
|
||||
const CantSaveMessage = 301;
|
||||
const CantSendMessage = 302;
|
||||
const InvalidRecipients = 303;
|
||||
|
||||
const CantCreateFolder = 400;
|
||||
const CantRenameFolder = 401;
|
||||
const CantDeleteFolder = 402;
|
||||
const CantSubscribeFolder = 403;
|
||||
const CantUnsubscribeFolder = 404;
|
||||
const CantDeleteNonEmptyFolder = 405;
|
||||
|
||||
const CantSaveSettings = 501;
|
||||
const CantSavePluginSettings = 502;
|
||||
|
||||
const DomainAlreadyExists = 601;
|
||||
|
||||
const CantInstallPackage = 701;
|
||||
const CantDeletePackage = 702;
|
||||
const InvalidPluginPackage = 703;
|
||||
const UnsupportedPluginPackage = 704;
|
||||
|
||||
const LicensingServerIsUnavailable = 710;
|
||||
const LicensingExpired = 711;
|
||||
const LicensingBanned = 712;
|
||||
|
||||
const DemoSendMessageError = 750;
|
||||
|
||||
const AccountAlreadyExists = 801;
|
||||
|
||||
const MailServerError = 901;
|
||||
const ClientViewError = 902;
|
||||
const InvalidInputArgument = 903;
|
||||
const UnknownNotification = 998;
|
||||
const UnknownError = 999;
|
||||
|
||||
/**
|
||||
* @staticvar array $aMap
|
||||
*
|
||||
* @param int $iCode
|
||||
* @param \Exception|null $oPrevious
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
static public function GetNotificationsMessage($iCode, $oPrevious = null)
|
||||
{
|
||||
static $aMap = array(
|
||||
self::InvalidToken => 'InvalidToken',
|
||||
self::AuthError => 'AuthError',
|
||||
self::AccessError => 'AccessError',
|
||||
self::ConnectionError => 'ConnectionError',
|
||||
self::CaptchaError => 'CaptchaError',
|
||||
self::SocialFacebookLoginAccessDisable => 'SocialFacebookLoginAccessDisable',
|
||||
self::SocialTwitterLoginAccessDisable => 'SocialTwitterLoginAccessDisable',
|
||||
self::SocialGoogleLoginAccessDisable => 'SocialGoogleLoginAccessDisable',
|
||||
self::DomainNotAllowed => 'DomainNotAllowed',
|
||||
self::AccountNotAllowed => 'AccountNotAllowed',
|
||||
self::AccountTwoFactorAuthRequired => 'AccountTwoFactorAuthRequired',
|
||||
self::AccountTwoFactorAuthError => 'AccountTwoFactorAuthError',
|
||||
|
||||
self::CouldNotSaveNewPassword => 'CouldNotSaveNewPassword',
|
||||
self::CurrentPasswordIncorrect => 'CurrentPasswordIncorrect',
|
||||
self::NewPasswordShort => 'NewPasswordShort',
|
||||
self::NewPasswordWeak => 'NewPasswordWeak',
|
||||
self::NewPasswordForbidden => 'NewPasswordForbidden',
|
||||
|
||||
self::ContactsSyncError => 'ContactsSyncError',
|
||||
|
||||
self::CantGetMessageList => 'CantGetMessageList',
|
||||
self::CantGetMessage => 'CantGetMessage',
|
||||
self::CantDeleteMessage => 'CantDeleteMessage',
|
||||
self::CantMoveMessage => 'CantMoveMessage',
|
||||
self::CantSaveMessage => 'CantSaveMessage',
|
||||
self::CantSendMessage => 'CantSendMessage',
|
||||
self::InvalidRecipients => 'InvalidRecipients',
|
||||
self::CantCreateFolder => 'CantCreateFolder',
|
||||
self::CantRenameFolder => 'CantRenameFolder',
|
||||
self::CantDeleteFolder => 'CantDeleteFolder',
|
||||
self::CantSubscribeFolder => 'CantSubscribeFolder',
|
||||
self::CantUnsubscribeFolder => 'CantUnsubscribeFolder',
|
||||
self::CantDeleteNonEmptyFolder => 'CantDeleteNonEmptyFolder',
|
||||
self::CantSaveSettings => 'CantSaveSettings',
|
||||
self::CantSavePluginSettings => 'CantSavePluginSettings',
|
||||
self::DomainAlreadyExists => 'DomainAlreadyExists',
|
||||
self::CantInstallPackage => 'CantInstallPackage',
|
||||
self::CantDeletePackage => 'CantDeletePackage',
|
||||
self::InvalidPluginPackage => 'InvalidPluginPackage',
|
||||
self::UnsupportedPluginPackage => 'UnsupportedPluginPackage',
|
||||
self::LicensingServerIsUnavailable => 'LicensingServerIsUnavailable',
|
||||
self::LicensingExpired => 'LicensingExpired',
|
||||
self::LicensingBanned => 'LicensingBanned',
|
||||
self::DemoSendMessageError => 'DemoSendMessageError',
|
||||
self::AccountAlreadyExists => 'AccountAlreadyExists',
|
||||
self::MailServerError => 'MailServerError',
|
||||
self::ClientViewError => 'ClientViewError',
|
||||
self::InvalidInputArgument => 'InvalidInputArgument',
|
||||
self::UnknownNotification => 'UnknownNotification',
|
||||
self::UnknownError => 'UnknownError'
|
||||
);
|
||||
|
||||
if (self::ClientViewError === $iCode && $oPrevious instanceof \Exception)
|
||||
{
|
||||
return $oPrevious->getMessage();
|
||||
}
|
||||
|
||||
return isset($aMap[$iCode]) ? $aMap[$iCode].'['.$iCode.']' : 'UnknownNotification['.$iCode.']';
|
||||
}
|
||||
}
|
||||
|
|
@ -1,338 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace RainLoop\Plugins;
|
||||
|
||||
abstract class AbstractPlugin
|
||||
{
|
||||
/**
|
||||
* @var \RainLoop\Plugins\Manager
|
||||
*/
|
||||
private $oPluginManager;
|
||||
|
||||
/**
|
||||
* @var \RainLoop\Config\Plugin
|
||||
*/
|
||||
private $oPluginConfig;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $bLangs;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sName;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sPath;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sVersion;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $aConfigMap;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $bPluginConfigLoaded;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->sName = '';
|
||||
$this->sPath = '';
|
||||
$this->sVersion = '0.0';
|
||||
$this->aConfigMap = null;
|
||||
|
||||
$this->oPluginManager = null;
|
||||
$this->oPluginConfig = null;
|
||||
$this->bPluginConfigLoaded = false;
|
||||
$this->bLangs = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \RainLoop\Config\Plugin
|
||||
*/
|
||||
public function Config()
|
||||
{
|
||||
if (!$this->bPluginConfigLoaded && $this->oPluginConfig)
|
||||
{
|
||||
$this->bPluginConfigLoaded = true;
|
||||
if ($this->oPluginConfig->IsInited())
|
||||
{
|
||||
if (!$this->oPluginConfig->Load())
|
||||
{
|
||||
$this->oPluginConfig->Save();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $this->oPluginConfig;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \RainLoop\Plugins\Manager
|
||||
*/
|
||||
public function Manager()
|
||||
{
|
||||
return $this->oPluginManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function Path()
|
||||
{
|
||||
return $this->sPath;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function Name()
|
||||
{
|
||||
return $this->sName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function Version()
|
||||
{
|
||||
return $this->sVersion;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool | null $bLangs = null
|
||||
* @return bool
|
||||
*/
|
||||
public function UseLangs($bLangs = null)
|
||||
{
|
||||
if (null !== $bLangs)
|
||||
{
|
||||
$this->bLangs = (bool) $bLangs;
|
||||
}
|
||||
|
||||
return $this->bLangs;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
protected function configMapping()
|
||||
{
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function Hash()
|
||||
{
|
||||
return \md5($this->sVersion);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function Supported()
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* @final
|
||||
* @return array
|
||||
*/
|
||||
final public function ConfigMap()
|
||||
{
|
||||
if (null === $this->aConfigMap)
|
||||
{
|
||||
$this->aConfigMap = $this->configMapping();
|
||||
if (!is_array($this->aConfigMap))
|
||||
{
|
||||
$this->aConfigMap = array();
|
||||
}
|
||||
}
|
||||
|
||||
return $this->aConfigMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sPath
|
||||
* @param string $sName
|
||||
* @param string $sVersion = ''
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function SetValues($sPath, $sName, $sVersion = '')
|
||||
{
|
||||
$this->sName = $sName;
|
||||
$this->sPath = $sPath;
|
||||
|
||||
if (0 < \strlen($sVersion))
|
||||
{
|
||||
$this->sVersion = $sVersion;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \RainLoop\Plugins\Manager $oPluginManager
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function SetPluginManager(\RainLoop\Plugins\Manager $oPluginManager)
|
||||
{
|
||||
$this->oPluginManager = $oPluginManager;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \RainLoop\Config\Plugin $oPluginConfig
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function SetPluginConfig(\RainLoop\Config\Plugin $oPluginConfig)
|
||||
{
|
||||
$this->oPluginConfig = $oPluginConfig;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function PreInit()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function Init()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $bAdmin
|
||||
* @param bool $bAuth
|
||||
* @param array $aConfig
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function FilterAppDataPluginSection($bAdmin, $bAuth, &$aConfig)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sHookName
|
||||
* @param string $sFunctionName
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
protected function addHook($sHookName, $sFunctionName)
|
||||
{
|
||||
if ($this->oPluginManager)
|
||||
{
|
||||
$this->oPluginManager->AddHook($sHookName, array(&$this, $sFunctionName));
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sFile
|
||||
* @param bool $bAdminScope = false
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
protected function addJs($sFile, $bAdminScope = false)
|
||||
{
|
||||
if ($this->oPluginManager)
|
||||
{
|
||||
$this->oPluginManager->AddJs($this->sPath.'/'.$sFile, $bAdminScope);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sFile
|
||||
* @param bool $bAdminScope = false
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
protected function addTemplate($sFile, $bAdminScope = false)
|
||||
{
|
||||
if ($this->oPluginManager)
|
||||
{
|
||||
$this->oPluginManager->AddTemplate($this->sPath.'/'.$sFile, $bAdminScope);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sActionName
|
||||
* @param string $sFunctionName
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
protected function addPartHook($sActionName, $sFunctionName)
|
||||
{
|
||||
if ($this->oPluginManager)
|
||||
{
|
||||
$this->oPluginManager->AddAdditionalPartAction($sActionName, array(&$this, $sFunctionName));
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sActionName
|
||||
* @param string $sFunctionName
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
protected function addAjaxHook($sActionName, $sFunctionName)
|
||||
{
|
||||
if ($this->oPluginManager)
|
||||
{
|
||||
$this->oPluginManager->AddAdditionalAjaxAction($sActionName, array(&$this, $sFunctionName));
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sName
|
||||
* @param string $sPlace
|
||||
* @param string $sHtml
|
||||
* @param bool $bPrepend = false
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
protected function addTemplateHook($sName, $sPlace, $sLocalTemplateName, $bPrepend = false)
|
||||
{
|
||||
if ($this->oPluginManager)
|
||||
{
|
||||
$this->oPluginManager->AddProcessTemplateAction($sName, $sPlace,
|
||||
'<!-- ko template: \''.$sLocalTemplateName.'\' --><!-- /ko -->', $bPrepend);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,73 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace RainLoop\Plugins;
|
||||
|
||||
class Helper
|
||||
{
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
private function __construct()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sString
|
||||
* @param string $sWildcardValues
|
||||
* @param string $sFoundedValue = ''
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
static public function ValidateWildcardValues($sString, $sWildcardValues, &$sFoundedValue = '')
|
||||
{
|
||||
$sFoundedValue = '';
|
||||
|
||||
$sString = \trim($sString);
|
||||
if ('' === $sString)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
$sWildcardValues = \trim($sWildcardValues);
|
||||
if ('' === $sWildcardValues)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if ('*' === $sWildcardValues)
|
||||
{
|
||||
$sFoundedValue = '*';
|
||||
return true;
|
||||
}
|
||||
|
||||
$sWildcardValues = \preg_replace('/[*]+/', '*', \preg_replace('/[\s,;]+/', ' ', $sWildcardValues));
|
||||
$aWildcardValues = \explode(' ', $sWildcardValues);
|
||||
|
||||
foreach ($aWildcardValues as $sItem)
|
||||
{
|
||||
if (false === \strpos($sItem, '*'))
|
||||
{
|
||||
if ($sString === $sItem)
|
||||
{
|
||||
$sFoundedValue = $sItem;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$aItem = \explode('*', $sItem);
|
||||
$aItem = \array_map(function ($sItem) {
|
||||
return \preg_quote($sItem, '/');
|
||||
}, $aItem);
|
||||
|
||||
if (\preg_match('/'.\implode('.*', $aItem).'/', $sString))
|
||||
{
|
||||
$sFoundedValue = $sItem;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,669 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace RainLoop\Plugins;
|
||||
|
||||
class Manager
|
||||
{
|
||||
/**
|
||||
* @var \RainLoop\Actions
|
||||
*/
|
||||
private $oActions;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $aHooks;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $aJs;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $aAdminJs;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $aTemplates;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $aAdminTemplates;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $aProcessTemplate;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $aAdditionalParts;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $aAdditionalAjax;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $aPlugins;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $bIsEnabled;
|
||||
|
||||
/**
|
||||
* @var \MailSo\Log\Logger
|
||||
*/
|
||||
private $oLogger;
|
||||
|
||||
/**
|
||||
* @param \RainLoop\Actions $oActions
|
||||
*/
|
||||
public function __construct(\RainLoop\Actions $oActions)
|
||||
{
|
||||
$this->oLogger = null;
|
||||
$this->oActions = $oActions;
|
||||
$this->aPlugins = array();
|
||||
|
||||
$this->aHooks = array();
|
||||
$this->aJs = array();
|
||||
$this->aAdminJs = array();
|
||||
$this->aTemplates = array();
|
||||
$this->aAdminTemplates = array();
|
||||
|
||||
$this->aAjaxFilters = array();
|
||||
$this->aAdditionalAjax = array();
|
||||
$this->aProcessTemplate = array();
|
||||
|
||||
$this->bIsEnabled = (bool) $this->oActions->Config()->Get('plugins', 'enable', false);
|
||||
if ($this->bIsEnabled)
|
||||
{
|
||||
$sList = \strtolower($this->oActions->Config()->Get('plugins', 'enabled_list', ''));
|
||||
if (0 < \strlen($sList))
|
||||
{
|
||||
$aList = \explode(',', $sList);
|
||||
$aList = \array_map('trim', $aList);
|
||||
|
||||
foreach ($aList as $sName)
|
||||
{
|
||||
if (0 < \strlen($sName))
|
||||
{
|
||||
$oPlugin = $this->CreatePluginByName($sName);
|
||||
if ($oPlugin)
|
||||
{
|
||||
$oPlugin->PreInit();
|
||||
$oPlugin->Init();
|
||||
|
||||
$this->aPlugins[] = $oPlugin;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sName
|
||||
*
|
||||
* @return \RainLoop\Plugins\AbstractPlugin | null
|
||||
*/
|
||||
public function CreatePluginByName($sName)
|
||||
{
|
||||
$oPlugin = null;
|
||||
if (\preg_match('/^[a-z0-9\-]+$/', $sName) &&
|
||||
\file_exists(APP_PLUGINS_PATH.$sName.'/index.php'))
|
||||
{
|
||||
$sClassName = $this->convertPluginFolderNameToClassName($sName);
|
||||
|
||||
if (!\class_exists($sClassName))
|
||||
{
|
||||
include APP_PLUGINS_PATH.$sName.'/index.php';
|
||||
}
|
||||
|
||||
if (\class_exists($sClassName))
|
||||
{
|
||||
$oPlugin = new $sClassName();
|
||||
if ($oPlugin instanceof \RainLoop\Plugins\AbstractPlugin)
|
||||
{
|
||||
$oPlugin
|
||||
->SetValues(APP_PLUGINS_PATH.$sName, $sName,
|
||||
\file_exists(APP_PLUGINS_PATH.$sName.'/VERSION') ?
|
||||
\file_get_contents(APP_PLUGINS_PATH.$sName.'/VERSION') : '')
|
||||
->SetPluginManager($this)
|
||||
->SetPluginConfig(new \RainLoop\Config\Plugin($sName, $oPlugin->ConfigMap()))
|
||||
;
|
||||
}
|
||||
else
|
||||
{
|
||||
$oPlugin = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $oPlugin;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function InstalledPlugins()
|
||||
{
|
||||
$aList = array();
|
||||
|
||||
$aGlob = @\glob(APP_PLUGINS_PATH.'*', GLOB_ONLYDIR|GLOB_NOSORT);
|
||||
if (\is_array($aGlob))
|
||||
{
|
||||
foreach ($aGlob as $sPathName)
|
||||
{
|
||||
$sName = \basename($sPathName);
|
||||
if (\preg_match('/^[a-z0-9\-]+$/', $sName) &&
|
||||
\file_exists($sPathName.'/index.php'))
|
||||
{
|
||||
$sVersion = @\file_get_contents($sPathName.'/VERSION');
|
||||
$aList[] = array(
|
||||
$sName, $sVersion
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->Actions()->Logger()->Write('Cannot get installed plugins from '.APP_PLUGINS_PATH,
|
||||
\MailSo\Log\Enumerations\Type::ERROR);
|
||||
}
|
||||
|
||||
return $aList;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sFolderName
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function convertPluginFolderNameToClassName($sFolderName)
|
||||
{
|
||||
$aParts = \array_map('ucfirst', \array_map('strtolower',
|
||||
\explode(' ', \preg_replace('/[^a-z0-9]+/', ' ', $sFolderName))));
|
||||
|
||||
return \implode($aParts).'Plugin';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \RainLoop\Actions
|
||||
*/
|
||||
public function Actions()
|
||||
{
|
||||
return $this->oActions;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \RainLoop\Actions
|
||||
*/
|
||||
public function Hash()
|
||||
{
|
||||
$sResult = \md5(APP_VERSION);
|
||||
foreach ($this->aPlugins as $oPlugin)
|
||||
{
|
||||
$sResult = \md5($sResult.$oPlugin->Path().$oPlugin->Hash());
|
||||
}
|
||||
|
||||
return $sResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $bAdminScope = false
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function CompileJs($bAdminScope = false)
|
||||
{
|
||||
$aResult = array();
|
||||
if ($this->bIsEnabled)
|
||||
{
|
||||
$aJs = $bAdminScope ? $this->aAdminJs : $this->aJs;
|
||||
foreach ($aJs as $sFile)
|
||||
{
|
||||
if (file_exists($sFile))
|
||||
{
|
||||
$aResult[] = file_get_contents($sFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return implode("\n", $aResult);
|
||||
}
|
||||
|
||||
/**
|
||||
* @todo
|
||||
* @param bool $bAdminScope = false
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function CompileCss($bAdminScope = false)
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $bAdminScope = false
|
||||
* @return string
|
||||
*/
|
||||
public function CompileTemplate($bAdminScope = false)
|
||||
{
|
||||
$sResult = '';
|
||||
if ($this->bIsEnabled)
|
||||
{
|
||||
$aTemplates = $bAdminScope ? $this->aAdminTemplates : $this->aTemplates;
|
||||
foreach ($aTemplates as $sFile)
|
||||
{
|
||||
if (file_exists($sFile))
|
||||
{
|
||||
$sTemplateName = substr(basename($sFile), 0, -5);
|
||||
$sResult .= '<script id="'.preg_replace('/[^a-zA-Z0-9]/', '', $sTemplateName).'" type="text/html" data-cfasync="false">'.
|
||||
$this->Actions()->ProcessTemplate($sTemplateName, file_get_contents($sFile)).'</script>';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $sResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $bAdmin
|
||||
* @param array $aAppData
|
||||
*
|
||||
* @return \RainLoop\Plugins\Manager
|
||||
*/
|
||||
public function InitAppData($bAdmin, &$aAppData, $oAccount = null)
|
||||
{
|
||||
if ($this->bIsEnabled && isset($aAppData['Plugins']) && is_array($aAppData['Plugins']))
|
||||
{
|
||||
$bAuth = isset($aAppData['Auth']) && !!$aAppData['Auth'];
|
||||
foreach ($this->aPlugins as $oPlugin)
|
||||
{
|
||||
if ($oPlugin)
|
||||
{
|
||||
$aConfig = array();
|
||||
$aMap = $oPlugin->ConfigMap();
|
||||
if (\is_array($aMap))
|
||||
{
|
||||
foreach ($aMap as /* @var $oPluginProperty \RainLoop\Plugins\Property */ $oPluginProperty)
|
||||
{
|
||||
if ($oPluginProperty && $oPluginProperty->AllowedInJs())
|
||||
{
|
||||
$aConfig[$oPluginProperty->Name()] =
|
||||
$oPlugin->Config()->Get('plugin',
|
||||
$oPluginProperty->Name(),
|
||||
$oPluginProperty->DefaultValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$oPlugin->FilterAppDataPluginSection($bAdmin, $bAuth, $aConfig);
|
||||
|
||||
if (0 < \count($aConfig))
|
||||
{
|
||||
$aAppData['Plugins'][$oPlugin->Name()] = $aConfig;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$this->RunHook('filter.app-data', array($bAdmin, &$aAppData));
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sHookName
|
||||
* @param mixed $mCallbak
|
||||
*
|
||||
* @return \RainLoop\Plugins\Manager
|
||||
*/
|
||||
public function AddHook($sHookName, $mCallbak)
|
||||
{
|
||||
if ($this->bIsEnabled && is_callable($mCallbak))
|
||||
{
|
||||
if (!isset($this->aHooks[$sHookName]))
|
||||
{
|
||||
$this->aHooks[$sHookName] = array();
|
||||
}
|
||||
|
||||
$this->aHooks[$sHookName][] = $mCallbak;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sFile
|
||||
* @param bool $bAdminScope = false
|
||||
*
|
||||
* @return \RainLoop\Plugins\Manager
|
||||
*/
|
||||
public function AddJs($sFile, $bAdminScope = false)
|
||||
{
|
||||
if ($this->bIsEnabled)
|
||||
{
|
||||
if ($bAdminScope)
|
||||
{
|
||||
$this->aAdminJs[$sFile] = $sFile;
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->aJs[$sFile] = $sFile;
|
||||
}
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sFile
|
||||
* @param bool $bAdminScope = false
|
||||
*
|
||||
* @return \RainLoop\Plugins\Manager
|
||||
*/
|
||||
public function AddTemplate($sFile, $bAdminScope = false)
|
||||
{
|
||||
if ($this->bIsEnabled)
|
||||
{
|
||||
if ($bAdminScope)
|
||||
{
|
||||
$this->aAdminTemplates[$sFile] = $sFile;
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->aTemplates[$sFile] = $sFile;
|
||||
}
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sHookName
|
||||
* @param array $aArg = array()
|
||||
* @param bool $bLogHook = true
|
||||
*
|
||||
* @return \RainLoop\Plugins\Manager
|
||||
*/
|
||||
public function RunHook($sHookName, $aArg = array(), $bLogHook = true)
|
||||
{
|
||||
if ($this->bIsEnabled)
|
||||
{
|
||||
if (isset($this->aHooks[$sHookName]))
|
||||
{
|
||||
if ($bLogHook)
|
||||
{
|
||||
$this->WriteLog('Hook: '.$sHookName, \MailSo\Log\Enumerations\Type::NOTE);
|
||||
}
|
||||
|
||||
foreach ($this->aHooks[$sHookName] as $mCallbak)
|
||||
{
|
||||
call_user_func_array($mCallbak, $aArg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sActionName
|
||||
* @param mixed $mCallbak
|
||||
*
|
||||
* @return \RainLoop\Plugins\Manager
|
||||
*/
|
||||
public function AddAdditionalPartAction($sActionName, $mCallbak)
|
||||
{
|
||||
if ($this->bIsEnabled && \is_callable($mCallbak))
|
||||
{
|
||||
$sActionName = \strtolower($sActionName);
|
||||
if (!isset($this->aAdditionalParts[$sActionName]))
|
||||
{
|
||||
$this->aAdditionalParts[$sActionName] = array();
|
||||
}
|
||||
|
||||
$this->aAdditionalParts[$sActionName][] = $mCallbak;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sActionName
|
||||
* @param array $aParts = array()
|
||||
*
|
||||
* @return \RainLoop\Plugins\Manager
|
||||
*/
|
||||
public function RunAdditionalPart($sActionName, $aParts = array())
|
||||
{
|
||||
$bResult = false;
|
||||
if ($this->bIsEnabled)
|
||||
{
|
||||
$sActionName = \strtolower($sActionName);
|
||||
if (isset($this->aAdditionalParts[$sActionName]))
|
||||
{
|
||||
foreach ($this->aAdditionalParts[$sActionName] as $mCallbak)
|
||||
{
|
||||
$bCallResult = \call_user_func_array($mCallbak, $aParts);
|
||||
if ($bCallResult && !$bResult)
|
||||
{
|
||||
$bResult = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $bResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sName
|
||||
* @param string $sPlace
|
||||
* @param string $sHtml
|
||||
* @param bool $bPrepend = false
|
||||
*
|
||||
* @return \RainLoop\Plugins\Manager
|
||||
*/
|
||||
public function AddProcessTemplateAction($sName, $sPlace, $sHtml, $bPrepend = false)
|
||||
{
|
||||
if ($this->bIsEnabled)
|
||||
{
|
||||
if (!isset($this->aProcessTemplate[$sName]))
|
||||
{
|
||||
$this->aProcessTemplate[$sName] = array();
|
||||
}
|
||||
|
||||
if (!isset($this->aProcessTemplate[$sName][$sPlace]))
|
||||
{
|
||||
$this->aProcessTemplate[$sName][$sPlace] = array();
|
||||
}
|
||||
|
||||
if ($bPrepend)
|
||||
{
|
||||
array_unshift($this->aProcessTemplate[$sName][$sPlace], $sHtml);
|
||||
}
|
||||
else
|
||||
{
|
||||
array_push($this->aProcessTemplate[$sName][$sPlace], $sHtml);
|
||||
}
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sActionName
|
||||
* @param mixed $mCallbak
|
||||
*
|
||||
* @return \RainLoop\Plugins\Manager
|
||||
*/
|
||||
public function AddAdditionalAjaxAction($sActionName, $mCallbak)
|
||||
{
|
||||
if ($this->bIsEnabled && is_callable($mCallbak) && 0 < strlen($sActionName))
|
||||
{
|
||||
$sActionName = 'Do'.$sActionName;
|
||||
|
||||
if (!isset($this->aAdditionalAjax[$sActionName]))
|
||||
{
|
||||
$this->aAdditionalAjax[$sActionName] = $mCallbak;
|
||||
}
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sActionName
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function HasAdditionalAjax($sActionName)
|
||||
{
|
||||
return $this->bIsEnabled && isset($this->aAdditionalAjax[$sActionName]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sActionName
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function RunAdditionalAjax($sActionName)
|
||||
{
|
||||
if ($this->bIsEnabled)
|
||||
{
|
||||
if (isset($this->aAdditionalAjax[$sActionName]))
|
||||
{
|
||||
return call_user_func($this->aAdditionalAjax[$sActionName]);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sLang
|
||||
* @param array $sActionName
|
||||
*
|
||||
* @return \RainLoop\Plugins\Manager
|
||||
*/
|
||||
public function ReadLang($sLang, &$aLang)
|
||||
{
|
||||
if ($this->bIsEnabled)
|
||||
{
|
||||
foreach ($this->aPlugins as $oPlugin)
|
||||
{
|
||||
if ($oPlugin->UseLangs())
|
||||
{
|
||||
$sPath = $oPlugin->Path();
|
||||
|
||||
\RainLoop\Utils::ReadAndAddLang($sPath.'/langs/en.ini', $aLang);
|
||||
if ('en' !== $sLang)
|
||||
{
|
||||
\RainLoop\Utils::ReadAndAddLang($sPath.'/langs/'.$sLang.'.ini', $aLang);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sName
|
||||
* @param string $sHtml
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function ProcessTemplate($sName, $sHtml)
|
||||
{
|
||||
if (isset($this->aProcessTemplate[$sName]))
|
||||
{
|
||||
foreach ($this->aProcessTemplate[$sName] as $sPlace => $aAddHtml)
|
||||
{
|
||||
if (\is_array($aAddHtml) && 0 < \count($aAddHtml))
|
||||
{
|
||||
foreach ($aAddHtml as $sAddHtml)
|
||||
{
|
||||
$sHtml = \str_replace('{{INCLUDE/'.$sPlace.'/PLACE}}', $sAddHtml.'{{INCLUDE/'.$sPlace.'/PLACE}}', $sHtml);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $sHtml;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function bIsEnabled()
|
||||
{
|
||||
return $this->bIsEnabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function Count()
|
||||
{
|
||||
return $this->bIsEnabled ? \count($this->aPlugins) : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \MailSo\Log\Logger $oLogger
|
||||
*
|
||||
* @return \RainLoop\Plugins\Manager
|
||||
*
|
||||
* @throws \MailSo\Base\Exceptions\InvalidArgumentException
|
||||
*/
|
||||
public function SetLogger($oLogger)
|
||||
{
|
||||
if (!($oLogger instanceof \MailSo\Log\Logger))
|
||||
{
|
||||
throw new \MailSo\Base\Exceptions\InvalidArgumentException();
|
||||
}
|
||||
|
||||
$this->oLogger = $oLogger;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sDesc
|
||||
* @param int $iDescType = \MailSo\Log\Enumerations\Type::INFO
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function WriteLog($sDesc, $iDescType = \MailSo\Log\Enumerations\Type::INFO)
|
||||
{
|
||||
if ($this->oLogger)
|
||||
{
|
||||
$this->oLogger->Write($sDesc, $iDescType, 'PLUGIN');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sDesc
|
||||
* @param int $iDescType = \MailSo\Log\Enumerations\Type::INFO
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function WriteException($sDesc, $iDescType = \MailSo\Log\Enumerations\Type::INFO)
|
||||
{
|
||||
if ($this->oLogger)
|
||||
{
|
||||
$this->oLogger->WriteException($sDesc, $iDescType, 'PLUGIN');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,205 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace RainLoop\Plugins;
|
||||
|
||||
class Property
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sName;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sLabel;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sDesc;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $iType;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $bAllowedInJs;
|
||||
|
||||
/**
|
||||
* @var mixed
|
||||
*/
|
||||
private $mDefaultValue;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sPlaceholder;
|
||||
|
||||
private function __construct($sName)
|
||||
{
|
||||
$this->sName = $sName;
|
||||
$this->iType = \RainLoop\Enumerations\PluginPropertyType::STRING;
|
||||
$this->mDefaultValue = '';
|
||||
$this->sLabel = '';
|
||||
$this->sDesc = '';
|
||||
$this->bAllowedInJs = false;
|
||||
$this->sPlaceholder = '';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sName
|
||||
*
|
||||
* @return \RainLoop\Plugins\Property
|
||||
*/
|
||||
public static function NewInstance($sName)
|
||||
{
|
||||
return new self($sName);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $iType
|
||||
*
|
||||
* @return \RainLoop\Plugins\Property
|
||||
*/
|
||||
public function SetType($iType)
|
||||
{
|
||||
$this->iType = (int) $iType;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $mDefaultValue
|
||||
*
|
||||
* @return \RainLoop\Plugins\Property
|
||||
*/
|
||||
public function SetDefaultValue($mDefaultValue)
|
||||
{
|
||||
$this->mDefaultValue = $mDefaultValue;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sPlaceholder
|
||||
*
|
||||
* @return \RainLoop\Plugins\Property
|
||||
*/
|
||||
public function SetPlaceholder($sPlaceholder)
|
||||
{
|
||||
$this->sPlaceholder = $sPlaceholder;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sLabel
|
||||
*
|
||||
* @return \RainLoop\Plugins\Property
|
||||
*/
|
||||
public function SetLabel($sLabel)
|
||||
{
|
||||
$this->sLabel = $sLabel;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sDesc
|
||||
*
|
||||
* @return \RainLoop\Plugins\Property
|
||||
*/
|
||||
public function SetDescription($sDesc)
|
||||
{
|
||||
$this->sDesc = $sDesc;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $bValue = true
|
||||
* @return \RainLoop\Plugins\Property
|
||||
*/
|
||||
public function SetAllowedInJs($bValue = true)
|
||||
{
|
||||
$this->bAllowedInJs = !!$bValue;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function Name()
|
||||
{
|
||||
return $this->sName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function AllowedInJs()
|
||||
{
|
||||
return $this->bAllowedInJs;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function Description()
|
||||
{
|
||||
return $this->sDesc;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function Label()
|
||||
{
|
||||
return $this->sLabel;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function Type()
|
||||
{
|
||||
return $this->iType;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function DefaultValue()
|
||||
{
|
||||
return $this->mDefaultValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function Placeholder()
|
||||
{
|
||||
return $this->sPlaceholder;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function ToArray()
|
||||
{
|
||||
return array(
|
||||
'',
|
||||
$this->sName,
|
||||
$this->iType,
|
||||
$this->sLabel,
|
||||
$this->mDefaultValue,
|
||||
$this->sDesc,
|
||||
$this->sPlaceholder
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,340 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace RainLoop\PluginsNext;
|
||||
|
||||
abstract class AbstractPlugin
|
||||
{
|
||||
/**
|
||||
* @var \RainLoop\PluginsNext\Manager
|
||||
*/
|
||||
private $oPluginManager;
|
||||
|
||||
/**
|
||||
* @var \RainLoop\Config\Plugin
|
||||
*/
|
||||
private $oPluginConfig;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $bLangs;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sName;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sPath;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sVersion;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $aConfigMap;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $bPluginConfigLoaded;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->sName = '';
|
||||
$this->sPath = '';
|
||||
$this->sVersion = '0.0';
|
||||
$this->aConfigMap = null;
|
||||
|
||||
$this->oPluginManager = null;
|
||||
$this->oPluginConfig = null;
|
||||
$this->bPluginConfigLoaded = false;
|
||||
$this->bLangs = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \RainLoop\Config\Plugin
|
||||
*/
|
||||
public function Config()
|
||||
{
|
||||
if (!$this->bPluginConfigLoaded && $this->oPluginConfig)
|
||||
{
|
||||
$this->bPluginConfigLoaded = true;
|
||||
if ($this->oPluginConfig->IsInited())
|
||||
{
|
||||
if (!$this->oPluginConfig->Load())
|
||||
{
|
||||
$this->oPluginConfig->Save();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $this->oPluginConfig;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \RainLoop\PluginsNext\Manager
|
||||
*/
|
||||
public function Manager()
|
||||
{
|
||||
return $this->oPluginManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function Path()
|
||||
{
|
||||
return $this->sPath;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function Name()
|
||||
{
|
||||
return $this->sName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function Version()
|
||||
{
|
||||
return $this->sVersion;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool|null $bLangs = null
|
||||
* @return bool
|
||||
*/
|
||||
public function UseLangs($bLangs = null)
|
||||
{
|
||||
if (null !== $bLangs)
|
||||
{
|
||||
$this->bLangs = (bool) $bLangs;
|
||||
}
|
||||
|
||||
return $this->bLangs;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
protected function configMapping()
|
||||
{
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function Hash()
|
||||
{
|
||||
return \md5($this->sVersion);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function Supported()
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* @final
|
||||
* @return array
|
||||
*/
|
||||
final public function ConfigMap()
|
||||
{
|
||||
if (null === $this->aConfigMap)
|
||||
{
|
||||
$this->aConfigMap = $this->configMapping();
|
||||
if (!\is_array($this->aConfigMap))
|
||||
{
|
||||
$this->aConfigMap = array();
|
||||
}
|
||||
}
|
||||
|
||||
return $this->aConfigMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sPath
|
||||
* @param string $sName
|
||||
* @param string $sVersion = ''
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function SetValues($sPath, $sName, $sVersion = '')
|
||||
{
|
||||
$this->sName = $sName;
|
||||
$this->sPath = $sPath;
|
||||
|
||||
if (0 < \strlen($sVersion))
|
||||
{
|
||||
$this->sVersion = $sVersion;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \RainLoop\PluginsNext\Manager $oPluginManager
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function SetPluginManager(\RainLoop\PluginsNext\Manager $oPluginManager)
|
||||
{
|
||||
$this->oPluginManager = $oPluginManager;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \RainLoop\Config\Plugin $oPluginConfig
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function SetPluginConfig(\RainLoop\Config\Plugin $oPluginConfig)
|
||||
{
|
||||
$this->oPluginConfig = $oPluginConfig;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return self
|
||||
*/
|
||||
public function Init()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sStep
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function InitStep($sStep)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $bAdmin
|
||||
* @param bool $bAuth
|
||||
* @param array $aConfig
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function FilterAppDataPluginSection($bAdmin, $bAuth, &$aConfig)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sHookName
|
||||
* @param string $sFunctionName
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
protected function addHook($sHookName, $sFunctionName)
|
||||
{
|
||||
if ($this->oPluginManager)
|
||||
{
|
||||
$this->oPluginManager->AddHook($sHookName, array(&$this, $sFunctionName));
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sFile
|
||||
* @param bool $bAdminScope = false
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
protected function addJs($sFile, $bAdminScope = false)
|
||||
{
|
||||
if ($this->oPluginManager)
|
||||
{
|
||||
$this->oPluginManager->AddJs($this->sPath.'/'.$sFile, $bAdminScope);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sFile
|
||||
* @param bool $bAdminScope = false
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
protected function addTemplate($sFile, $bAdminScope = false)
|
||||
{
|
||||
if ($this->oPluginManager)
|
||||
{
|
||||
$this->oPluginManager->AddTemplate($this->sPath.'/'.$sFile, $bAdminScope);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sActionName
|
||||
* @param string $sFunctionName
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
protected function addPartHook($sActionName, $sFunctionName)
|
||||
{
|
||||
if ($this->oPluginManager)
|
||||
{
|
||||
$this->oPluginManager->AddAdditionalPartAction($sActionName, array(&$this, $sFunctionName));
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sActionName
|
||||
* @param string $sFunctionName
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
protected function addAjaxHook($sActionName, $sFunctionName)
|
||||
{
|
||||
if ($this->oPluginManager)
|
||||
{
|
||||
$this->oPluginManager->AddAdditionalAjaxAction($sActionName, array(&$this, $sFunctionName));
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sName
|
||||
* @param string $sPlace
|
||||
* @param string $sLocalTemplateName
|
||||
* @param bool $bPrepend = false
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
protected function addTemplateHook($sName, $sPlace, $sLocalTemplateName, $bPrepend = false)
|
||||
{
|
||||
if ($this->oPluginManager)
|
||||
{
|
||||
$this->oPluginManager->AddProcessTemplateAction($sName, $sPlace,
|
||||
'<!-- ko template: \''.$sLocalTemplateName.'\' --><!-- /ko -->', $bPrepend);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,685 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace RainLoop\PluginsNext;
|
||||
|
||||
class Manager
|
||||
{
|
||||
/**
|
||||
* @var \RainLoop\Actions
|
||||
*/
|
||||
private $oActions;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $aHooks;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $aJs;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $aAdminJs;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $aTemplates;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $aAdminTemplates;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $aProcessTemplate;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $aAdditionalParts;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $aAdditionalAjax;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $aPlugins;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $bIsEnabled;
|
||||
|
||||
/**
|
||||
* @var \MailSo\Log\Logger
|
||||
*/
|
||||
private $oLogger;
|
||||
|
||||
/**
|
||||
* @param \RainLoop\Actions $oActions
|
||||
*/
|
||||
public function __construct(\RainLoop\Actions $oActions)
|
||||
{
|
||||
$this->oLogger = null;
|
||||
$this->oActions = $oActions;
|
||||
$this->aPlugins = array();
|
||||
|
||||
$this->aHooks = array();
|
||||
$this->aJs = array();
|
||||
$this->aAdminJs = array();
|
||||
$this->aTemplates = array();
|
||||
$this->aAdminTemplates = array();
|
||||
|
||||
$this->aAjaxFilters = array();
|
||||
$this->aAdditionalAjax = array();
|
||||
$this->aProcessTemplate = array();
|
||||
|
||||
$this->bIsEnabled = (bool) $this->oActions->Config()->Get('plugins', 'enable', false);
|
||||
if ($this->bIsEnabled)
|
||||
{
|
||||
$sList = \strtolower($this->oActions->Config()->Get('plugins', 'enabled_list', ''));
|
||||
if (0 < \strlen($sList))
|
||||
{
|
||||
$aList = \explode(',', $sList);
|
||||
$aList = \array_map('trim', $aList);
|
||||
|
||||
foreach ($aList as $sName)
|
||||
{
|
||||
if (0 < \strlen($sName))
|
||||
{
|
||||
$oPlugin = $this->CreatePluginByName($sName);
|
||||
if ($oPlugin)
|
||||
{
|
||||
$oPlugin->InitStep('step1');
|
||||
$oPlugin->Init();
|
||||
$oPlugin->InitStep('step2');
|
||||
|
||||
$this->aPlugins[] = $oPlugin;
|
||||
|
||||
$oPlugin->InitStep('spep3');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$this->RunHook('api.bootstrap.plugins');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sName
|
||||
*
|
||||
* @return \RainLoop\Plugins\AbstractPlugin|null
|
||||
*/
|
||||
public function CreatePluginByName($sName)
|
||||
{
|
||||
$oPlugin = null;
|
||||
if (\preg_match('/^[a-z0-9\-]+$/', $sName) &&
|
||||
\file_exists(APP_PLUGINS_PATH.$sName.'/index.php'))
|
||||
{
|
||||
$sClassName = $this->convertPluginFolderNameToClassName($sName);
|
||||
|
||||
if (!\class_exists($sClassName))
|
||||
{
|
||||
include APP_PLUGINS_PATH.$sName.'/index.php';
|
||||
}
|
||||
|
||||
if (\class_exists($sClassName))
|
||||
{
|
||||
$oPlugin = new $sClassName();
|
||||
if ($oPlugin instanceof \RainLoop\PluginsNext\AbstractPlugin)
|
||||
{
|
||||
$oPlugin
|
||||
->SetValues(APP_PLUGINS_PATH.$sName, $sName,
|
||||
\file_exists(APP_PLUGINS_PATH.$sName.'/VERSION') ?
|
||||
\file_get_contents(APP_PLUGINS_PATH.$sName.'/VERSION') : '')
|
||||
->SetPluginManager($this)
|
||||
->SetPluginConfig(new \RainLoop\Config\Plugin($sName, $oPlugin->ConfigMap()))
|
||||
;
|
||||
}
|
||||
else
|
||||
{
|
||||
$oPlugin = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $oPlugin;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function InstalledPlugins()
|
||||
{
|
||||
$aList = array();
|
||||
|
||||
$aGlob = @\glob(APP_PLUGINS_PATH.'*', GLOB_ONLYDIR|GLOB_NOSORT);
|
||||
if (\is_array($aGlob))
|
||||
{
|
||||
foreach ($aGlob as $sPathName)
|
||||
{
|
||||
$sName = \basename($sPathName);
|
||||
if (\preg_match('/^[a-z0-9\-]+$/', $sName) &&
|
||||
\file_exists($sPathName.'/index.php'))
|
||||
{
|
||||
$aList[] = array(
|
||||
$sName, @\file_get_contents($sPathName.'/VERSION')
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->Actions()->Logger()->Write('Cannot get installed plugins from '.APP_PLUGINS_PATH,
|
||||
\MailSo\Log\Enumerations\Type::ERROR);
|
||||
}
|
||||
|
||||
return $aList;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sFolderName
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function convertPluginFolderNameToClassName($sFolderName)
|
||||
{
|
||||
$aParts = \array_map('ucfirst', \array_map('strtolower',
|
||||
\explode(' ', \preg_replace('/[^a-z0-9]+/', ' ', $sFolderName))));
|
||||
|
||||
return \implode($aParts).'Plugin';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \RainLoop\Actions
|
||||
*/
|
||||
public function Actions()
|
||||
{
|
||||
return $this->oActions;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function Hash()
|
||||
{
|
||||
$sResult = \md5(APP_VERSION);
|
||||
foreach ($this->aPlugins as $oPlugin)
|
||||
{
|
||||
$sResult = \md5($sResult.$oPlugin->Path().$oPlugin->Hash());
|
||||
}
|
||||
|
||||
return $sResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $bAdminScope = false
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function CompileJs($bAdminScope = false)
|
||||
{
|
||||
$aResult = array();
|
||||
if ($this->bIsEnabled)
|
||||
{
|
||||
$aJs = $bAdminScope ? $this->aAdminJs : $this->aJs;
|
||||
foreach ($aJs as $sFile)
|
||||
{
|
||||
if (\file_exists($sFile))
|
||||
{
|
||||
$aResult[] = \file_get_contents($sFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return \implode("\n", $aResult);
|
||||
}
|
||||
|
||||
/**
|
||||
* @todo
|
||||
* @param bool $bAdminScope = false
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function CompileCss($bAdminScope = false)
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $bAdminScope = false
|
||||
* @return string
|
||||
*/
|
||||
public function CompileTemplate($bAdminScope = false)
|
||||
{
|
||||
$sResult = '';
|
||||
if ($this->bIsEnabled)
|
||||
{
|
||||
foreach ($bAdminScope ? $this->aAdminTemplates : $this->aTemplates as $sFile)
|
||||
{
|
||||
if (\file_exists($sFile))
|
||||
{
|
||||
$sTemplateName = \substr(\basename($sFile), 0, -5);
|
||||
$sResult .= '<script id="'.\preg_replace('/[^a-zA-Z0-9]/', '', $sTemplateName).'" type="text/html" data-cfasync="false">'.
|
||||
$this->Actions()->ProcessTemplate($sTemplateName, \file_get_contents($sFile)).'</script>';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $sResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $bAdmin
|
||||
* @param array $aAppData
|
||||
* @param \RainLoop\Account|null $oAccount = null
|
||||
*
|
||||
* @return \RainLoop\PluginsNext\Manager
|
||||
*/
|
||||
public function InitAppData($bAdmin, &$aAppData, $oAccount = null)
|
||||
{
|
||||
if ($this->bIsEnabled && isset($aAppData['Plugins']) && \is_array($aAppData['Plugins']))
|
||||
{
|
||||
$bAuth = isset($aAppData['Auth']) && !!$aAppData['Auth'];
|
||||
foreach ($this->aPlugins as $oPlugin)
|
||||
{
|
||||
if ($oPlugin)
|
||||
{
|
||||
$aConfig = array();
|
||||
$aMap = $oPlugin->ConfigMap();
|
||||
if (\is_array($aMap))
|
||||
{
|
||||
foreach ($aMap as /* @var $oPluginProperty \RainLoop\PluginsNext\Property */$oPluginProperty)
|
||||
{
|
||||
if ($oPluginProperty && $oPluginProperty->AllowedInJs())
|
||||
{
|
||||
$aConfig[$oPluginProperty->Name()] =
|
||||
$oPlugin->Config()->Get('plugin',
|
||||
$oPluginProperty->Name(),
|
||||
$oPluginProperty->DefaultValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$oPlugin->FilterAppDataPluginSection($bAdmin, $bAuth, $aConfig);
|
||||
|
||||
if (0 < \count($aConfig))
|
||||
{
|
||||
$aAppData['Plugins'][$oPlugin->Name()] = $aConfig;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$this->RunHook('filter.app-data', array(
|
||||
'IsAdmin' => $bAdmin,
|
||||
'AppData' => &$aAppData
|
||||
), $oAccount);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sHookName
|
||||
* @param mixed $mCallbak
|
||||
*
|
||||
* @return \RainLoop\PluginsNext\Manager
|
||||
*/
|
||||
public function AddHook($sHookName, $mCallbak)
|
||||
{
|
||||
if ($this->bIsEnabled && \is_callable($mCallbak))
|
||||
{
|
||||
if (!isset($this->aHooks[$sHookName]))
|
||||
{
|
||||
$this->aHooks[$sHookName] = array();
|
||||
}
|
||||
|
||||
$this->aHooks[$sHookName][] = $mCallbak;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sFile
|
||||
* @param bool $bAdminScope = false
|
||||
*
|
||||
* @return \RainLoop\PluginsNext\Manager
|
||||
*/
|
||||
public function AddJs($sFile, $bAdminScope = false)
|
||||
{
|
||||
if ($this->bIsEnabled)
|
||||
{
|
||||
if ($bAdminScope)
|
||||
{
|
||||
$this->aAdminJs[$sFile] = $sFile;
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->aJs[$sFile] = $sFile;
|
||||
}
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sFile
|
||||
* @param bool $bAdminScope = false
|
||||
*
|
||||
* @return \RainLoop\PluginsNext\Manager
|
||||
*/
|
||||
public function AddTemplate($sFile, $bAdminScope = false)
|
||||
{
|
||||
if ($this->bIsEnabled)
|
||||
{
|
||||
if ($bAdminScope)
|
||||
{
|
||||
$this->aAdminTemplates[$sFile] = $sFile;
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->aTemplates[$sFile] = $sFile;
|
||||
}
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sHookName
|
||||
* @param array $aArg = array()
|
||||
* @param \RainLoop\Account|null $oAccount = null
|
||||
* @param bool $bLogHook = true
|
||||
*
|
||||
* @return \RainLoop\PluginsNext\Manager
|
||||
*/
|
||||
public function RunHook($sHookName, $aArg = array(), $oAccount = null, $bLogHook = true)
|
||||
{
|
||||
if ($this->bIsEnabled)
|
||||
{
|
||||
if (isset($this->aHooks[$sHookName]))
|
||||
{
|
||||
if ($bLogHook)
|
||||
{
|
||||
$this->WriteLog('Hook: '.$sHookName, \MailSo\Log\Enumerations\Type::NOTE);
|
||||
}
|
||||
|
||||
$bArgArray = 0 < \count($aArg);
|
||||
foreach ($this->aHooks[$sHookName] as $mCallbak)
|
||||
{
|
||||
if ($bArgArray)
|
||||
{
|
||||
\call_user_func_array($mCallbak, array($aArg));
|
||||
}
|
||||
else
|
||||
{
|
||||
\call_user_func($mCallbak);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sActionName
|
||||
* @param mixed $mCallbak
|
||||
*
|
||||
* @return \RainLoop\PluginsNext\Manager
|
||||
*/
|
||||
public function AddAdditionalPartAction($sActionName, $mCallbak)
|
||||
{
|
||||
if ($this->bIsEnabled && \is_callable($mCallbak))
|
||||
{
|
||||
$sActionName = \strtolower($sActionName);
|
||||
if (!isset($this->aAdditionalParts[$sActionName]))
|
||||
{
|
||||
$this->aAdditionalParts[$sActionName] = array();
|
||||
}
|
||||
|
||||
$this->aAdditionalParts[$sActionName][] = $mCallbak;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sActionName
|
||||
* @param array $aParts = array()
|
||||
*
|
||||
* @return \RainLoop\PluginsNext\Manager
|
||||
*/
|
||||
public function RunAdditionalPart($sActionName, $aParts = array())
|
||||
{
|
||||
$bResult = false;
|
||||
if ($this->bIsEnabled)
|
||||
{
|
||||
$sActionName = \strtolower($sActionName);
|
||||
if (isset($this->aAdditionalParts[$sActionName]))
|
||||
{
|
||||
foreach ($this->aAdditionalParts[$sActionName] as $mCallbak)
|
||||
{
|
||||
$bCallResult = \call_user_func_array($mCallbak, $aParts);
|
||||
if ($bCallResult && !$bResult)
|
||||
{
|
||||
$bResult = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $bResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sName
|
||||
* @param string $sPlace
|
||||
* @param string $sHtml
|
||||
* @param bool $bPrepend = false
|
||||
*
|
||||
* @return \RainLoop\PluginsNext\Manager
|
||||
*/
|
||||
public function AddProcessTemplateAction($sName, $sPlace, $sHtml, $bPrepend = false)
|
||||
{
|
||||
if ($this->bIsEnabled)
|
||||
{
|
||||
if (!isset($this->aProcessTemplate[$sName]))
|
||||
{
|
||||
$this->aProcessTemplate[$sName] = array();
|
||||
}
|
||||
|
||||
if (!isset($this->aProcessTemplate[$sName][$sPlace]))
|
||||
{
|
||||
$this->aProcessTemplate[$sName][$sPlace] = array();
|
||||
}
|
||||
|
||||
if ($bPrepend)
|
||||
{
|
||||
\array_unshift($this->aProcessTemplate[$sName][$sPlace], $sHtml);
|
||||
}
|
||||
else
|
||||
{
|
||||
\array_push($this->aProcessTemplate[$sName][$sPlace], $sHtml);
|
||||
}
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sActionName
|
||||
* @param mixed $mCallbak
|
||||
*
|
||||
* @return \RainLoop\Plugins\Manager
|
||||
*/
|
||||
public function AddAdditionalAjaxAction($sActionName, $mCallbak)
|
||||
{
|
||||
if ($this->bIsEnabled && \is_callable($mCallbak) && 0 < \strlen($sActionName))
|
||||
{
|
||||
$sActionName = 'Do'.$sActionName;
|
||||
|
||||
if (!isset($this->aAdditionalAjax[$sActionName]))
|
||||
{
|
||||
$this->aAdditionalAjax[$sActionName] = $mCallbak;
|
||||
}
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sActionName
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function HasAdditionalAjax($sActionName)
|
||||
{
|
||||
return $this->bIsEnabled && isset($this->aAdditionalAjax[$sActionName]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sActionName
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function RunAdditionalAjax($sActionName)
|
||||
{
|
||||
if ($this->bIsEnabled)
|
||||
{
|
||||
if (isset($this->aAdditionalAjax[$sActionName]))
|
||||
{
|
||||
return \call_user_func($this->aAdditionalAjax[$sActionName]);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sLang
|
||||
* @param array $sActionName
|
||||
*
|
||||
* @return \RainLoop\PluginsNext\Manager
|
||||
*/
|
||||
public function ReadLang($sLang, &$aLang)
|
||||
{
|
||||
if ($this->bIsEnabled)
|
||||
{
|
||||
foreach ($this->aPlugins as $oPlugin)
|
||||
{
|
||||
if ($oPlugin->UseLangs())
|
||||
{
|
||||
$sPath = $oPlugin->Path();
|
||||
|
||||
\RainLoop\Utils::ReadAndAddLang($sPath.'/langs/en.ini', $aLang);
|
||||
if ('en' !== $sLang)
|
||||
{
|
||||
\RainLoop\Utils::ReadAndAddLang($sPath.'/langs/'.$sLang.'.ini', $aLang);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sName
|
||||
* @param string $sHtml
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function ProcessTemplate($sName, $sHtml)
|
||||
{
|
||||
if (isset($this->aProcessTemplate[$sName]))
|
||||
{
|
||||
foreach ($this->aProcessTemplate[$sName] as $sPlace => $aAddHtml)
|
||||
{
|
||||
if (\is_array($aAddHtml) && 0 < \count($aAddHtml))
|
||||
{
|
||||
foreach ($aAddHtml as $sAddHtml)
|
||||
{
|
||||
$sHtml = \str_replace('{{INCLUDE/'.$sPlace.'/PLACE}}', $sAddHtml.'{{INCLUDE/'.$sPlace.'/PLACE}}', $sHtml);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $sHtml;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function bIsEnabled()
|
||||
{
|
||||
return $this->bIsEnabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function Count()
|
||||
{
|
||||
return $this->bIsEnabled ? \count($this->aPlugins) : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \MailSo\Log\Logger $oLogger
|
||||
*
|
||||
* @return \RainLoop\PluginsNext\Manager
|
||||
*
|
||||
* @throws \MailSo\Base\Exceptions\InvalidArgumentException
|
||||
*/
|
||||
public function SetLogger($oLogger)
|
||||
{
|
||||
if (!($oLogger instanceof \MailSo\Log\Logger))
|
||||
{
|
||||
throw new \MailSo\Base\Exceptions\InvalidArgumentException();
|
||||
}
|
||||
|
||||
$this->oLogger = $oLogger;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sDesc
|
||||
* @param int $iType = \MailSo\Log\Enumerations\Type::INFO
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function WriteLog($sDesc, $iType = \MailSo\Log\Enumerations\Type::INFO)
|
||||
{
|
||||
if ($this->oLogger)
|
||||
{
|
||||
$this->oLogger->Write($sDesc, $iType, 'PLUGIN');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sDesc
|
||||
* @param int $iType = \MailSo\Log\Enumerations\Type::INFO
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function WriteException($sDesc, $iType = \MailSo\Log\Enumerations\Type::INFO)
|
||||
{
|
||||
if ($this->oLogger)
|
||||
{
|
||||
$this->oLogger->WriteException($sDesc, $iType, 'PLUGIN');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,179 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace RainLoop\PluginsNext;
|
||||
|
||||
class Property
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sName;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sLabel;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sDesc;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $iType;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $bAllowedInJs;
|
||||
|
||||
/**
|
||||
* @var mixed
|
||||
*/
|
||||
private $mDefaultValue;
|
||||
|
||||
private function __construct($sName)
|
||||
{
|
||||
$this->sName = $sName;
|
||||
$this->iType = \RainLoop\Enumerations\PluginPropertyType::STRING;
|
||||
$this->mDefaultValue = '';
|
||||
$this->sLabel = '';
|
||||
$this->sDesc = '';
|
||||
$this->bAllowedInJs = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sName
|
||||
*
|
||||
* @return \RainLoop\PluginsNext\Property
|
||||
*/
|
||||
public static function NewInstance($sName)
|
||||
{
|
||||
return new self($sName);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $iType
|
||||
*
|
||||
* @return \RainLoop\PluginsNext\Property
|
||||
*/
|
||||
public function SetType($iType)
|
||||
{
|
||||
$this->iType = (int) $iType;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $mDefaultValue
|
||||
*
|
||||
* @return \RainLoop\PluginsNext\Property
|
||||
*/
|
||||
public function SetDefaultValue($mDefaultValue)
|
||||
{
|
||||
$this->mDefaultValue = $mDefaultValue;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sLabel
|
||||
*
|
||||
* @return \RainLoop\PluginsNext\Property
|
||||
*/
|
||||
public function SetLabel($sLabel)
|
||||
{
|
||||
$this->sLabel = $sLabel;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sDesc
|
||||
*
|
||||
* @return \RainLoop\PluginsNext\Property
|
||||
*/
|
||||
public function SetDescription($sDesc)
|
||||
{
|
||||
$this->sDesc = $sDesc;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $bValue = true
|
||||
*
|
||||
* @return \RainLoop\PluginsNext\Property
|
||||
*/
|
||||
public function SetAllowedInJs($bValue = true)
|
||||
{
|
||||
$this->bAllowedInJs = !!$bValue;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function Name()
|
||||
{
|
||||
return $this->sName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function AllowedInJs()
|
||||
{
|
||||
return $this->bAllowedInJs;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function Description()
|
||||
{
|
||||
return $this->sDesc;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function Label()
|
||||
{
|
||||
return $this->sLabel;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function Type()
|
||||
{
|
||||
return $this->iType;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function DefaultValue()
|
||||
{
|
||||
return $this->mDefaultValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function ToArray()
|
||||
{
|
||||
return array(
|
||||
'',
|
||||
$this->sName,
|
||||
$this->iType,
|
||||
$this->sLabel,
|
||||
$this->mDefaultValue,
|
||||
$this->sDesc
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,51 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace RainLoop\Providers;
|
||||
|
||||
abstract class AbstractProvider
|
||||
{
|
||||
/**
|
||||
* @var \RainLoop\Account
|
||||
*/
|
||||
protected $oAccount;
|
||||
|
||||
/**
|
||||
* @var \MailSo\Log\Logger
|
||||
*/
|
||||
protected $oLogger = null;
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function IsActive()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \RainLoop\Account $oAccount
|
||||
*/
|
||||
public function SetAccount($oAccount)
|
||||
{
|
||||
$this->oAccount = $oAccount;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \MailSo\Log\Logger $oLogger
|
||||
*/
|
||||
public function SetLogger($oLogger)
|
||||
{
|
||||
if ($oLogger instanceof \MailSo\Log\Logger)
|
||||
{
|
||||
$this->oLogger = $oLogger;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \MailSo\Log\Logger|null
|
||||
*/
|
||||
public function Logger()
|
||||
{
|
||||
return $this->oLogger;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,373 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace RainLoop\Providers;
|
||||
|
||||
use \RainLoop\Providers\AddressBook\Enumerations\PropertyType as PropertyType;
|
||||
|
||||
class AddressBook extends \RainLoop\Providers\AbstractProvider
|
||||
{
|
||||
/**
|
||||
* @var \RainLoop\Providers\AddressBook\AddressBookInterface
|
||||
*/
|
||||
private $oDriver;
|
||||
|
||||
/**
|
||||
* @param \RainLoop\Providers\AddressBook\Interface $oDriver
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($oDriver)
|
||||
{
|
||||
$this->oDriver = null;
|
||||
if ($oDriver instanceof \RainLoop\Providers\AddressBook\AddressBookInterface)
|
||||
{
|
||||
$this->oDriver = $oDriver;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function Test()
|
||||
{
|
||||
\sleep(1);
|
||||
return $this->oDriver instanceof \RainLoop\Providers\AddressBook\AddressBookInterface ?
|
||||
$this->oDriver->Test() : 'Personal address book driver is not allowed';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function IsActive()
|
||||
{
|
||||
return $this->oDriver instanceof \RainLoop\Providers\AddressBook\AddressBookInterface &&
|
||||
$this->oDriver->IsSupported();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function IsSupported()
|
||||
{
|
||||
return $this->oDriver instanceof \RainLoop\Providers\AddressBook\AddressBookInterface &&
|
||||
$this->oDriver->IsSupported();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function IsSharingAllowed()
|
||||
{
|
||||
return $this->oDriver instanceof \RainLoop\Providers\AddressBook\AddressBookInterface &&
|
||||
$this->oDriver->IsSharingAllowed();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sEmail
|
||||
* @param string $sUrl
|
||||
* @param string $sUser
|
||||
* @param string $sPassword
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function Sync($sEmail, $sUrl, $sUser, $sPassword)
|
||||
{
|
||||
return $this->IsActive() ? $this->oDriver->Sync($sEmail, $sUrl, $sUser, $sPassword) : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sEmail
|
||||
* @param string $sType = 'vcf'
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function Export($sEmail, $sType = 'vcf')
|
||||
{
|
||||
return $this->IsActive() ? $this->oDriver->Export($sEmail, $sType) : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sEmail
|
||||
* @param \RainLoop\Providers\AddressBook\Classes\Contact $oContact
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function ContactSave($sEmail, &$oContact)
|
||||
{
|
||||
return $this->IsActive() ? $this->oDriver->ContactSave($sEmail, $oContact) : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sEmail
|
||||
* @param array $aContactIds
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function DeleteContacts($sEmail, $aContactIds)
|
||||
{
|
||||
return $this->IsActive() ? $this->oDriver->DeleteContacts($sEmail, $aContactIds) : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sEmail
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function DeleteAllContacts($sEmail)
|
||||
{
|
||||
return $this->IsActive() ? $this->oDriver->DeleteAllContacts($sEmail) : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sEmail
|
||||
* @param int $iOffset = 0
|
||||
* @param type $iLimit = 20
|
||||
* @param string $sSearch = ''
|
||||
* @param int $iResultCount = 0
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function GetContacts($sEmail, $iOffset = 0, $iLimit = 20, $sSearch = '', &$iResultCount = 0)
|
||||
{
|
||||
return $this->IsActive() ? $this->oDriver->GetContacts($sEmail,
|
||||
$iOffset, $iLimit, $sSearch, $iResultCount) : array();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sEmail
|
||||
* @param string $mID
|
||||
* @param bool $bIsStrID = false
|
||||
*
|
||||
* @return \RainLoop\Providers\AddressBook\Classes\Contact|null
|
||||
*/
|
||||
public function GetContactByID($sEmail, $mID, $bIsStrID = false)
|
||||
{
|
||||
return $this->IsActive() ? $this->oDriver->GetContactByID($sEmail, $mID, $bIsStrID) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sEmail
|
||||
* @param string $sSearch
|
||||
* @param int $iLimit = 20
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function GetSuggestions($sEmail, $sSearch, $iLimit = 20)
|
||||
{
|
||||
return $this->IsActive() ? $this->oDriver->GetSuggestions($sEmail, $sSearch, $iLimit) : array();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sEmail
|
||||
* @param array $aEmails
|
||||
* @param bool $bCreateAuto = true
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function IncFrec($sEmail, $aEmails, $bCreateAuto = true)
|
||||
{
|
||||
return $this->IsActive() ? $this->oDriver->IncFrec($sEmail, $aEmails, $bCreateAuto) : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sCsvName
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
private function csvNameToTypeConvertor($sCsvName)
|
||||
{
|
||||
static $aMap = null;
|
||||
if (null === $aMap)
|
||||
{
|
||||
$aMap = array(
|
||||
'Title' => PropertyType::FULLNAME,
|
||||
'Name' => PropertyType::FULLNAME,
|
||||
'FullName' => PropertyType::FULLNAME,
|
||||
'DisplayName' => PropertyType::FULLNAME,
|
||||
'GivenName' => PropertyType::FULLNAME,
|
||||
'First' => PropertyType::FIRST_NAME,
|
||||
'FirstName' => PropertyType::FIRST_NAME,
|
||||
'Middle' => PropertyType::MIDDLE_NAME,
|
||||
'MiddleName' => PropertyType::MIDDLE_NAME,
|
||||
'Last' => PropertyType::LAST_NAME,
|
||||
'LastName' => PropertyType::LAST_NAME,
|
||||
'Suffix' => PropertyType::NAME_SUFFIX,
|
||||
'NameSuffix' => PropertyType::NAME_SUFFIX,
|
||||
'Prefix' => PropertyType::NAME_PREFIX,
|
||||
'NamePrefix' => PropertyType::NAME_PREFIX,
|
||||
'ShortName' => PropertyType::NICK_NAME,
|
||||
'NickName' => PropertyType::NICK_NAME,
|
||||
'BusinessFax' => array(PropertyType::PHONE, 'Work,Fax'),
|
||||
'BusinessFax2' => array(PropertyType::PHONE, 'Work,Fax'),
|
||||
'BusinessFax3' => array(PropertyType::PHONE, 'Work,Fax'),
|
||||
'BusinessPhone' => array(PropertyType::PHONE, 'Work'),
|
||||
'BusinessPhone2' => array(PropertyType::PHONE, 'Work'),
|
||||
'BusinessPhone3' => array(PropertyType::PHONE, 'Work'),
|
||||
'CompanyPhone' => array(PropertyType::PHONE, 'Work'),
|
||||
'CompanyMainPhone' => array(PropertyType::PHONE, 'Work'),
|
||||
'HomeFax' => array(PropertyType::PHONE, 'Home,Fax'),
|
||||
'HomeFax2' => array(PropertyType::PHONE, 'Home,Fax'),
|
||||
'HomeFax3' => array(PropertyType::PHONE, 'Home,Fax'),
|
||||
'HomePhone' => array(PropertyType::PHONE, 'Home'),
|
||||
'HomePhone2' => array(PropertyType::PHONE, 'Home'),
|
||||
'HomePhone3' => array(PropertyType::PHONE, 'Home'),
|
||||
'Mobile' => array(PropertyType::PHONE, 'Mobile'),
|
||||
'MobilePhone' => array(PropertyType::PHONE, 'Mobile'),
|
||||
'BusinessMobile' => array(PropertyType::PHONE, 'Work,Mobile'),
|
||||
'BusinessMobilePhone' => array(PropertyType::PHONE, 'Work,Mobile'),
|
||||
'OtherFax' => array(PropertyType::PHONE, 'Other,Fax'),
|
||||
'OtherPhone' => array(PropertyType::PHONE, 'Other'),
|
||||
'PrimaryPhone' => array(PropertyType::PHONE, 'Pref,Home'),
|
||||
'Email' => array(PropertyType::EMAIl, 'Home'),
|
||||
'Email2' => array(PropertyType::EMAIl, 'Home'),
|
||||
'Email3' => array(PropertyType::EMAIl, 'Home'),
|
||||
'HomeEmail' => array(PropertyType::EMAIl, 'Home'),
|
||||
'HomeEmail2' => array(PropertyType::EMAIl, 'Home'),
|
||||
'HomeEmail3' => array(PropertyType::EMAIl, 'Home'),
|
||||
'EmailAddress' => array(PropertyType::EMAIl, 'Home'),
|
||||
'Email2Address' => array(PropertyType::EMAIl, 'Home'),
|
||||
'Email3Address' => array(PropertyType::EMAIl, 'Home'),
|
||||
'OtherEmail' => array(PropertyType::EMAIl, 'Other'),
|
||||
'BusinessEmail' => array(PropertyType::EMAIl, 'Work'),
|
||||
'BusinessEmail2' => array(PropertyType::EMAIl, 'Work'),
|
||||
'BusinessEmail3' => array(PropertyType::EMAIl, 'Work'),
|
||||
'PersonalEmail' => array(PropertyType::EMAIl, 'Home'),
|
||||
'PersonalEmail2' => array(PropertyType::EMAIl, 'Home'),
|
||||
'PersonalEmail3' => array(PropertyType::EMAIl, 'Home'),
|
||||
'Notes' => PropertyType::NOTE,
|
||||
'Web' => PropertyType::WEB_PAGE,
|
||||
'BusinessWeb' => array(PropertyType::WEB_PAGE, 'Work'),
|
||||
'WebPage' => PropertyType::WEB_PAGE,
|
||||
'BusinessWebPage' => array(PropertyType::WEB_PAGE, 'Work'),
|
||||
'WebSite' => PropertyType::WEB_PAGE,
|
||||
'BusinessWebSite' => array(PropertyType::WEB_PAGE, 'Work'),
|
||||
'PersonalWebSite' => PropertyType::WEB_PAGE
|
||||
);
|
||||
|
||||
$aMap = \array_change_key_case($aMap, CASE_LOWER);
|
||||
}
|
||||
|
||||
$sCsvNameLower = \MailSo\Base\Utils::IsAscii($sCsvName) ? \preg_replace('/[\s\-]+/', '', \strtolower($sCsvName)) : '';
|
||||
return !empty($sCsvNameLower) && isset($aMap[$sCsvNameLower]) ? $aMap[$sCsvNameLower] : PropertyType::UNKNOWN;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sEmail
|
||||
* @param array $aCsvData
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function ImportCsvArray($sEmail, $aCsvData)
|
||||
{
|
||||
$iCount = 0;
|
||||
if ($this->IsActive() && \is_array($aCsvData) && 0 < \count($aCsvData))
|
||||
{
|
||||
$oContact = new \RainLoop\Providers\AddressBook\Classes\Contact();
|
||||
foreach ($aCsvData as $aItem)
|
||||
{
|
||||
\MailSo\Base\Utils::ResetTimeLimit();
|
||||
|
||||
foreach ($aItem as $sItemName => $sItemValue)
|
||||
{
|
||||
$sItemName = \trim($sItemName);
|
||||
$sItemValue = \trim($sItemValue);
|
||||
|
||||
if (!empty($sItemName) && !empty($sItemValue))
|
||||
{
|
||||
$mData = $this->csvNameToTypeConvertor($sItemName);
|
||||
$iType = \is_array($mData) ? $mData[0] : $mData;
|
||||
|
||||
if (PropertyType::UNKNOWN !== $iType)
|
||||
{
|
||||
$oProp = new \RainLoop\Providers\AddressBook\Classes\Property();
|
||||
$oProp->Type = $iType;
|
||||
$oProp->Value = $sItemValue;
|
||||
$oProp->TypeStr = \is_array($mData) && !empty($mData[1]) ? $mData[1] : '';
|
||||
|
||||
$oContact->Properties[] = $oProp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($oContact && 0 < \count($oContact->Properties))
|
||||
{
|
||||
if ($this->ContactSave($sEmail, $oContact))
|
||||
{
|
||||
$iCount++;
|
||||
}
|
||||
}
|
||||
|
||||
$oContact->Clear();
|
||||
}
|
||||
|
||||
unset($oContact);
|
||||
}
|
||||
|
||||
return $iCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sEmail
|
||||
* @param string $sVcfData
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function ImportVcfFile($sEmail, $sVcfData)
|
||||
{
|
||||
$iCount = 0;
|
||||
if ($this->IsActive() && \is_string($sVcfData))
|
||||
{
|
||||
$sVcfData = \trim($sVcfData);
|
||||
if ("\xef\xbb\xbf" === \substr($sVcfData, 0, 3))
|
||||
{
|
||||
$sVcfData = \substr($sVcfData, 3);
|
||||
}
|
||||
|
||||
$oVCardSplitter = null;
|
||||
try
|
||||
{
|
||||
$oVCardSplitter = new \Sabre\VObject\Splitter\VCard($sVcfData);
|
||||
}
|
||||
catch (\Exception $oExc)
|
||||
{
|
||||
$this->Logger()->WriteException($oExc);
|
||||
}
|
||||
|
||||
if ($oVCardSplitter)
|
||||
{
|
||||
$oContact = new \RainLoop\Providers\AddressBook\Classes\Contact();
|
||||
|
||||
$oVCard = null;
|
||||
|
||||
while ($oVCard = $oVCardSplitter->getNext())
|
||||
{
|
||||
if ($oVCard instanceof \Sabre\VObject\Component\VCard)
|
||||
{
|
||||
\MailSo\Base\Utils::ResetTimeLimit();
|
||||
|
||||
if (empty($oVCard->UID))
|
||||
{
|
||||
$oVCard->UID = \Sabre\DAV\UUIDUtil::getUUID();
|
||||
}
|
||||
|
||||
$oContact->PopulateByVCard($oVCard->serialize());
|
||||
|
||||
if (0 < \count($oContact->Properties))
|
||||
{
|
||||
if ($this->ContactSave($sEmail, $oContact))
|
||||
{
|
||||
$iCount++;
|
||||
}
|
||||
}
|
||||
|
||||
$oContact->Clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $iCount;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace RainLoop\Providers\AddressBook;
|
||||
|
||||
interface AddressBookInterface
|
||||
{
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function IsSupported();
|
||||
}
|
||||
|
|
@ -1,583 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace RainLoop\Providers\AddressBook\Classes;
|
||||
|
||||
use
|
||||
RainLoop\Providers\AddressBook\Enumerations\PropertyType,
|
||||
RainLoop\Providers\AddressBook\Classes\Property
|
||||
;
|
||||
|
||||
class Contact
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $IdContact;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $IdContactStr;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $Display;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
public $Changed;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
public $Properties;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
public $ReadOnly;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
public $IdPropertyFromSearch;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $Etag;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->Clear();
|
||||
}
|
||||
|
||||
public function Clear()
|
||||
{
|
||||
$this->IdContact = '';
|
||||
$this->IdContactStr = '';
|
||||
$this->Display = '';
|
||||
$this->Changed = \time();
|
||||
$this->Properties = array();
|
||||
$this->ReadOnly = false;
|
||||
$this->IdPropertyFromSearch = 0;
|
||||
$this->Etag = '';
|
||||
}
|
||||
|
||||
public function UpdateDependentValues()
|
||||
{
|
||||
$sLastName = '';
|
||||
$sFirstName = '';
|
||||
$sEmail = '';
|
||||
$sOther = '';
|
||||
|
||||
$oFullNameProperty = null;
|
||||
|
||||
foreach ($this->Properties as /* @var $oProperty \RainLoop\Providers\AddressBook\Classes\Property */ &$oProperty)
|
||||
{
|
||||
if ($oProperty)
|
||||
{
|
||||
$oProperty->UpdateDependentValues();
|
||||
|
||||
if (!$oFullNameProperty && PropertyType::FULLNAME === $oProperty->Type)
|
||||
{
|
||||
$oFullNameProperty =& $oProperty;
|
||||
}
|
||||
|
||||
if (0 < \strlen($oProperty->Value))
|
||||
{
|
||||
if ('' === $sEmail && $oProperty->IsEmail())
|
||||
{
|
||||
$sEmail = $oProperty->Value;
|
||||
}
|
||||
else if ('' === $sLastName && PropertyType::LAST_NAME === $oProperty->Type)
|
||||
{
|
||||
$sLastName = $oProperty->Value;
|
||||
}
|
||||
else if ('' === $sFirstName && PropertyType::FIRST_NAME === $oProperty->Type)
|
||||
{
|
||||
$sFirstName = $oProperty->Value;
|
||||
}
|
||||
else if (\in_array($oProperty->Type, array(
|
||||
PropertyType::FULLNAME, PropertyType::PHONE
|
||||
)))
|
||||
{
|
||||
$sOther = $oProperty->Value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($this->IdContactStr))
|
||||
{
|
||||
$this->RegenerateContactStr();
|
||||
}
|
||||
|
||||
$sDisplay = '';
|
||||
if (0 < \strlen($sLastName) || 0 < \strlen($sFirstName))
|
||||
{
|
||||
$sDisplay = \trim($sFirstName.' '.$sLastName);
|
||||
}
|
||||
|
||||
if ('' === $sDisplay && 0 < \strlen($sEmail))
|
||||
{
|
||||
$sDisplay = \trim($sEmail);
|
||||
}
|
||||
|
||||
if ('' === $sDisplay)
|
||||
{
|
||||
$sDisplay = $sOther;
|
||||
}
|
||||
|
||||
$this->Display = \trim($sDisplay);
|
||||
|
||||
if ($oFullNameProperty)
|
||||
{
|
||||
$oFullNameProperty->Value = $this->Display;
|
||||
$oFullNameProperty->UpdateDependentValues();
|
||||
}
|
||||
|
||||
if (!$oFullNameProperty)
|
||||
{
|
||||
$this->Properties[] = new \RainLoop\Providers\AddressBook\Classes\Property(PropertyType::FULLNAME, $this->Display);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function RegenerateContactStr()
|
||||
{
|
||||
$this->IdContactStr = \Sabre\DAV\UUIDUtil::getUUID();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function GetEmails()
|
||||
{
|
||||
$aResult = array();
|
||||
foreach ($this->Properties as /* @var $oProperty \RainLoop\Providers\AddressBook\Classes\Property */ &$oProperty)
|
||||
{
|
||||
if ($oProperty && $oProperty->IsEmail())
|
||||
{
|
||||
$aResult[] = $oProperty->Value;
|
||||
}
|
||||
}
|
||||
|
||||
return \array_unique($aResult);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function CardDavNameUri()
|
||||
{
|
||||
return $this->IdContactStr.'.vcf';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function ToVCard($sPreVCard = '')
|
||||
{
|
||||
$this->UpdateDependentValues();
|
||||
|
||||
$oVCard = null;
|
||||
if (0 < \strlen($sPreVCard))
|
||||
{
|
||||
try
|
||||
{
|
||||
$oVCard = \Sabre\VObject\Reader::read($sPreVCard);
|
||||
}
|
||||
catch (\Exception $oExc) {};
|
||||
}
|
||||
|
||||
if (!$oVCard)
|
||||
{
|
||||
$oVCard = new \Sabre\VObject\Component\VCard();
|
||||
}
|
||||
|
||||
$oVCard->VERSION = '3.0';
|
||||
$oVCard->PRODID = '-//RainLoop//'.APP_VERSION.'//EN';
|
||||
|
||||
unset($oVCard->FN, $oVCard->EMAIL, $oVCard->TEL, $oVCard->URL, $oVCard->NICKNAME);
|
||||
|
||||
$sFirstName = $sLastName = $sMiddleName = $sSuffix = $sPrefix = '';
|
||||
foreach ($this->Properties as /* @var $oProperty \RainLoop\Providers\AddressBook\Classes\Property */ &$oProperty)
|
||||
{
|
||||
if ($oProperty)
|
||||
{
|
||||
$sAddKey = '';
|
||||
switch ($oProperty->Type)
|
||||
{
|
||||
case PropertyType::FULLNAME:
|
||||
$oVCard->FN = $oProperty->Value;
|
||||
break;
|
||||
case PropertyType::NICK_NAME:
|
||||
$oVCard->NICKNAME = $oProperty->Value;
|
||||
break;
|
||||
case PropertyType::NOTE:
|
||||
$oVCard->NOTE = $oProperty->Value;
|
||||
break;
|
||||
case PropertyType::FIRST_NAME:
|
||||
$sFirstName = $oProperty->Value;
|
||||
break;
|
||||
case PropertyType::LAST_NAME:
|
||||
$sLastName = $oProperty->Value;
|
||||
break;
|
||||
case PropertyType::MIDDLE_NAME:
|
||||
$sMiddleName = $oProperty->Value;
|
||||
break;
|
||||
case PropertyType::NAME_SUFFIX:
|
||||
$sSuffix = $oProperty->Value;
|
||||
break;
|
||||
case PropertyType::NAME_PREFIX:
|
||||
$sPrefix = $oProperty->Value;
|
||||
break;
|
||||
case PropertyType::EMAIl:
|
||||
if (empty($sAddKey))
|
||||
{
|
||||
$sAddKey = 'EMAIL';
|
||||
}
|
||||
case PropertyType::WEB_PAGE:
|
||||
if (empty($sAddKey))
|
||||
{
|
||||
$sAddKey = 'URL';
|
||||
}
|
||||
case PropertyType::PHONE:
|
||||
if (empty($sAddKey))
|
||||
{
|
||||
$sAddKey = 'TEL';
|
||||
}
|
||||
|
||||
$aTypes = $oProperty->TypesAsArray();
|
||||
$oVCard->add($sAddKey, $oProperty->Value, \is_array($aTypes) && 0 < \count($aTypes) ? array('TYPE' => $aTypes) : null);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$oVCard->UID = $this->IdContactStr;
|
||||
$oVCard->N = array($sLastName, $sFirstName, $sMiddleName, $sPrefix, $sSuffix);
|
||||
$oVCard->REV = \gmdate('Ymd', $this->Changed).'T'.\gmdate('His', $this->Changed).'Z';
|
||||
|
||||
return (string) $oVCard->serialize();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function ToCsv($bWithHeader = false)
|
||||
{
|
||||
$aData = array();
|
||||
if ($bWithHeader)
|
||||
{
|
||||
$aData[] = array(
|
||||
'Title', 'First Name', 'Middle Name', 'Last Name', 'Nick Name', 'Display Name',
|
||||
'Company', 'Department', 'Job Title', 'Office Location',
|
||||
'E-mail Address', 'Notes', 'Web Page', 'Birthday',
|
||||
'Other Email', 'Other Phone', 'Other Mobile', 'Mobile Phone',
|
||||
'Home Email', 'Home Phone', 'Home Fax',
|
||||
'Home Street', 'Home City', 'Home State', 'Home Postal Code', 'Home Country',
|
||||
'Business Email', 'Business Phone', 'Business Fax',
|
||||
'Business Street', 'Business City', 'Business State', 'Business Postal Code', 'Business Country'
|
||||
);
|
||||
}
|
||||
|
||||
$aValues = array(
|
||||
'', // 0 'Title',
|
||||
'', // 1 'First Name',
|
||||
'', // 2 'Middle Name',
|
||||
'', // 3 'Last Name',
|
||||
'', // 4 'Nick Name',
|
||||
'', // 5 'Display Name',
|
||||
'', // 6 'Company',
|
||||
'', // 7 'Department',
|
||||
'', // 8 'Job Title',
|
||||
'', // 9 'Office Location',
|
||||
'', // 10 'E-mail Address',
|
||||
'', // 11 'Notes',
|
||||
'', // 12 'Web Page',
|
||||
'', // 13 'Birthday',
|
||||
'', // 14 'Other Email',
|
||||
'', // 15 'Other Phone',
|
||||
'', // 16 'Other Mobile',
|
||||
'', // 17 'Mobile Phone',
|
||||
'', // 18 'Home Email',
|
||||
'', // 19 'Home Phone',
|
||||
'', // 20 'Home Fax',
|
||||
'', // 21 'Home Street',
|
||||
'', // 22 'Home City',
|
||||
'', // 23 'Home State',
|
||||
'', // 24 'Home Postal Code',
|
||||
'', // 25 'Home Country',
|
||||
'', // 26 'Business Email',
|
||||
'', // 27 'Business Phone',
|
||||
'', // 28 'Business Fax',
|
||||
'', // 29 'Business Street',
|
||||
'', // 30 'Business City',
|
||||
'', // 31 'Business State',
|
||||
'', // 32 'Business Postal Code',
|
||||
'' // 33 'Business Country'
|
||||
);
|
||||
|
||||
$this->UpdateDependentValues();
|
||||
|
||||
foreach ($this->Properties as /* @var $oProperty \RainLoop\Providers\AddressBook\Classes\Property */ &$oProperty)
|
||||
{
|
||||
$iIndex = -1;
|
||||
if ($oProperty)
|
||||
{
|
||||
$aUpperTypes = $oProperty->TypesUpperAsArray();
|
||||
switch ($oProperty->Type)
|
||||
{
|
||||
case PropertyType::FULLNAME:
|
||||
$iIndex = 5;
|
||||
break;
|
||||
case PropertyType::NICK_NAME:
|
||||
$iIndex = 4;
|
||||
break;
|
||||
case PropertyType::FIRST_NAME:
|
||||
$iIndex = 1;
|
||||
break;
|
||||
case PropertyType::LAST_NAME:
|
||||
$iIndex = 3;
|
||||
break;
|
||||
case PropertyType::MIDDLE_NAME:
|
||||
$iIndex = 2;
|
||||
break;
|
||||
case PropertyType::EMAIl:
|
||||
switch (true)
|
||||
{
|
||||
case \in_array('OTHER', $aUpperTypes):
|
||||
$iIndex = 14;
|
||||
break;
|
||||
case \in_array('WORK', $aUpperTypes):
|
||||
$iIndex = 26;
|
||||
break;
|
||||
default:
|
||||
$iIndex = 18;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case PropertyType::PHONE:
|
||||
switch (true)
|
||||
{
|
||||
case \in_array('OTHER', $aUpperTypes):
|
||||
$iIndex = 15;
|
||||
break;
|
||||
case \in_array('WORK', $aUpperTypes):
|
||||
$iIndex = 27;
|
||||
break;
|
||||
case \in_array('MOBILE', $aUpperTypes):
|
||||
$iIndex = 17;
|
||||
break;
|
||||
default:
|
||||
$iIndex = 19;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case PropertyType::WEB_PAGE:
|
||||
$iIndex = 12;
|
||||
break;
|
||||
case PropertyType::NOTE:
|
||||
$iIndex = 11;
|
||||
break;
|
||||
}
|
||||
|
||||
if (-1 < $iIndex)
|
||||
{
|
||||
$aValues[$iIndex] = $oProperty->Value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// subfix
|
||||
if (empty($aValues[10])) // 'E-mail Address'
|
||||
{
|
||||
if (!empty($aValues[18]))
|
||||
{
|
||||
$aValues[10] = $aValues[18];
|
||||
}
|
||||
else if (!empty($aValues[26]))
|
||||
{
|
||||
$aValues[10] = $aValues[26];
|
||||
}
|
||||
else if (!empty($aValues[14]))
|
||||
{
|
||||
$aValues[10] = $aValues[14];
|
||||
}
|
||||
}
|
||||
|
||||
$aData[] = \array_map(function ($sValue) {
|
||||
$sValue = \trim($sValue);
|
||||
return \preg_match('/[\r\n,"]/', $sValue) ? '"'.\str_replace('"', '""', $sValue).'"' : $sValue;
|
||||
}, $aValues);
|
||||
|
||||
$sResult = '';
|
||||
foreach ($aData as $aSubData)
|
||||
{
|
||||
$sResult .= \implode(',', $aSubData)."\r\n";
|
||||
}
|
||||
|
||||
return $sResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $oProp
|
||||
* @param bool $bOldVersion
|
||||
* @return string
|
||||
*/
|
||||
private function getPropertyValueHelper($oProp, $bOldVersion)
|
||||
{
|
||||
$sValue = \trim($oProp);
|
||||
if ($bOldVersion && !isset($oProp->parameters['CHARSET']))
|
||||
{
|
||||
if (0 < \strlen($sValue))
|
||||
{
|
||||
$sEncValue = @\utf8_encode($sValue);
|
||||
if (0 === \strlen($sEncValue))
|
||||
{
|
||||
$sEncValue = $sValue;
|
||||
}
|
||||
|
||||
$sValue = $sEncValue;
|
||||
}
|
||||
}
|
||||
|
||||
return \MailSo\Base\Utils::Utf8Clear($sValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $oProp
|
||||
* @param bool $bOldVersion
|
||||
* @return string
|
||||
*/
|
||||
private function addArrayPropertyHelper(&$aProperties, $oArrayProp, $iType)
|
||||
{
|
||||
foreach ($oArrayProp as $oProp)
|
||||
{
|
||||
$oTypes = $oProp ? $oProp['TYPE'] : null;
|
||||
$aTypes = $oTypes ? $oTypes->getParts() : array();
|
||||
$sValue = $oProp ? \trim($oProp->getValue()) : '';
|
||||
|
||||
if (0 < \strlen($sValue))
|
||||
{
|
||||
if (!$oTypes || $oTypes->has('PREF'))
|
||||
{
|
||||
\array_unshift($aProperties, new Property($iType, $sValue, \implode(',', $aTypes)));
|
||||
}
|
||||
else
|
||||
{
|
||||
\array_push($aProperties, new Property($iType, $sValue, \implode(',', $aTypes)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function PopulateByVCard($sVCard, $sEtag = '')
|
||||
{
|
||||
$this->Properties = array();
|
||||
|
||||
if (!empty($sEtag))
|
||||
{
|
||||
$this->Etag = $sEtag;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
$oVCard = \Sabre\VObject\Reader::read($sVCard);
|
||||
}
|
||||
catch (\Exception $oExc) {};
|
||||
|
||||
$aProperties = array();
|
||||
if ($oVCard)
|
||||
{
|
||||
$bOldVersion = empty($oVCard->VERSION) ? false :
|
||||
\in_array((string) $oVCard->VERSION, array('2.1', '2.0', '1.0'));
|
||||
|
||||
$this->IdContactStr = $oVCard->UID ? (string) $oVCard->UID : \Sabre\DAV\UUIDUtil::getUUID();
|
||||
|
||||
if (isset($oVCard->FN) && '' !== \trim($oVCard->FN))
|
||||
{
|
||||
$sValue = $this->getPropertyValueHelper($oVCard->FN, $bOldVersion);
|
||||
$aProperties[] = new Property(PropertyType::FULLNAME, $sValue);
|
||||
}
|
||||
|
||||
if (isset($oVCard->NICKNAME) && '' !== \trim($oVCard->NICKNAME))
|
||||
{
|
||||
$sValue = $sValue = $this->getPropertyValueHelper($oVCard->NICKNAME, $bOldVersion);
|
||||
$aProperties[] = new Property(PropertyType::NICK_NAME, $sValue);
|
||||
}
|
||||
|
||||
if (isset($oVCard->NOTE) && '' !== \trim($oVCard->NOTE))
|
||||
{
|
||||
$sValue = $this->getPropertyValueHelper($oVCard->NOTE, $bOldVersion);
|
||||
$aProperties[] = new Property(PropertyType::NOTE, $sValue);
|
||||
}
|
||||
|
||||
if (isset($oVCard->N))
|
||||
{
|
||||
$aNames = $oVCard->N->getParts();
|
||||
foreach ($aNames as $iIndex => $sValue)
|
||||
{
|
||||
$sValue = \trim($sValue);
|
||||
if ($bOldVersion && !isset($oVCard->N->parameters['CHARSET']))
|
||||
{
|
||||
if (0 < \strlen($sValue))
|
||||
{
|
||||
$sEncValue = @\utf8_encode($sValue);
|
||||
if (0 === \strlen($sEncValue))
|
||||
{
|
||||
$sEncValue = $sValue;
|
||||
}
|
||||
|
||||
$sValue = $sEncValue;
|
||||
}
|
||||
}
|
||||
|
||||
$sValue = \MailSo\Base\Utils::Utf8Clear($sValue);
|
||||
switch ($iIndex) {
|
||||
case 0:
|
||||
$aProperties[] = new Property(PropertyType::LAST_NAME, $sValue);
|
||||
break;
|
||||
case 1:
|
||||
$aProperties[] = new Property(PropertyType::FIRST_NAME, $sValue);
|
||||
break;
|
||||
case 2:
|
||||
$aProperties[] = new Property(PropertyType::MIDDLE_NAME, $sValue);
|
||||
break;
|
||||
case 3:
|
||||
$aProperties[] = new Property(PropertyType::NAME_PREFIX, $sValue);
|
||||
break;
|
||||
case 4:
|
||||
$aProperties[] = new Property(PropertyType::NAME_SUFFIX, $sValue);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($oVCard->EMAIL))
|
||||
{
|
||||
$this->addArrayPropertyHelper($aProperties, $oVCard->EMAIL, PropertyType::EMAIl);
|
||||
}
|
||||
|
||||
if (isset($oVCard->URL))
|
||||
{
|
||||
$this->addArrayPropertyHelper($aProperties, $oVCard->URL, PropertyType::WEB_PAGE);
|
||||
}
|
||||
|
||||
if (isset($oVCard->TEL))
|
||||
{
|
||||
$this->addArrayPropertyHelper($aProperties, $oVCard->TEL, PropertyType::PHONE);
|
||||
}
|
||||
|
||||
$this->Properties = $aProperties;
|
||||
}
|
||||
|
||||
$this->UpdateDependentValues();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,133 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace RainLoop\Providers\AddressBook\Classes;
|
||||
|
||||
use RainLoop\Providers\AddressBook\Enumerations\PropertyType;
|
||||
|
||||
class Property
|
||||
{
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
public $IdProperty;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
public $Type;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $TypeStr;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $Value;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $ValueCustom;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
public $Frec;
|
||||
|
||||
public function __construct(
|
||||
$iType = \RainLoop\Providers\AddressBook\Enumerations\PropertyType::UNKNOWN, $sValue = '', $sTypeStr = '')
|
||||
{
|
||||
$this->Clear();
|
||||
|
||||
$this->Type = $iType;
|
||||
$this->Value = $sValue;
|
||||
$this->TypeStr = $sTypeStr;
|
||||
}
|
||||
|
||||
public function Clear()
|
||||
{
|
||||
$this->IdProperty = 0;
|
||||
|
||||
$this->Type = PropertyType::UNKNOWN;
|
||||
$this->TypeStr = '';
|
||||
|
||||
$this->Value = '';
|
||||
$this->ValueCustom = '';
|
||||
|
||||
$this->Frec = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function IsEmail()
|
||||
{
|
||||
return PropertyType::EMAIl === $this->Type;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function IsPhone()
|
||||
{
|
||||
return PropertyType::PHONE === $this->Type;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function IsWeb()
|
||||
{
|
||||
return PropertyType::WEB_PAGE === $this->Type;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function TypesAsArray()
|
||||
{
|
||||
$aResult = array();
|
||||
if (!empty($this->TypeStr))
|
||||
{
|
||||
$sTypeStr = \preg_replace('/[\s]+/', '', $this->TypeStr);
|
||||
$aResult = \explode(',', $sTypeStr);
|
||||
}
|
||||
|
||||
return $aResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function TypesUpperAsArray()
|
||||
{
|
||||
return \array_map('strtoupper', $this->TypesAsArray());
|
||||
}
|
||||
|
||||
public function UpdateDependentValues()
|
||||
{
|
||||
$this->Value = \trim($this->Value);
|
||||
$this->ValueCustom = \trim($this->ValueCustom);
|
||||
$this->TypeStr = \trim($this->TypeStr);
|
||||
|
||||
if (0 < \strlen($this->Value))
|
||||
{
|
||||
// lower
|
||||
if ($this->IsEmail())
|
||||
{
|
||||
$this->Value = \MailSo\Base\Utils::StrToLowerIfAscii($this->Value);
|
||||
}
|
||||
|
||||
// phones clear value for searching
|
||||
if ($this->IsPhone())
|
||||
{
|
||||
$sPhone = $this->Value;
|
||||
$sPhone = \preg_replace('/^[+]+/', '', $sPhone);
|
||||
$sPhone = \preg_replace('/[^\d]/', '', $sPhone);
|
||||
$this->ValueCustom = $sPhone;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,33 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace RainLoop\Providers\AddressBook\Classes;
|
||||
|
||||
class Tag
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $IdContactTag;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $Name;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
public $ReadOnly;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->Clear();
|
||||
}
|
||||
|
||||
public function Clear()
|
||||
{
|
||||
$this->IdContactTag = '';
|
||||
$this->Name = '';
|
||||
$this->ReadOnly = false;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,34 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace RainLoop\Providers\AddressBook\Enumerations;
|
||||
|
||||
class PropertyType
|
||||
{
|
||||
const UNKNOWN = 0;
|
||||
|
||||
const FULLNAME = 10;
|
||||
|
||||
const FIRST_NAME = 15;
|
||||
const LAST_NAME = 16;
|
||||
const MIDDLE_NAME = 17;
|
||||
const NICK_NAME = 18;
|
||||
|
||||
const NAME_PREFIX = 20;
|
||||
const NAME_SUFFIX = 21;
|
||||
|
||||
const EMAIl = 30;
|
||||
const PHONE = 31;
|
||||
// const MOBILE = 32;
|
||||
// const FAX = 33;
|
||||
const WEB_PAGE = 32;
|
||||
|
||||
const BIRTHDAY = 40;
|
||||
|
||||
const FACEBOOK = 90;
|
||||
const SKYPE = 91;
|
||||
const GITHUB = 92;
|
||||
|
||||
const NOTE = 110;
|
||||
|
||||
const CUSTOM = 250;
|
||||
}
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -1,108 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace RainLoop\Providers;
|
||||
|
||||
class ChangePassword extends \RainLoop\Providers\AbstractProvider
|
||||
{
|
||||
/**
|
||||
* @var \RainLoop\Actions
|
||||
*/
|
||||
private $oActions;
|
||||
|
||||
/**
|
||||
* @var \RainLoop\Providers\ChangePassword\ChangePasswordInterface
|
||||
*/
|
||||
private $oDriver;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $bCheckWeak;
|
||||
|
||||
/**
|
||||
* @param \RainLoop\Actions $oActions
|
||||
* @param \RainLoop\Providers\ChangePassword\ChangePasswordInterface|null $oDriver = null
|
||||
* @param bool $bCheckWeak = true
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($oActions, $oDriver = null, $bCheckWeak = true)
|
||||
{
|
||||
$this->oActions = $oActions;
|
||||
$this->oDriver = $oDriver;
|
||||
$this->bCheckWeak = !!$bCheckWeak;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \RainLoop\Account $oAccount
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function PasswordChangePossibility($oAccount)
|
||||
{
|
||||
return $this->IsActive() &&
|
||||
$oAccount instanceof \RainLoop\Account &&
|
||||
$this->oDriver && $this->oDriver->PasswordChangePossibility($oAccount)
|
||||
;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \RainLoop\Account $oAccount
|
||||
* @param string $sPrevPassword
|
||||
* @param string $sNewPassword
|
||||
*/
|
||||
public function ChangePassword(\RainLoop\Account $oAccount, $sPrevPassword, $sNewPassword)
|
||||
{
|
||||
if ($this->oDriver instanceof \RainLoop\Providers\ChangePassword\ChangePasswordInterface &&
|
||||
$this->PasswordChangePossibility($oAccount))
|
||||
{
|
||||
if ($sPrevPassword !== $oAccount->Password())
|
||||
{
|
||||
throw new \RainLoop\Exceptions\ClientException(\RainLoop\Notifications::CurrentPasswordIncorrect);
|
||||
}
|
||||
|
||||
$this->weaknessCheck($sNewPassword);
|
||||
|
||||
if (!$this->oDriver->ChangePassword($oAccount, $sPrevPassword, $sNewPassword))
|
||||
{
|
||||
throw new \RainLoop\Exceptions\ClientException(\RainLoop\Notifications::CouldNotSaveNewPassword);
|
||||
}
|
||||
|
||||
$oAccount->SetPassword($sNewPassword);
|
||||
$this->oActions->SetAuthToken($oAccount);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new \RainLoop\Exceptions\ClientException(\RainLoop\Notifications::CouldNotSaveNewPassword);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function IsActive()
|
||||
{
|
||||
return $this->oDriver instanceof \RainLoop\Providers\ChangePassword\ChangePasswordInterface;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sPassword
|
||||
*/
|
||||
public function weaknessCheck($sPassword)
|
||||
{
|
||||
$sPassword = \trim($sPassword);
|
||||
if (4 > \strlen($sPassword))
|
||||
{
|
||||
throw new \RainLoop\Exceptions\ClientException(\RainLoop\Notifications::NewPasswordShort);
|
||||
}
|
||||
|
||||
if ($this->bCheckWeak)
|
||||
{
|
||||
$sLine = ' password 123.456 12345678 abc123 qwerty monkey letmein dragon 111.111 baseball iloveyou trustno1 1234567 sunshine master 123.123 welcome shadow ashley football jesus michael ninja mustang password1 123456 123456789 qwerty 111111 1234567 666666 12345678 7777777 123321 654321 1234567890 123123 555555 vkontakte gfhjkm 159753 777777 temppassword qazwsx 1q2w3e 1234 112233 121212 qwertyuiop qq18ww899 987654321 12345 zxcvbn zxcvbnm 999999 samsung ghbdtn 1q2w3e4r 1111111 123654 159357 131313 qazwsxedc 123qwe 222222 asdfgh 333333 9379992 asdfghjkl 4815162342 12344321 88888888 11111111 knopka 789456 qwertyu 1q2w3e4r5t iloveyou vfhbyf marina password qweasdzxc 10203 987654 yfnfif cjkysirj nikita 888888 vfrcbv k.,jdm qwertyuiop[] qwe123 qweasd natasha 123123123 fylhtq q1w2e3 stalker 1111111111 q1w2e3r4 nastya 147258369 147258 fyfcnfcbz 1234554321 1qaz2wsx andrey 111222 147852 genius sergey 7654321 232323 123789 fktrcfylh spartak admin test 123 azerty abc123 lol123 easytocrack1 hello saravn holysh!t test123 tundra_cool2 456 dragon thomas killer root 1111 pass master aaaaaa a monkey daniel asdasd e10adc3949ba59abbe56e057f20f883e changeme computer jessica letmein mirage loulou lol superman shadow admin123 secret administrator sophie kikugalanetroot doudou liverpool hallo sunshine charlie parola 100827092 michael andrew password1 fuckyou matrix cjmasterinf internet hallo123 eminem demo gewinner pokemon abcd1234 guest ngockhoa martin sandra asdf hejsan george qweqwe lollipop lovers q1q1q1 tecktonik naruto 12 password12 password123 password1234 password12345 password123456 password1234567 password12345678 password123456789 000000 maximius 123abc baseball1 football1 soccer princess slipknot 11111 nokia super star 666999 12341234 1234321 135790 159951 212121 zzzzzz 121314 134679 142536 19921992 753951 7007 1111114 124578 19951995 258456 qwaszx zaqwsx 55555 77777 54321 qwert 22222 33333 99999 88888 66666 ';
|
||||
if (false !== \strpos($sLine, \strtolower($sPassword)))
|
||||
{
|
||||
throw new \RainLoop\Exceptions\ClientException(\RainLoop\Notifications::NewPasswordWeak);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,22 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace RainLoop\Providers\ChangePassword;
|
||||
|
||||
interface ChangePasswordInterface
|
||||
{
|
||||
/**
|
||||
* @param \RainLoop\Account $oAccount
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function PasswordChangePossibility($oAccount);
|
||||
|
||||
/**
|
||||
* @param \RainLoop\Account $oAccount
|
||||
* @param string $sPrevPassword
|
||||
* @param string $sNewPassword
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function ChangePassword(\RainLoop\Account $oAccount, $sPrevPassword, $sNewPassword);
|
||||
}
|
||||
|
|
@ -1,183 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace RainLoop\Providers;
|
||||
|
||||
class Domain extends \RainLoop\Providers\AbstractProvider
|
||||
{
|
||||
/**
|
||||
* @var \RainLoop\Providers\Domain\DomainInterface
|
||||
*/
|
||||
private $oDriver;
|
||||
|
||||
/**
|
||||
* @var \RainLoop\Plugins\Manager
|
||||
*/
|
||||
private $oPlugins;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $bAdmin;
|
||||
|
||||
/**
|
||||
* @param \RainLoop\Providers\Domain\DomainInterface $oDriver
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(\RainLoop\Providers\Domain\DomainInterface $oDriver,
|
||||
\RainLoop\Plugins\Manager $oPlugins)
|
||||
{
|
||||
$this->oDriver = $oDriver;
|
||||
$this->oPlugins = $oPlugins;
|
||||
$this->bAdmin = $this->oDriver instanceof \RainLoop\Providers\Domain\DomainAdminInterface;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function IsAdmin()
|
||||
{
|
||||
return $this->bAdmin;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sName
|
||||
* @param bool $bFindWithWildCard = false
|
||||
* @param bool $bCheckDisabled = true
|
||||
*
|
||||
* @return \RainLoop\Domain|null
|
||||
*/
|
||||
public function Load($sName, $bFindWithWildCard = false, $bCheckDisabled = true)
|
||||
{
|
||||
$oDomain = $this->oDriver->Load($sName, $bFindWithWildCard, $bCheckDisabled);
|
||||
if ($oDomain instanceof \RainLoop\Domain)
|
||||
{
|
||||
$this->oPlugins->RunHook('filter.domain', array(&$oDomain));
|
||||
}
|
||||
|
||||
return $oDomain;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \RainLoop\Domain $oDomain
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function Save(\RainLoop\Domain $oDomain)
|
||||
{
|
||||
return $this->bAdmin ? $this->oDriver->Save($oDomain) : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sName
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function Delete($sName)
|
||||
{
|
||||
return $this->bAdmin ? $this->oDriver->Delete($sName) : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sName
|
||||
* @param bool $bDisabled
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function Disable($sName, $bDisabled)
|
||||
{
|
||||
return $this->bAdmin ? $this->oDriver->Disable($sName, $bDisabled) : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $iOffset = 0
|
||||
* @param int $iLimit = 20
|
||||
* @param string $sSearch = ''
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function GetList($iOffset = 0, $iLimit = 20, $sSearch = '')
|
||||
{
|
||||
return $this->bAdmin ? $this->oDriver->GetList($iOffset, $iLimit, $sSearch) : array();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sSearch = ''
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function Count($sSearch = '')
|
||||
{
|
||||
return $this->oDriver->Count($sSearch);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \RainLoop\Actions $oActions
|
||||
* @param string $sNameForTest = ''
|
||||
*
|
||||
* @return \RainLoop\Domain | null
|
||||
*/
|
||||
public function LoadOrCreateNewFromAction(\RainLoop\Actions $oActions, $sNameForTest = '')
|
||||
{
|
||||
$oDomain = null;
|
||||
|
||||
if ($this->bAdmin)
|
||||
{
|
||||
$bCreate = '1' === (string) $oActions->GetActionParam('Create', '0');
|
||||
$sName = (string) $oActions->GetActionParam('Name', '');
|
||||
$sIncHost = (string) $oActions->GetActionParam('IncHost', '');
|
||||
$iIncPort = (int) $oActions->GetActionParam('IncPort', 143);
|
||||
$iIncSecure = (int) $oActions->GetActionParam('IncSecure', \MailSo\Net\Enumerations\ConnectionSecurityType::NONE);
|
||||
$bIncVerifySsl = '1' === (string) $oActions->GetActionParam('IncVerifySsl', '0');
|
||||
$bIncShortLogin = '1' === (string) $oActions->GetActionParam('IncShortLogin', '0');
|
||||
$sOutHost = (string) $oActions->GetActionParam('OutHost', '');
|
||||
$iOutPort = (int) $oActions->GetActionParam('OutPort', 25);
|
||||
$iOutSecure = (int) $oActions->GetActionParam('OutSecure', \MailSo\Net\Enumerations\ConnectionSecurityType::NONE);
|
||||
$bOutVerifySsl = '1' === (string) $oActions->GetActionParam('OutVerifySsl', '0');
|
||||
$bOutShortLogin = '1' === (string) $oActions->GetActionParam('OutShortLogin', '0');
|
||||
$bOutAuth = '1' === (string) $oActions->GetActionParam('OutAuth', '1');
|
||||
$sWhiteList = (string) $oActions->GetActionParam('WhiteList', '');
|
||||
|
||||
if (0 < \strlen($sName) && 0 < strlen($sNameForTest) && false === \strpos($sName, '*'))
|
||||
{
|
||||
$sNameForTest = '';
|
||||
}
|
||||
|
||||
if (0 < strlen($sName) || 0 < strlen($sNameForTest))
|
||||
{
|
||||
$oDomain = 0 < strlen($sNameForTest) ? null : $this->Load($sName);
|
||||
if ($oDomain instanceof \RainLoop\Domain)
|
||||
{
|
||||
if ($bCreate)
|
||||
{
|
||||
throw new \RainLoop\Exceptions\ClientException(\RainLoop\Notifications::DomainAlreadyExists);
|
||||
}
|
||||
else
|
||||
{
|
||||
$oDomain->UpdateInstance(
|
||||
$sIncHost, $iIncPort, $iIncSecure, $bIncVerifySsl, $bIncShortLogin,
|
||||
$sOutHost, $iOutPort, $iOutSecure, $bOutVerifySsl, $bOutShortLogin, $bOutAuth,
|
||||
$sWhiteList);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$oDomain = \RainLoop\Domain::NewInstance(0 < strlen($sNameForTest) ? $sNameForTest : $sName,
|
||||
$sIncHost, $iIncPort, $iIncSecure, $bIncVerifySsl, $bIncShortLogin,
|
||||
$sOutHost, $iOutPort, $iOutSecure, $bOutVerifySsl, $bOutShortLogin, $bOutAuth,
|
||||
$sWhiteList);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $oDomain;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function IsActive()
|
||||
{
|
||||
return $this->oDriver instanceof \RainLoop\Providers\Domain\DomainInterface;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,332 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace RainLoop\Providers\Domain;
|
||||
|
||||
class DefaultDomain implements \RainLoop\Providers\Domain\DomainAdminInterface
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $sDomainPath;
|
||||
|
||||
/**
|
||||
* @var \MailSo\Cache\CacheClient
|
||||
*/
|
||||
protected $oCacher;
|
||||
|
||||
/**
|
||||
* @param string $sDomainPath
|
||||
* @param \MailSo\Cache\CacheClient $oCacher = null
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($sDomainPath, $oCacher = null)
|
||||
{
|
||||
$this->sDomainPath = \rtrim(\trim($sDomainPath), '\\/');
|
||||
$this->oCacher = $oCacher;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sName
|
||||
* @param bool $bBack = false
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function codeFileName($sName, $bBack = false)
|
||||
{
|
||||
if ($bBack && 'default' === $sName)
|
||||
{
|
||||
return '*';
|
||||
}
|
||||
else if (!$bBack && '*' === $sName)
|
||||
{
|
||||
return 'default';
|
||||
}
|
||||
|
||||
if ($bBack)
|
||||
{
|
||||
$sName = \MailSo\Base\Utils::IdnToUtf8($sName, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
$sName = \MailSo\Base\Utils::IdnToAscii($sName, true);
|
||||
}
|
||||
|
||||
return $bBack ? \str_replace('_wildcard_', '*', $sName) : \str_replace('*', '_wildcard_', $sName);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sName
|
||||
* @param bool $bDisable
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function Disable($sName, $bDisable)
|
||||
{
|
||||
$sName = \MailSo\Base\Utils::IdnToAscii($sName, true);
|
||||
|
||||
$sFile = '';
|
||||
if (\file_exists($this->sDomainPath.'/disabled'))
|
||||
{
|
||||
$sFile = @\file_get_contents($this->sDomainPath.'/disabled');
|
||||
}
|
||||
|
||||
$aResult = array();
|
||||
$aNames = \explode(',', $sFile);
|
||||
if ($bDisable)
|
||||
{
|
||||
\array_push($aNames, $sName);
|
||||
$aResult = $aNames;
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach ($aNames as $sItem)
|
||||
{
|
||||
if ($sName !== $sItem)
|
||||
{
|
||||
$aResult[] = $sItem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$aResult = \array_unique($aResult);
|
||||
return false !== \file_put_contents($this->sDomainPath.'/disabled', \trim(\implode(',', $aResult), ', '));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
private function wildcardDomainsCacheKey()
|
||||
{
|
||||
return '/WildCard/DomainCache/'.\md5(APP_VERSION.APP_PRIVATE_DATA_NAME).'/';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
private function getWildcardDomainsLine()
|
||||
{
|
||||
if ($this->oCacher)
|
||||
{
|
||||
$sResult = $this->oCacher->Get($this->wildcardDomainsCacheKey());
|
||||
if (0 < \strlen($sResult))
|
||||
{
|
||||
return $sResult;
|
||||
}
|
||||
}
|
||||
|
||||
$sResult = '';
|
||||
$aNames = array();
|
||||
|
||||
$aList = \glob($this->sDomainPath.'/*.ini');
|
||||
foreach ($aList as $sFile)
|
||||
{
|
||||
$sName = \substr(\basename($sFile), 0, -4);
|
||||
if ('default' === $sName || false !== \strpos($sName, '_wildcard_'))
|
||||
{
|
||||
$aNames[] = $this->codeFileName($sName, true);
|
||||
}
|
||||
}
|
||||
|
||||
if (0 < \count($aNames))
|
||||
{
|
||||
\rsort($aNames, SORT_STRING);
|
||||
$sResult = \implode(' ', $aNames);
|
||||
}
|
||||
|
||||
if ($this->oCacher)
|
||||
{
|
||||
$this->oCacher->Set($this->wildcardDomainsCacheKey(), $sResult);
|
||||
}
|
||||
|
||||
return $sResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sName
|
||||
* @param bool $bFindWithWildCard = false
|
||||
* @param bool $bCheckDisabled = true
|
||||
*
|
||||
* @return \RainLoop\Domain|null
|
||||
*/
|
||||
public function Load($sName, $bFindWithWildCard = false, $bCheckDisabled = true)
|
||||
{
|
||||
$mResult = null;
|
||||
|
||||
$sDisabled = '';
|
||||
$sFoundedValue = '';
|
||||
|
||||
$sRealFileName = $this->codeFileName($sName);
|
||||
|
||||
if (\file_exists($this->sDomainPath.'/disabled'))
|
||||
{
|
||||
$sDisabled = @\file_get_contents($this->sDomainPath.'/disabled');
|
||||
}
|
||||
|
||||
if (\file_exists($this->sDomainPath.'/'.$sRealFileName.'.ini') &&
|
||||
(!$bCheckDisabled || 0 === \strlen($sDisabled) || false === \strpos(','.$sDisabled.',', ','.\MailSo\Base\Utils::IdnToAscii($sName, true).',')))
|
||||
{
|
||||
$aDomain = @\parse_ini_file($this->sDomainPath.'/'.$sRealFileName.'.ini');
|
||||
// fix misspellings (#119)
|
||||
if (\is_array($aDomain))
|
||||
{
|
||||
if (isset($aDomain['smpt_host']))
|
||||
{
|
||||
$aDomain['smtp_host'] = $aDomain['smpt_host'];
|
||||
}
|
||||
|
||||
if (isset($aDomain['smpt_port']))
|
||||
{
|
||||
$aDomain['smtp_port'] = $aDomain['smpt_port'];
|
||||
}
|
||||
|
||||
if (isset($aDomain['smpt_secure']))
|
||||
{
|
||||
$aDomain['smtp_secure'] = $aDomain['smpt_secure'];
|
||||
}
|
||||
|
||||
if (isset($aDomain['smpt_auth']))
|
||||
{
|
||||
$aDomain['smtp_auth'] = $aDomain['smpt_auth'];
|
||||
}
|
||||
}
|
||||
//---
|
||||
|
||||
$mResult = \RainLoop\Domain::NewInstanceFromDomainConfigArray($sName, $aDomain);
|
||||
}
|
||||
else if ($bFindWithWildCard)
|
||||
{
|
||||
$sNames = $this->getWildcardDomainsLine();
|
||||
if (0 < \strlen($sNames))
|
||||
{
|
||||
if (\RainLoop\Plugins\Helper::ValidateWildcardValues(
|
||||
\MailSo\Base\Utils::IdnToUtf8($sName, true), $sNames, $sFoundedValue) && 0 < \strlen($sFoundedValue))
|
||||
{
|
||||
if (!$bCheckDisabled || 0 === \strlen($sDisabled) || false === \strpos(','.$sDisabled.',', ','.$sFoundedValue.','))
|
||||
{
|
||||
$mResult = $this->Load($sFoundedValue, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $mResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \RainLoop\Domain $oDomain
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function Save(\RainLoop\Domain $oDomain)
|
||||
{
|
||||
$sRealFileName = $this->codeFileName($oDomain->Name());
|
||||
|
||||
if ($this->oCacher)
|
||||
{
|
||||
$this->oCacher->Delete($this->wildcardDomainsCacheKey());
|
||||
}
|
||||
|
||||
$mResult = \file_put_contents($this->sDomainPath.'/'.$sRealFileName.'.ini', $oDomain->ToIniString());
|
||||
return \is_int($mResult) && 0 < $mResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sName
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function Delete($sName)
|
||||
{
|
||||
$bResult = true;
|
||||
$sRealFileName = $this->codeFileName($sName);
|
||||
|
||||
if (0 < \strlen($sName) && \file_exists($this->sDomainPath.'/'.$sRealFileName.'.ini'))
|
||||
{
|
||||
$bResult = \unlink($this->sDomainPath.'/'.$sRealFileName.'.ini');
|
||||
}
|
||||
|
||||
if ($bResult)
|
||||
{
|
||||
$this->Disable($sName, false);
|
||||
}
|
||||
|
||||
if ($this->oCacher)
|
||||
{
|
||||
$this->oCacher->Delete($this->wildcardDomainsCacheKey());
|
||||
}
|
||||
|
||||
return $bResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $iOffset
|
||||
* @param int $iLimit = 20
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function GetList($iOffset, $iLimit = 20)
|
||||
{
|
||||
$aResult = array();
|
||||
$aWildCards = array();
|
||||
$aList = \glob($this->sDomainPath.'/*.ini');
|
||||
|
||||
foreach ($aList as $sFile)
|
||||
{
|
||||
$sName = \substr(\basename($sFile), 0, -4);
|
||||
$sName = $this->codeFileName($sName, true);
|
||||
|
||||
if (false === \strpos($sName, '*'))
|
||||
{
|
||||
$aResult[] = $sName;
|
||||
}
|
||||
else
|
||||
{
|
||||
$aWildCards[] = $sName;
|
||||
}
|
||||
}
|
||||
|
||||
\sort($aResult, SORT_STRING);
|
||||
\rsort($aWildCards, SORT_STRING);
|
||||
|
||||
$aResult = \array_merge($aResult, $aWildCards);
|
||||
|
||||
$iOffset = (0 > $iOffset) ? 0 : $iOffset;
|
||||
$iLimit = (0 > $iLimit) ? 0 : ((999 < $iLimit) ? 999 : $iLimit);
|
||||
|
||||
$aResult = \array_slice($aResult, $iOffset, $iLimit);
|
||||
|
||||
$aDisabledNames = array();
|
||||
if (0 < \count($aResult) && \file_exists($this->sDomainPath.'/disabled'))
|
||||
{
|
||||
$sDisabled = @\file_get_contents($this->sDomainPath.'/disabled');
|
||||
if (false !== $sDisabled && 0 < strlen($sDisabled))
|
||||
{
|
||||
$aDisabledNames = \explode(',', $sDisabled);
|
||||
$aDisabledNames = \array_unique($aDisabledNames);
|
||||
foreach ($aDisabledNames as $iIndex => $sValue)
|
||||
{
|
||||
$aDisabledNames[$iIndex] = \MailSo\Base\Utils::IdnToUtf8($sValue, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$aReturn = array();
|
||||
foreach ($aResult as $sName)
|
||||
{
|
||||
$aReturn[$sName] = !\in_array($sName, $aDisabledNames);
|
||||
}
|
||||
|
||||
return $aReturn;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sSearch = ''
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function Count()
|
||||
{
|
||||
return \count($this->GetList(0, 999));
|
||||
}
|
||||
}
|
||||
|
|
@ -1,51 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace RainLoop\Providers\Domain;
|
||||
|
||||
interface DomainAdminInterface extends DomainInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* @param string $sName
|
||||
* @param bool $bDisable
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function Disable($sName, $bDisable);
|
||||
|
||||
/**
|
||||
* @param string $sName
|
||||
* @param bool $bFindWithWildCard = false
|
||||
* @param bool $bCheckDisabled = true
|
||||
*
|
||||
* @return \RainLoop\Domain|null
|
||||
*/
|
||||
public function Load($sName, $bFindWithWildCard = false, $bCheckDisabled = true);
|
||||
|
||||
/**
|
||||
* @param \RainLoop\Domain $oDomain
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function Save(\RainLoop\Domain $oDomain);
|
||||
|
||||
/**
|
||||
* @param string $sName
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function Delete($sName);
|
||||
|
||||
/**
|
||||
* @param int $iOffset
|
||||
* @param int $iLimit = 20
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function GetList($iOffset, $iLimit = 20);
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function Count();
|
||||
}
|
||||
|
|
@ -1,7 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace RainLoop\Providers\Domain;
|
||||
|
||||
interface DomainInterface
|
||||
{
|
||||
}
|
||||
|
|
@ -1,117 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace RainLoop\Providers;
|
||||
|
||||
class Files extends \RainLoop\Providers\AbstractProvider
|
||||
{
|
||||
/**
|
||||
* @var \RainLoop\Providers\Files\FilesInterface
|
||||
*/
|
||||
private $oDriver;
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(\RainLoop\Providers\Files\FilesInterface $oDriver)
|
||||
{
|
||||
$this->oDriver = $oDriver;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \RainLoop\Account $oAccount
|
||||
* @param string $sKey
|
||||
* @param resource $rSource
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function PutFile($oAccount, $sKey, $rSource)
|
||||
{
|
||||
return $this->oDriver->PutFile($oAccount, $sKey, $rSource);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \RainLoop\Account $oAccount
|
||||
* @param string $sKey
|
||||
* @param string $sSource
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function MoveUploadedFile($oAccount, $sKey, $sSource)
|
||||
{
|
||||
return $this->oDriver->MoveUploadedFile($oAccount, $sKey, $sSource);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \RainLoop\Account $oAccount
|
||||
* @param string $sKey
|
||||
* @param string $sOpenMode = 'rb'
|
||||
*
|
||||
* @return resource|bool
|
||||
*/
|
||||
public function GetFile($oAccount, $sKey, $sOpenMode = 'rb')
|
||||
{
|
||||
return $this->oDriver->GetFile($oAccount, $sKey, $sOpenMode);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \RainLoop\Account $oAccount
|
||||
* @param string $sKey
|
||||
*
|
||||
* @return string | bool
|
||||
*/
|
||||
public function GetFileName($oAccount, $sKey)
|
||||
{
|
||||
return $this->oDriver->GetFileName($oAccount, $sKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \RainLoop\Account $oAccount
|
||||
* @param string $sKey
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function Clear($oAccount, $sKey)
|
||||
{
|
||||
return $this->oDriver->Clear($oAccount, $sKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \RainLoop\Account $oAccount
|
||||
* @param string $sKey
|
||||
*
|
||||
* @return int|bool
|
||||
*/
|
||||
public function FileSize($oAccount, $sKey)
|
||||
{
|
||||
return $this->oDriver->FileSize($oAccount, $sKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \RainLoop\Account $oAccount
|
||||
* @param string $sKey
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function FileExists($oAccount, $sKey)
|
||||
{
|
||||
return $this->oDriver->FileExists($oAccount, $sKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $iTimeToClearInHours = 24
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function GC($iTimeToClearInHours = 24)
|
||||
{
|
||||
return $this->oDriver ? $this->oDriver->GC($iTimeToClearInHours) : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function IsActive()
|
||||
{
|
||||
return $this->oDriver instanceof \RainLoop\Providers\Files\FilesInterface;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,186 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace RainLoop\Providers\Files;
|
||||
|
||||
class DefaultStorage implements \RainLoop\Providers\Files\FilesInterface
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sDataPath;
|
||||
|
||||
/**
|
||||
* @param string $sStoragePath
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($sStoragePath)
|
||||
{
|
||||
$this->sDataPath = \rtrim(\trim($sStoragePath), '\\/');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \RainLoop\Account $oAccount
|
||||
* @param string $sKey
|
||||
* @param resource $rSource
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function PutFile($oAccount, $sKey, $rSource)
|
||||
{
|
||||
$bResult = false;
|
||||
if ($rSource)
|
||||
{
|
||||
$rOpenOutput = @\fopen($this->generateFileName($oAccount, $sKey, true), 'w+b');
|
||||
if ($rOpenOutput)
|
||||
{
|
||||
$bResult = (false !== \MailSo\Base\Utils::MultipleStreamWriter($rSource, array($rOpenOutput)));
|
||||
@\fclose($rOpenOutput);
|
||||
}
|
||||
}
|
||||
return $bResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \RainLoop\Account $oAccount
|
||||
* @param string $sKey
|
||||
* @param string $sSource
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function MoveUploadedFile($oAccount, $sKey, $sSource)
|
||||
{
|
||||
return @\move_uploaded_file($sSource,
|
||||
$this->generateFileName($oAccount, $sKey, true));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \RainLoop\Account $oAccount
|
||||
* @param string $sKey
|
||||
* @param string $sOpenMode = 'rb'
|
||||
*
|
||||
* @return resource|bool
|
||||
*/
|
||||
public function GetFile($oAccount, $sKey, $sOpenMode = 'rb')
|
||||
{
|
||||
$mResult = false;
|
||||
$bCreate = !!\preg_match('/[wac]/', $sOpenMode);
|
||||
|
||||
$sFileName = $this->generateFileName($oAccount, $sKey, $bCreate);
|
||||
if ($bCreate || \file_exists($sFileName))
|
||||
{
|
||||
$mResult = @\fopen($sFileName, $sOpenMode);
|
||||
}
|
||||
|
||||
return $mResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \RainLoop\Account $oAccount
|
||||
* @param string $sKey
|
||||
*
|
||||
* @return string|bool
|
||||
*/
|
||||
public function GetFileName($oAccount, $sKey)
|
||||
{
|
||||
$mResult = false;
|
||||
$sFileName = $this->generateFileName($oAccount, $sKey);
|
||||
if (\file_exists($sFileName))
|
||||
{
|
||||
$mResult = $sFileName;
|
||||
}
|
||||
|
||||
return $mResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \RainLoop\Account $oAccount
|
||||
* @param string $sKey
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function Clear($oAccount, $sKey)
|
||||
{
|
||||
$mResult = true;
|
||||
$sFileName = $this->generateFileName($oAccount, $sKey);
|
||||
if (\file_exists($sFileName))
|
||||
{
|
||||
$mResult = @\unlink($sFileName);
|
||||
}
|
||||
|
||||
return $mResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \RainLoop\Account $oAccount
|
||||
* @param string $sKey
|
||||
*
|
||||
* @return int|bool
|
||||
*/
|
||||
public function FileSize($oAccount, $sKey)
|
||||
{
|
||||
$mResult = false;
|
||||
$sFileName = $this->generateFileName($oAccount, $sKey);
|
||||
if (\file_exists($sFileName))
|
||||
{
|
||||
$mResult = \filesize($sFileName);
|
||||
}
|
||||
|
||||
return $mResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \RainLoop\Account $oAccount
|
||||
* @param string $sKey
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function FileExists($oAccount, $sKey)
|
||||
{
|
||||
return @\file_exists($this->generateFileName($oAccount, $sKey));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $iTimeToClearInHours = 24
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function GC($iTimeToClearInHours = 24)
|
||||
{
|
||||
if (0 < $iTimeToClearInHours)
|
||||
{
|
||||
\MailSo\Base\Utils::RecTimeDirRemove($this->sDataPath, 60 * 60 * $iTimeToClearInHours, \time());
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \RainLoop\Account $oAccount
|
||||
* @param string $sKey
|
||||
* @param bool $bMkDir = false
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function generateFileName($oAccount, $sKey, $bMkDir = false)
|
||||
{
|
||||
$sEmail = \preg_replace('/[^a-z0-9\-\.@]+/', '_',
|
||||
('' === $oAccount->ParentEmail() ? '' : $oAccount->ParentEmail().'/').$oAccount->Email());
|
||||
|
||||
$sKeyPath = \sha1($sKey);
|
||||
$sKeyPath = \substr($sKeyPath, 0, 2).'/'.\substr($sKeyPath, 2, 2).'/'.$sKeyPath;
|
||||
|
||||
$sFilePath = $this->sDataPath.'/'.rtrim(substr($sEmail, 0, 2), '@').'/'.$sEmail.'/'.$sKeyPath;
|
||||
|
||||
if ($bMkDir && !empty($sFilePath) && !@\is_dir(\dirname($sFilePath)))
|
||||
{
|
||||
if (!@\mkdir(\dirname($sFilePath), 0755, true))
|
||||
{
|
||||
throw new \RainLoop\Exceptions\Exception('Can\'t make storage directory "'.$sFilePath.'"');
|
||||
}
|
||||
}
|
||||
|
||||
return $sFilePath;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,72 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace RainLoop\Providers\Files;
|
||||
|
||||
interface FilesInterface
|
||||
{
|
||||
/**
|
||||
* @param \RainLoop\Account $oAccount
|
||||
* @param string $sKey
|
||||
* @param resource $rSource
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function PutFile($oAccount, $sKey, $rSource);
|
||||
|
||||
/**
|
||||
* @param CAccount $oAccount
|
||||
* @param string $sKey
|
||||
* @param string $sSource
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function MoveUploadedFile($oAccount, $sKey, $sSource);
|
||||
|
||||
/**
|
||||
* @param \RainLoop\Account $oAccount
|
||||
* @param string $sKey
|
||||
* @param string $sOpenMode = 'rb'
|
||||
*
|
||||
* @return resource|bool
|
||||
*/
|
||||
public function GetFile($oAccount, $sKey, $sOpenMode = 'rb');
|
||||
|
||||
/**
|
||||
* @param \RainLoop\Account $oAccount
|
||||
* @param string $sKey
|
||||
*
|
||||
* @return string|bool
|
||||
*/
|
||||
public function GetFileName($oAccount, $sKey);
|
||||
|
||||
/**
|
||||
* @param \RainLoop\Account $oAccount
|
||||
* @param string $sKey
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function Clear($oAccount, $sKey);
|
||||
|
||||
/**
|
||||
* @param \RainLoop\Account $oAccount
|
||||
* @param string $sKey
|
||||
*
|
||||
* @return int | bool
|
||||
*/
|
||||
public function FileSize($oAccount, $sKey);
|
||||
|
||||
/**
|
||||
* @param \RainLoop\Account $oAccount
|
||||
* @param string $sKey
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function FileExists($oAccount, $sKey);
|
||||
|
||||
/**
|
||||
* @param int $iTimeToClearInHours = 24
|
||||
|
||||
* @return bool
|
||||
*/
|
||||
public function GC($iTimeToClearInHours = 24);
|
||||
}
|
||||
|
|
@ -1,62 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace RainLoop\Providers;
|
||||
|
||||
class Settings extends \RainLoop\Providers\AbstractProvider
|
||||
{
|
||||
/**
|
||||
* @var \RainLoop\Providers\Settings\SettingsInterface
|
||||
*/
|
||||
private $oDriver;
|
||||
|
||||
/**
|
||||
* @param \RainLoop\Providers\Settings\SettingsInterface $oDriver
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(\RainLoop\Providers\Settings\SettingsInterface $oDriver)
|
||||
{
|
||||
$this->oDriver = $oDriver;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \RainLoop\Account $oAccount
|
||||
*
|
||||
* @return \RainLoop\Settings
|
||||
*/
|
||||
public function Load(\RainLoop\Account $oAccount)
|
||||
{
|
||||
$oSettings = new \RainLoop\Settings();
|
||||
$oSettings->InitData($this->oDriver->Load($oAccount));
|
||||
return $oSettings;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \RainLoop\Account $oAccount
|
||||
* @param \RainLoop\Settings $oSettings
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function Save(\RainLoop\Account $oAccount, \RainLoop\Settings $oSettings)
|
||||
{
|
||||
return $this->oDriver->Save($oAccount, $oSettings->DataAsArray());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sEmail
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function ClearByEmail($sEmail)
|
||||
{
|
||||
return $this->oDriver->ClearByEmail($sEmail);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function IsActive()
|
||||
{
|
||||
return $this->oDriver instanceof \RainLoop\Providers\Settings\SettingsInterface;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,71 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace RainLoop\Providers\Settings;
|
||||
|
||||
class DefaultSettings implements \RainLoop\Providers\Settings\SettingsInterface
|
||||
{
|
||||
const FILE_NAME = 'settings';
|
||||
|
||||
/**
|
||||
* @var \RainLoop\Providers\Storage
|
||||
*/
|
||||
private $oStorageProvider;
|
||||
|
||||
/**
|
||||
* @param \RainLoop\Providers\Storage $oStorageProvider
|
||||
*/
|
||||
public function __construct(\RainLoop\Providers\Storage $oStorageProvider)
|
||||
{
|
||||
$this->oStorageProvider = $oStorageProvider;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \RainLoop\Account $oAccount
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function Load(\RainLoop\Account $oAccount)
|
||||
{
|
||||
$sValue = $this->oStorageProvider->Get($oAccount,
|
||||
\RainLoop\Providers\Storage\Enumerations\StorageType::CONFIG,
|
||||
\RainLoop\Providers\Settings\DefaultSettings::FILE_NAME);
|
||||
|
||||
$aSettings = array();
|
||||
if (\is_string($sValue))
|
||||
{
|
||||
$aData = \json_decode($sValue, true);
|
||||
if (\is_array($aData))
|
||||
{
|
||||
$aSettings = $aData;
|
||||
}
|
||||
}
|
||||
|
||||
return $aSettings;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \RainLoop\Account $oAccount
|
||||
* @param array $aSettings
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function Save(\RainLoop\Account $oAccount, array $aSettings)
|
||||
{
|
||||
return $this->oStorageProvider->Put($oAccount,
|
||||
\RainLoop\Providers\Storage\Enumerations\StorageType::CONFIG,
|
||||
\RainLoop\Providers\Settings\DefaultSettings::FILE_NAME,
|
||||
\json_encode($aSettings));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sEmail
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function ClearByEmail($sEmail)
|
||||
{
|
||||
return $this->oStorageProvider->Clear($sEmail,
|
||||
\RainLoop\Providers\Storage\Enumerations\StorageType::CONFIG,
|
||||
\RainLoop\Providers\Settings\DefaultSettings::FILE_NAME);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,28 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace RainLoop\Providers\Settings;
|
||||
|
||||
interface SettingsInterface
|
||||
{
|
||||
/**
|
||||
* @param \RainLoop\Account $oAccount
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function Load(\RainLoop\Account $oAccount);
|
||||
|
||||
/**
|
||||
* @param \RainLoop\Account $oAccount
|
||||
* @param array $aSettings
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function Save(\RainLoop\Account $oAccount, array $aSettings);
|
||||
|
||||
/**
|
||||
* @param string $sEmail
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function ClearByEmail($sEmail);
|
||||
}
|
||||
|
|
@ -1,97 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace RainLoop\Providers;
|
||||
|
||||
class Storage extends \RainLoop\Providers\AbstractProvider
|
||||
{
|
||||
/**
|
||||
* @var \RainLoop\Providers\Storage\StorageInterface
|
||||
*/
|
||||
private $oDriver;
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(\RainLoop\Providers\Storage\StorageInterface $oDriver)
|
||||
{
|
||||
$this->oDriver = $oDriver;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \RainLoop\Account|string|null $oAccount
|
||||
* @param int $iStorageType
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function verifyAccount($oAccount, $iStorageType)
|
||||
{
|
||||
if (\RainLoop\Providers\Storage\Enumerations\StorageType::NOBODY !== $iStorageType &&
|
||||
!($oAccount instanceof \RainLoop\Account || \is_string($oAccount)))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \RainLoop\Account|string|null $oAccount
|
||||
* @param int $iStorageType
|
||||
* @param string $sKey
|
||||
* @param string $sValue
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function Put($oAccount, $iStorageType, $sKey, $sValue)
|
||||
{
|
||||
if (!$this->verifyAccount($oAccount, $iStorageType))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return $this->oDriver->Put($oAccount, $iStorageType, $sKey, $sValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \RainLoop\Account|string|null $oAccount
|
||||
* @param int $iStorageType
|
||||
* @param string $sKey
|
||||
* @param mixed $mDefault = false
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function Get($oAccount, $iStorageType, $sKey, $mDefault = false)
|
||||
{
|
||||
if (!$this->verifyAccount($oAccount, $iStorageType))
|
||||
{
|
||||
return $mDefault;
|
||||
}
|
||||
|
||||
return $this->oDriver->Get($oAccount, $iStorageType, $sKey, $mDefault);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \RainLoop\Account|string|null $oAccount
|
||||
* @param int $iStorageType
|
||||
* @param string $sKey
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function Clear($oAccount, $iStorageType, $sKey)
|
||||
{
|
||||
if (!$this->verifyAccount($oAccount, $iStorageType))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return $this->oDriver->Clear($oAccount, $iStorageType, $sKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function IsActive()
|
||||
{
|
||||
return $this->oDriver instanceof \RainLoop\Providers\Storage\StorageInterface;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,134 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace RainLoop\Providers\Storage;
|
||||
|
||||
class DefaultStorage implements \RainLoop\Providers\Storage\StorageInterface
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sDataPath;
|
||||
|
||||
/**
|
||||
* @param string $sStoragePath
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($sStoragePath)
|
||||
{
|
||||
$this->sDataPath = \rtrim(\trim($sStoragePath), '\\/');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \RainLoop\Account|string|null $oAccount
|
||||
* @param int $iStorageType
|
||||
* @param string $sKey
|
||||
* @param string $sValue
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function Put($oAccount, $iStorageType, $sKey, $sValue)
|
||||
{
|
||||
return false !== @\file_put_contents(
|
||||
$this->generateFileName($oAccount, $iStorageType, $sKey, true), $sValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \RainLoop\Account|string|null $oAccount
|
||||
* @param int $iStorageType
|
||||
* @param string $sKey
|
||||
* @param mixed $mDefault = false
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function Get($oAccount, $iStorageType, $sKey, $mDefault = false)
|
||||
{
|
||||
$mValue = false;
|
||||
$sFileName = $this->generateFileName($oAccount, $iStorageType, $sKey);
|
||||
if (\file_exists($sFileName))
|
||||
{
|
||||
$mValue = \file_get_contents($sFileName);
|
||||
}
|
||||
|
||||
return false === $mValue ? $mDefault : $mValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \RainLoop\Account|string|null $oAccount
|
||||
* @param int $iStorageType
|
||||
* @param string $sKey
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function Clear($oAccount, $iStorageType, $sKey)
|
||||
{
|
||||
$mResult = true;
|
||||
$sFileName = $this->generateFileName($oAccount, $iStorageType, $sKey);
|
||||
if (\file_exists($sFileName))
|
||||
{
|
||||
$mResult = @\unlink($sFileName);
|
||||
}
|
||||
|
||||
return $mResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \RainLoop\Account|string|null $mAccount
|
||||
* @param int $iStorageType
|
||||
* @param string $sKey
|
||||
* @param bool $bMkDir = false
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function generateFileName($mAccount, $iStorageType, $sKey, $bMkDir = false)
|
||||
{
|
||||
if (null === $mAccount)
|
||||
{
|
||||
$iStorageType = \RainLoop\Providers\Storage\Enumerations\StorageType::NOBODY;
|
||||
}
|
||||
|
||||
$sEmail = $mAccount instanceof \RainLoop\Account ? \preg_replace('/[^a-z0-9\-\.@]+/', '_',
|
||||
('' === $mAccount->ParentEmail() ? '' : $mAccount->ParentEmail().'/').$mAccount->Email()) : '';
|
||||
|
||||
if (\is_string($mAccount) && empty($sEmail))
|
||||
{
|
||||
$sEmail = \preg_replace('/[^a-z0-9\-\.@]+/', '_', $mAccount);
|
||||
}
|
||||
|
||||
$sTypePath = $sKeyPath = '';
|
||||
switch ($iStorageType)
|
||||
{
|
||||
default:
|
||||
case \RainLoop\Providers\Storage\Enumerations\StorageType::USER:
|
||||
case \RainLoop\Providers\Storage\Enumerations\StorageType::NOBODY:
|
||||
$sTypePath = 'data';
|
||||
$sKeyPath = \md5($sKey);
|
||||
$sKeyPath = \substr($sKeyPath, 0, 2).'/'.$sKeyPath;
|
||||
break;
|
||||
case \RainLoop\Providers\Storage\Enumerations\StorageType::CONFIG:
|
||||
$sTypePath = 'cfg';
|
||||
$sKeyPath = \preg_replace('/[_]+/', '_', \preg_replace('/[^a-zA-Z0-9\/]/', '_', $sKey));
|
||||
break;
|
||||
}
|
||||
|
||||
$sFilePath = '';
|
||||
if (\RainLoop\Providers\Storage\Enumerations\StorageType::NOBODY === $iStorageType)
|
||||
{
|
||||
$sFilePath = $this->sDataPath.'/'.$sTypePath.'/__nobody__/'.$sKeyPath;
|
||||
}
|
||||
else if (!empty($sEmail))
|
||||
{
|
||||
$sFilePath = $this->sDataPath.'/'.$sTypePath.'/'.rtrim(substr($sEmail, 0, 2), '@').'/'.$sEmail.'/'.$sKeyPath;
|
||||
}
|
||||
|
||||
if ($bMkDir && !empty($sFilePath) && !@\is_dir(\dirname($sFilePath)))
|
||||
{
|
||||
if (!@\mkdir(\dirname($sFilePath), 0755, true))
|
||||
{
|
||||
throw new \RainLoop\Exceptions\Exception('Can\'t make storage directory "'.$sFilePath.'"');
|
||||
}
|
||||
}
|
||||
|
||||
return $sFilePath;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,10 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace RainLoop\Providers\Storage\Enumerations;
|
||||
|
||||
class StorageType
|
||||
{
|
||||
const USER = 1;
|
||||
const CONFIG = 2;
|
||||
const NOBODY = 3;
|
||||
}
|
||||
|
|
@ -1,35 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace RainLoop\Providers\Storage;
|
||||
|
||||
interface StorageInterface
|
||||
{
|
||||
/**
|
||||
* @param \RainLoop\Account|null $oAccount
|
||||
* @param int $iStorageType
|
||||
* @param string $sKey
|
||||
* @param string $sValue
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function Put($oAccount, $iStorageType, $sKey, $sValue);
|
||||
|
||||
/**
|
||||
* @param \RainLoop\Account|null $oAccount
|
||||
* @param int $iStorageType
|
||||
* @param string $sKey
|
||||
* @param mixed $mDefault = false
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function Get($oAccount, $iStorageType, $sKey, $mDefault = false);
|
||||
|
||||
/**
|
||||
* @param \RainLoop\Account|null $oAccount
|
||||
* @param int $iStorageType
|
||||
* @param string $sKey
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function Clear($oAccount, $iStorageType, $sKey);
|
||||
}
|
||||
|
|
@ -1,40 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace RainLoop\Providers;
|
||||
|
||||
class Suggestions extends \RainLoop\Providers\AbstractProvider
|
||||
{
|
||||
/**
|
||||
* @var \RainLoop\Providers\Suggestions\SuggestionsInterface
|
||||
*/
|
||||
private $oDriver;
|
||||
|
||||
/**
|
||||
* @param \RainLoop\Providers\Suggestions\SuggestionsInterface|null $oDriver = null
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($oDriver = null)
|
||||
{
|
||||
$this->oDriver = $oDriver;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \RainLoop\Account $oAccount
|
||||
* @param string $sQuery
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function Process(\RainLoop\Account $oAccount, $sQuery)
|
||||
{
|
||||
return $this->oDriver && $this->IsActive() && 0 < \strlen($sQuery) ? $this->oDriver->Process($oAccount, $sQuery) : array();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function IsActive()
|
||||
{
|
||||
return $this->oDriver instanceof \RainLoop\Providers\Suggestions\SuggestionsInterface;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,14 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace RainLoop\Providers\Suggestions;
|
||||
|
||||
interface SuggestionsInterface
|
||||
{
|
||||
/**
|
||||
* @param \RainLoop\Account $oAccount
|
||||
* @param string $sQuery
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function Process(\RainLoop\Account $oAccount, $sQuery);
|
||||
}
|
||||
|
|
@ -1,73 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace RainLoop\Providers;
|
||||
|
||||
class TwoFactorAuth extends \RainLoop\Providers\AbstractProvider
|
||||
{
|
||||
/**
|
||||
* @var \RainLoop\Providers\TwoFactorAuth\TwoFactorAuthInterface
|
||||
*/
|
||||
private $oDriver;
|
||||
|
||||
/**
|
||||
* @param \RainLoop\Providers\TwoFactorAuth\TwoFactorAuthInterface|null $oDriver = null
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($oDriver = null)
|
||||
{
|
||||
$this->oDriver = $oDriver;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function IsActive()
|
||||
{
|
||||
return $this->oDriver instanceof \RainLoop\Providers\TwoFactorAuth\TwoFactorAuthInterface;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sName
|
||||
* @param string $sSecret
|
||||
* @param string $sTitle = ''
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function GetQRCodeGoogleUrl($sName, $sSecret, $sTitle = '')
|
||||
{
|
||||
$sUrl = sprintf('otpauth://%s/%s?secret=%s&issuer=%s', 'totp', urlencode($sName), $sSecret, urlencode($sTitle));
|
||||
return 'https://chart.googleapis.com/chart?chs=200x200&chld=M|0&cht=qr&chl='.\urlencode($sUrl);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function CreateSecret()
|
||||
{
|
||||
$sResult = '';
|
||||
if ($this->IsActive())
|
||||
{
|
||||
$sResult = $this->oDriver->CreateSecret();
|
||||
}
|
||||
|
||||
return $sResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sSecret
|
||||
* @param string $sCode
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function VerifyCode($sSecret, $sCode)
|
||||
{
|
||||
$bResult = false;
|
||||
if ($this->IsActive())
|
||||
{
|
||||
$bResult = $this->oDriver->VerifyCode($sSecret, $sCode);
|
||||
}
|
||||
|
||||
return $bResult;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,24 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace RainLoop\Providers\TwoFactorAuth;
|
||||
|
||||
abstract class AbstractTwoFactorAuth
|
||||
{
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function Label()
|
||||
{
|
||||
return 'Two Factor Authenticator Code';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sSecret
|
||||
* @param string $sCode
|
||||
* @return bool
|
||||
*/
|
||||
public function VerifyCode($sSecret, $sCode)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,33 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace RainLoop\Providers\TwoFactorAuth;
|
||||
|
||||
class GoogleTwoFactorAuth
|
||||
extends \RainLoop\Providers\TwoFactorAuth\AbstractTwoFactorAuth
|
||||
implements \RainLoop\Providers\TwoFactorAuth\TwoFactorAuthInterface
|
||||
{
|
||||
/**
|
||||
* @param string $sSecret
|
||||
* @param string $sCode
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function VerifyCode($sSecret, $sCode)
|
||||
{
|
||||
include_once APP_VERSION_ROOT_PATH.'app/libraries/PHPGangsta/GoogleAuthenticator.php';
|
||||
|
||||
$oGoogleAuthenticator = new \PHPGangsta_GoogleAuthenticator();
|
||||
return $oGoogleAuthenticator->verifyCode($sSecret, $sCode);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function CreateSecret()
|
||||
{
|
||||
include_once APP_VERSION_ROOT_PATH.'app/libraries/PHPGangsta/GoogleAuthenticator.php';
|
||||
|
||||
$oGoogleAuthenticator = new \PHPGangsta_GoogleAuthenticator();
|
||||
return $oGoogleAuthenticator->createSecret();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,14 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace RainLoop\Providers\TwoFactorAuth;
|
||||
|
||||
interface TwoFactorAuthInterface
|
||||
{
|
||||
/**
|
||||
* @param string $sSecret
|
||||
* @param string $sCode
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function VerifyCode($sSecret, $sCode);
|
||||
}
|
||||
|
|
@ -1,261 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace RainLoop;
|
||||
|
||||
class Service
|
||||
{
|
||||
/**
|
||||
* @var \MailSo\Base\Http
|
||||
*/
|
||||
private $oHttp;
|
||||
|
||||
/**
|
||||
* @var \RainLoop\Actions
|
||||
*/
|
||||
private $oActions;
|
||||
|
||||
/**
|
||||
* @var \RainLoop\ServiceActions
|
||||
*/
|
||||
private $oServiceActions;
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
private function __construct()
|
||||
{
|
||||
$this->oHttp = \MailSo\Base\Http::SingletonInstance();
|
||||
$this->oActions = \RainLoop\Api::Actions();
|
||||
|
||||
$this->oServiceActions = new \RainLoop\ServiceActions($this->oHttp, $this->oActions);
|
||||
|
||||
if ($this->oActions->Config()->Get('debug', 'enable', false))
|
||||
{
|
||||
\error_reporting(E_ALL);
|
||||
\ini_set('display_errors', 1);
|
||||
}
|
||||
|
||||
$sServer = \trim($this->oActions->Config()->Get('security', 'custom_server_signature', ''));
|
||||
if (0 < \strlen($sServer))
|
||||
{
|
||||
@\header('Server: '.$sServer, true);
|
||||
}
|
||||
|
||||
$sXFrameOptionsHeader = \trim($this->oActions->Config()->Get('security', 'x_frame_options_header', ''));
|
||||
if (0 < \strlen($sXFrameOptionsHeader))
|
||||
{
|
||||
@\header('X-Frame-Options: '.$sXFrameOptionsHeader, true);
|
||||
}
|
||||
|
||||
if ($this->oActions->Config()->Get('labs', 'force_https', false) && !$this->oHttp->IsSecure())
|
||||
{
|
||||
@\header('Location: https://'.$this->oHttp->GetHost(false, false).$this->oHttp->GetUrl(), true);
|
||||
exit();
|
||||
}
|
||||
|
||||
$this->localHandle();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function RunResult()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @staticvar bool $bOne
|
||||
* @return bool
|
||||
*/
|
||||
public static function Handle()
|
||||
{
|
||||
static $bOne = null;
|
||||
if (null === $bOne)
|
||||
{
|
||||
$oService = null;
|
||||
if (\class_exists('MailSo\Version'))
|
||||
{
|
||||
$oService = new self();
|
||||
}
|
||||
|
||||
$bOne = $oService->RunResult();
|
||||
}
|
||||
|
||||
return $bOne;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \RainLoop\Service
|
||||
*/
|
||||
private function localHandle()
|
||||
{
|
||||
if (!\class_exists('MailSo\Version'))
|
||||
{
|
||||
return $this;
|
||||
}
|
||||
|
||||
$this->oActions->BootStart();
|
||||
|
||||
$sResult = '';
|
||||
$bCached = false;
|
||||
|
||||
$sQuery = $this->oActions->ParseQueryAuthString();
|
||||
|
||||
$this->oActions->Plugins()->RunHook('filter.http-query', array(&$sQuery));
|
||||
$aPaths = \explode('/', $sQuery);
|
||||
$this->oActions->Plugins()->RunHook('filter.http-paths', array(&$aPaths));
|
||||
|
||||
$bAdmin = false;
|
||||
$sAdminPanelHost = $this->oActions->Config()->Get('security', 'admin_panel_host', '');
|
||||
if (empty($sAdminPanelHost))
|
||||
{
|
||||
$bAdmin = !empty($aPaths[0]) && \in_array(\strtolower($aPaths[0]), array('admin', 'cp'));
|
||||
}
|
||||
else if (empty($aPaths[0]) &&
|
||||
\MailSo\Base\Utils::StrToLowerIfAscii($sAdminPanelHost) === \MailSo\Base\Utils::StrToLowerIfAscii($this->oHttp->GetHost()))
|
||||
{
|
||||
$bAdmin = true;
|
||||
}
|
||||
|
||||
if ($this->oHttp->IsPost())
|
||||
{
|
||||
$this->oHttp->ServerNoCache();
|
||||
}
|
||||
|
||||
if ($bAdmin && !$this->oActions->Config()->Get('security', 'allow_admin_panel', true))
|
||||
{
|
||||
echo $this->oActions->ErrorTemplates('Access Denied.',
|
||||
'Access to the RainLoop Webmail Admin Panel is not allowed!', true);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
$bIndex = true;
|
||||
if (0 < \count($aPaths) && !empty($aPaths[0]) && !$bAdmin && 'index' !== $aPaths[0])
|
||||
{
|
||||
$bIndex = false;
|
||||
$sMethodName = 'Service'.$aPaths[0];
|
||||
if (\method_exists($this->oServiceActions, $sMethodName) &&
|
||||
\is_callable(array($this->oServiceActions, $sMethodName)))
|
||||
{
|
||||
$this->oServiceActions->SetQuery($sQuery)->SetPaths($aPaths);
|
||||
$sResult = \call_user_func(array($this->oServiceActions, $sMethodName));
|
||||
}
|
||||
else if (!$this->oActions->Plugins()->RunAdditionalPart($aPaths[0], $aPaths))
|
||||
{
|
||||
$bIndex = true;
|
||||
}
|
||||
}
|
||||
|
||||
if ($bIndex)
|
||||
{
|
||||
@header('Content-Type: text/html; charset=utf-8');
|
||||
$this->oHttp->ServerNoCache();
|
||||
|
||||
$aTemplateParameters = $this->indexTemplateParameters($bAdmin);
|
||||
|
||||
$sCacheFileName = '';
|
||||
if ($this->oActions->Config()->Get('labs', 'cache_system_data', true))
|
||||
{
|
||||
$sCacheFileName = 'TMPL:'.$aTemplateParameters['{{BaseHash}}'];
|
||||
$sResult = $this->oActions->Cacher()->Get($sCacheFileName);
|
||||
}
|
||||
|
||||
if (0 === \strlen($sResult))
|
||||
{
|
||||
$sResult = \strtr(\file_get_contents(APP_VERSION_ROOT_PATH.'app/templates/Index.html'), $aTemplateParameters);
|
||||
|
||||
$sResult = \RainLoop\Utils::ClearHtmlOutput($sResult);
|
||||
if (0 < \strlen($sCacheFileName))
|
||||
{
|
||||
$this->oActions->Cacher()->Set($sCacheFileName, $sResult);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$bCached = true;
|
||||
}
|
||||
|
||||
$sResult .= '<!--';
|
||||
$sResult .= ' [version:'.APP_VERSION;
|
||||
$sResult .= '][time:'.\substr(\microtime(true) - APP_START, 0, 6);
|
||||
$sResult .= '][cached:'.($bCached ? 'true' : 'false');
|
||||
$sResult .= '][hash:'.$aTemplateParameters['{{BaseHash}}'];
|
||||
$sResult .= '][session:'.\md5(\RainLoop\Utils::GetShortToken());
|
||||
$sResult .= '] -->';
|
||||
}
|
||||
|
||||
// Output result
|
||||
echo $sResult;
|
||||
unset($sResult);
|
||||
|
||||
$this->oActions->BootEnd();
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $bAdmin
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function indexTemplateParameters($bAdmin)
|
||||
{
|
||||
$sLanguage = 'en';
|
||||
$sTheme = 'Default';
|
||||
|
||||
if (!$bAdmin)
|
||||
{
|
||||
list($sLanguage, $sTheme) = $this->oActions->GetLanguageAndTheme();
|
||||
}
|
||||
|
||||
$sLanguage = $this->oActions->ValidateLanguage($sLanguage);
|
||||
$sTheme = $this->oActions->ValidateTheme($sTheme);
|
||||
|
||||
$bAppJsDebug = !!$this->oActions->Config()->Get('labs', 'use_app_debug_js', false);
|
||||
$bAppCssDebug = !!$this->oActions->Config()->Get('labs', 'use_app_debug_css', false);
|
||||
|
||||
$sStaticPrefix = APP_WEB_STATIC_PATH;
|
||||
|
||||
$aData = array(
|
||||
'Language' => $sLanguage,
|
||||
'Theme' => $sTheme,
|
||||
'LoadingDescription' => $this->oActions->Config()->Get('webmail', 'loading_description', 'RainLoop'),
|
||||
'FaviconIcoLink' => $sStaticPrefix.'favicon.ico',
|
||||
'FaviconPngLink' => $sStaticPrefix.'favicon.png',
|
||||
'AppleTouchLink' => $sStaticPrefix.'apple-touch-icon.png',
|
||||
'AppCssLink' => $sStaticPrefix.'css/app'.($bAppCssDebug ? '' : '.min').'.css',
|
||||
'BootJsLink' => $sStaticPrefix.'js/min/boot.js',
|
||||
'LibJsLink' => $sStaticPrefix.'js/min/libs.js',
|
||||
'EditorJsLink' => $sStaticPrefix.'ckeditor/ckeditor.js',
|
||||
'OpenPgpJsLink' => $sStaticPrefix.'js/min/openpgp.min.js',
|
||||
'AppJsLink' => $sStaticPrefix.'js/'.($bAppJsDebug ? '' : 'min/').($bAdmin ? 'admin' : 'app').'.js'
|
||||
);
|
||||
|
||||
$aTemplateParameters = array(
|
||||
'{{BaseAppDataScriptLink}}' => ($bAdmin ? './?/AdminAppData/' : './?/AppData/'),
|
||||
'{{BaseAppFaviconIcoFile}}' => $aData['FaviconIcoLink'],
|
||||
'{{BaseAppFaviconPngFile}}' => $aData['FaviconPngLink'],
|
||||
'{{BaseAppAppleTouchFile}}' => $aData['AppleTouchLink'],
|
||||
'{{BaseAppMainCssLink}}' => $aData['AppCssLink'],
|
||||
'{{BaseAppBootScriptLink}}' => $aData['BootJsLink'],
|
||||
'{{BaseAppLibsScriptLink}}' => $aData['LibJsLink'],
|
||||
'{{BaseAppEditorScriptLink}}' => $aData['EditorJsLink'],
|
||||
'{{BaseAppOpenPgpScriptLink}}' => $aData['OpenPgpJsLink'],
|
||||
'{{BaseAppMainScriptLink}}' => $aData['AppJsLink'],
|
||||
'{{BaseAppLoadingDescription}}' => \htmlspecialchars($aData['LoadingDescription'], ENT_QUOTES|ENT_IGNORE, 'UTF-8'),
|
||||
'{{BaseDir}}' => \in_array($aData['Language'], array('ar', 'he', 'ur')) ? 'rtl' : 'ltr'
|
||||
);
|
||||
|
||||
$aTemplateParameters['{{BaseHash}}'] = \md5(
|
||||
\implode('~', array(
|
||||
\md5($this->oActions->Config()->Get('cache', 'index', '')),
|
||||
$this->oActions->Plugins()->Hash(),
|
||||
APP_WEB_PATH, APP_VERSION
|
||||
)).
|
||||
\implode('~', $aTemplateParameters)
|
||||
);
|
||||
|
||||
return $aTemplateParameters;
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -1,64 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace RainLoop;
|
||||
|
||||
class Settings
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $aData;
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->aData = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $aData
|
||||
*
|
||||
* @return \RainLoop\Settings
|
||||
*/
|
||||
public function InitData($aData)
|
||||
{
|
||||
if (\is_array($aData))
|
||||
{
|
||||
$this->aData = $aData;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function DataAsArray()
|
||||
{
|
||||
return $this->aData;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sName
|
||||
* @param mixed $mDefValue = null
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function GetConf($sName, $mDefValue = null)
|
||||
{
|
||||
return isset($this->aData[$sName]) ? $this->aData[$sName] : $mDefValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sName
|
||||
* @param mixed $mValue
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function SetConf($sName, $mValue)
|
||||
{
|
||||
$this->aData[$sName] = $mValue;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,875 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace RainLoop;
|
||||
|
||||
class Social
|
||||
{
|
||||
/**
|
||||
* @var \MailSo\Base\Http
|
||||
*/
|
||||
private $oHttp;
|
||||
|
||||
/**
|
||||
* @var \RainLoop\Actions
|
||||
*/
|
||||
private $oActions;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param \MailSo\Base\Http $oHttp
|
||||
* @param \RainLoop\Actions $oActions
|
||||
*/
|
||||
public function __construct($oHttp, $oActions)
|
||||
{
|
||||
$this->oHttp = $oHttp;
|
||||
$this->oActions = $oActions;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $oItem
|
||||
* @param array $aPics
|
||||
*
|
||||
* @return array|null
|
||||
*/
|
||||
private function convertGoogleJsonContactToResponseContact($oItem, &$aPics)
|
||||
{
|
||||
$mResult = null;
|
||||
if (!empty($oItem['gd$email'][0]['address']))
|
||||
{
|
||||
$mEmail = \MailSo\Base\Utils::IdnToAscii($oItem['gd$email'][0]['address'], true);
|
||||
if (\is_array($oItem['gd$email']) && 1 < \count($oItem['gd$email']))
|
||||
{
|
||||
$mEmail = array();
|
||||
foreach ($oItem['gd$email'] as $oEmail)
|
||||
{
|
||||
if (!empty($oEmail['address']))
|
||||
{
|
||||
$mEmail[] = \MailSo\Base\Utils::IdnToAscii($oEmail['address'], true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$sImg = '';
|
||||
if (!empty($oItem['link']) && \is_array($oItem['link']))
|
||||
{
|
||||
foreach ($oItem['link'] as $oLink)
|
||||
{
|
||||
if ($oLink && isset($oLink['type'], $oLink['href'], $oLink['rel']) &&
|
||||
'image/*' === $oLink['type'] && '#photo' === \substr($oLink['rel'], -6))
|
||||
{
|
||||
$sImg = $oLink['href'];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$mResult = array(
|
||||
'email' => $mEmail,
|
||||
'name' => !empty($oItem['title']['$t']) ? $oItem['title']['$t'] : ''
|
||||
);
|
||||
|
||||
if (0 < \strlen($sImg))
|
||||
{
|
||||
$sHash = \RainLoop\Utils::EncodeKeyValues(array(
|
||||
'url' => $sImg,
|
||||
'type' => 'google_access_token'
|
||||
));
|
||||
|
||||
$mData = array();
|
||||
if (isset($aPics[$sHash]))
|
||||
{
|
||||
$mData = $aPics[$sHash];
|
||||
if (!\is_array($mData))
|
||||
{
|
||||
$mData = array($mData);
|
||||
}
|
||||
}
|
||||
|
||||
if (\is_array($mEmail))
|
||||
{
|
||||
$mData = \array_merge($mData, $mEmail);
|
||||
$mData = \array_unique($mData);
|
||||
}
|
||||
else if (0 < \strlen($mEmail))
|
||||
{
|
||||
$mData[] = $mEmail;
|
||||
}
|
||||
|
||||
if (\is_array($mData))
|
||||
{
|
||||
if (1 === \count($mData) && !empty($mData[0]))
|
||||
{
|
||||
$aPics[$sHash] = $mData[0];
|
||||
}
|
||||
else if (1 < \count($mData))
|
||||
{
|
||||
$aPics[$sHash] = $mData;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $mResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function GoogleUserContacts($oAccount)
|
||||
{
|
||||
$mResult = false;
|
||||
$oGoogle = $this->GoogleConnector();
|
||||
$aPics = array();
|
||||
|
||||
if ($oAccount && $oGoogle)
|
||||
{
|
||||
$sAccessToken = $this->GoogleAccessToken($oAccount, $oGoogle);
|
||||
if (!empty($sAccessToken))
|
||||
{
|
||||
$oGoogle->setAccessToken($sAccessToken);
|
||||
|
||||
$aResponse = $oGoogle->fetch('https://www.google.com/m8/feeds/contacts/default/full', array(
|
||||
'alt' => 'json'
|
||||
));
|
||||
|
||||
if (!empty($aResponse['result']['feed']['entry']) && \is_array($aResponse['result']['feed']['entry']))
|
||||
{
|
||||
$mResult = array();
|
||||
foreach ($aResponse['result']['feed']['entry'] as $oItem)
|
||||
{
|
||||
$aItem = $this->convertGoogleJsonContactToResponseContact($oItem, $aPics);
|
||||
if ($aItem)
|
||||
{
|
||||
if (\is_array($aItem['email']))
|
||||
{
|
||||
$aNewItem = $aItem;
|
||||
unset($aNewItem['email']);
|
||||
|
||||
foreach ($aItem['email'] as $sEmail)
|
||||
{
|
||||
$aNewItem['email'] = $sEmail;
|
||||
$mResult[] = $aNewItem;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$mResult[] = $aItem;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->oActions->Logger()->Write('Empty Google Access Token', \MailSo\Log\Enumerations\Type::ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
return false !== $mResult ? array(
|
||||
'List' => $mResult,
|
||||
'Pics' => $aPics
|
||||
) : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function GoogleDisconnect($oAccount)
|
||||
{
|
||||
$oGoogle = $this->GoogleConnector();
|
||||
if ($oAccount && $oGoogle)
|
||||
{
|
||||
$oSettings = $this->oActions->SettingsProvider()->Load($oAccount);
|
||||
$sEncodedeData = $oSettings->GetConf('GoogleAccessToken', '');
|
||||
|
||||
if (!empty($sEncodedeData))
|
||||
{
|
||||
$aData = \RainLoop\Utils::DecodeKeyValues($sEncodedeData);
|
||||
if (\is_array($aData) && isset($aData['access_token'], $aData['id']))
|
||||
{
|
||||
$this->oActions->StorageProvider()->Clear(null,
|
||||
\RainLoop\Providers\Storage\Enumerations\StorageType::NOBODY,
|
||||
$this->GoogleUserLoginStorageKey($oGoogle, $aData['id'])
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
$oSettings->SetConf('GoogleAccessToken', '');
|
||||
$oSettings->SetConf('GoogleSocialName', '');
|
||||
return $this->oActions->SettingsProvider()->Save($oAccount, $oSettings);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function FacebookDisconnect($oAccount)
|
||||
{
|
||||
$oFacebook = $this->FacebookConnector($oAccount ? $oAccount : null);
|
||||
if ($oAccount && $oFacebook)
|
||||
{
|
||||
$oSettings = $this->oActions->SettingsProvider()->Load($oAccount);
|
||||
|
||||
$sEncodedeData = $oSettings->GetConf('FacebookAccessToken', '');
|
||||
|
||||
if (!empty($sEncodedeData))
|
||||
{
|
||||
$aData = \RainLoop\Utils::DecodeKeyValues($sEncodedeData);
|
||||
if (is_array($aData) && isset($aData['id']))
|
||||
{
|
||||
$this->oActions->StorageProvider()->Clear(null,
|
||||
\RainLoop\Providers\Storage\Enumerations\StorageType::NOBODY,
|
||||
$this->FacebookUserLoginStorageKey($oFacebook, $aData['id'])
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
$oSettings->SetConf('FacebookAccessToken', '');
|
||||
$oSettings->SetConf('FacebookSocialName', '');
|
||||
|
||||
return $this->oActions->SettingsProvider()->Save($oAccount, $oSettings);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function TwitterDisconnect($oAccount)
|
||||
{
|
||||
$oTwitter = $this->TwitterConnector();
|
||||
if ($oAccount && $oTwitter)
|
||||
{
|
||||
$oSettings = $this->oActions->SettingsProvider()->Load($oAccount);
|
||||
$sEncodedeData = $oSettings->GetConf('TwitterAccessToken', '');
|
||||
|
||||
if (!empty($sEncodedeData))
|
||||
{
|
||||
$aData = \RainLoop\Utils::DecodeKeyValues($sEncodedeData);
|
||||
if (is_array($aData) && isset($aData['user_id']))
|
||||
{
|
||||
$this->oActions->StorageProvider()->Clear(null,
|
||||
\RainLoop\Providers\Storage\Enumerations\StorageType::NOBODY,
|
||||
$this->TwitterUserLoginStorageKey($oTwitter, $aData['user_id'])
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
$oSettings->SetConf('TwitterAccessToken', '');
|
||||
$oSettings->SetConf('TwitterSocialName', '');
|
||||
return $this->oActions->SettingsProvider()->Save($oAccount, $oSettings);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function GooglePopupService()
|
||||
{
|
||||
$sResult = '';
|
||||
$sLoginUrl = '';
|
||||
|
||||
$bLogin = false;
|
||||
$iErrorCode = \RainLoop\Notifications::UnknownError;
|
||||
|
||||
try
|
||||
{
|
||||
$oGoogle = $this->GoogleConnector();
|
||||
if ($this->oHttp->HasQuery('error'))
|
||||
{
|
||||
$iErrorCode = ('access_denied' === $this->oHttp->GetQuery('error')) ?
|
||||
\RainLoop\Notifications::SocialGoogleLoginAccessDisable : \RainLoop\Notifications::UnknownError;
|
||||
}
|
||||
else if ($oGoogle)
|
||||
{
|
||||
$oAccount = $this->oActions->GetAccount();
|
||||
$bLogin = !$oAccount;
|
||||
|
||||
$sCheckToken = '';
|
||||
$sCheckAuth = '';
|
||||
$sState = $this->oHttp->GetQuery('state');
|
||||
if (!empty($sState))
|
||||
{
|
||||
$aParts = explode('|', $sState, 2);
|
||||
$sCheckToken = !empty($aParts[0]) ? $aParts[0] : '';
|
||||
$sCheckAuth = !empty($aParts[1]) ? $aParts[1] : '';
|
||||
}
|
||||
|
||||
$sRedirectUrl = $this->oHttp->GetFullUrl().'?SocialGoogle';
|
||||
if (!$this->oHttp->HasQuery('code'))
|
||||
{
|
||||
// https://www.google.com/m8/feeds/
|
||||
$aParams = array(
|
||||
'scope' => 'https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/userinfo.profile',
|
||||
'state' => \RainLoop\Utils::GetConnectionToken().'|'.$this->oActions->GetSpecAuthToken(),
|
||||
// 'access_type' => 'offline',
|
||||
// 'approval_prompt' => 'force',
|
||||
'response_type' => 'code'
|
||||
);
|
||||
|
||||
$sLoginUrl = $oGoogle->getAuthenticationUrl('https://accounts.google.com/o/oauth2/auth', $sRedirectUrl, $aParams);
|
||||
}
|
||||
else if (!empty($sState) && $sCheckToken === \RainLoop\Utils::GetConnectionToken())
|
||||
{
|
||||
if (!empty($sCheckAuth))
|
||||
{
|
||||
$this->oActions->SetSpecAuthToken($sCheckAuth);
|
||||
$oAccount = $this->oActions->GetAccount();
|
||||
$bLogin = !$oAccount;
|
||||
}
|
||||
|
||||
$aParams = array('code' => $this->oHttp->GetQuery('code'), 'redirect_uri' => $sRedirectUrl);
|
||||
$aAuthorizationResponse = $oGoogle->getAccessToken('https://accounts.google.com/o/oauth2/token', 'authorization_code', $aParams);
|
||||
|
||||
if (!empty($aAuthorizationResponse['result']['access_token']))
|
||||
{
|
||||
$oGoogle->setAccessToken($aAuthorizationResponse['result']['access_token']);
|
||||
$aUserinfoResponse = $oGoogle->fetch('https://www.googleapis.com/oauth2/v2/userinfo');
|
||||
|
||||
if (!empty($aUserinfoResponse['result']['id']))
|
||||
{
|
||||
if ($bLogin)
|
||||
{
|
||||
$sUserData = $this->oActions->StorageProvider()->Get(null,
|
||||
\RainLoop\Providers\Storage\Enumerations\StorageType::NOBODY,
|
||||
$this->GoogleUserLoginStorageKey($oGoogle, $aUserinfoResponse['result']['id'])
|
||||
);
|
||||
|
||||
$aUserData = \RainLoop\Utils::DecodeKeyValues($sUserData);
|
||||
|
||||
if ($aUserData && \is_array($aUserData) &&
|
||||
!empty($aUserData['Email']) && isset($aUserData['Password']))
|
||||
{
|
||||
$oAccount = $this->oActions->LoginProcess($aUserData['Email'], $aUserData['Password']);
|
||||
if ($oAccount instanceof \RainLoop\Account)
|
||||
{
|
||||
$this->oActions->AuthToken($oAccount);
|
||||
|
||||
$iErrorCode = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$iErrorCode = \RainLoop\Notifications::SocialGoogleLoginAccessDisable;
|
||||
}
|
||||
}
|
||||
|
||||
if ($oAccount)
|
||||
{
|
||||
$aUserData = array(
|
||||
'Email' => $oAccount->Email(),
|
||||
'Password' => $oAccount->Password()
|
||||
);
|
||||
|
||||
$sSocialName = !empty($aUserinfoResponse['result']['name']) ? $aUserinfoResponse['result']['name'] : '';
|
||||
$sSocialName .= !empty($aUserinfoResponse['result']['email']) ? ' ('.$aUserinfoResponse['result']['email'].')' : '';
|
||||
$sSocialName = \trim($sSocialName);
|
||||
|
||||
$oSettings = $this->oActions->SettingsProvider()->Load($oAccount);
|
||||
$oSettings->SetConf('GoogleSocialName', $sSocialName);
|
||||
$this->oActions->SettingsProvider()->Save($oAccount, $oSettings);
|
||||
|
||||
$this->oActions->StorageProvider()->Put(null,
|
||||
\RainLoop\Providers\Storage\Enumerations\StorageType::NOBODY,
|
||||
$this->GoogleUserLoginStorageKey($oGoogle, $aUserinfoResponse['result']['id']),
|
||||
\RainLoop\Utils::EncodeKeyValues($aUserData));
|
||||
|
||||
$iErrorCode = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (\Exception $oException)
|
||||
{
|
||||
$this->oActions->Logger()->WriteException($oException, \MailSo\Log\Enumerations\Type::ERROR);
|
||||
}
|
||||
|
||||
if ($sLoginUrl)
|
||||
{
|
||||
$this->oActions->Location($sLoginUrl);
|
||||
}
|
||||
else
|
||||
{
|
||||
@\header('Content-Type: text/html; charset=utf-8');
|
||||
$sCallBackType = $bLogin ? '_login' : '';
|
||||
$sConnectionFunc = 'rl_'.\md5(\RainLoop\Utils::GetConnectionToken()).'_google'.$sCallBackType.'_service';
|
||||
$sResult = '<script data-cfasync="false">opener && opener.'.$sConnectionFunc.' && opener.'.
|
||||
$sConnectionFunc.'('.$iErrorCode.'); self && self.close && self.close();</script>';
|
||||
}
|
||||
|
||||
return $sResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function FacebookPopupService()
|
||||
{
|
||||
$sResult = '';
|
||||
$sLoginUrl = '';
|
||||
$sSocialName = '';
|
||||
|
||||
$mData = false;
|
||||
$sUserData = '';
|
||||
$aUserData = false;
|
||||
|
||||
$bLogin = false;
|
||||
$iErrorCode = \RainLoop\Notifications::UnknownError;
|
||||
|
||||
if (0 === \strlen($this->oActions->GetSpecAuthToken()) && $this->oHttp->HasQuery('rlah'))
|
||||
{
|
||||
$this->oActions->SetSpecAuthToken($this->oHttp->GetQuery('rlah', ''));
|
||||
}
|
||||
|
||||
$oAccount = $this->oActions->GetAccount();
|
||||
|
||||
$oFacebook = $this->FacebookConnector($oAccount);
|
||||
if ($oFacebook)
|
||||
{
|
||||
try
|
||||
{
|
||||
$oSession = $oFacebook->getSessionFromRedirect();
|
||||
if (!$oSession && !$this->oHttp->HasQuery('state'))
|
||||
{
|
||||
$sLoginUrl = $oFacebook->getLoginUrl().'&display=popup';
|
||||
}
|
||||
else if ($oSession)
|
||||
{
|
||||
$oRequest = new \Facebook\FacebookRequest($oSession, 'GET', '/me');
|
||||
$oResponse = $oRequest->execute();
|
||||
$oGraphObject = $oResponse->getGraphObject();
|
||||
|
||||
$mData = $oGraphObject->getProperty('id');
|
||||
$sSocialName = $oGraphObject->getProperty('name');
|
||||
|
||||
if ($oAccount)
|
||||
{
|
||||
if ($mData && 0 < \strlen($mData))
|
||||
{
|
||||
$aUserData = array(
|
||||
'Email' => $oAccount->Email(),
|
||||
'Password' => $oAccount->Password()
|
||||
);
|
||||
|
||||
$oSettings = $this->oActions->SettingsProvider()->Load($oAccount);
|
||||
$oSettings->SetConf('FacebookSocialName', $sSocialName);
|
||||
$oSettings->SetConf('FacebookAccessToken', \RainLoop\Utils::EncodeKeyValues(array('id' => $mData)));
|
||||
|
||||
|
||||
$this->oActions->SettingsProvider()->Save($oAccount, $oSettings);
|
||||
|
||||
$this->oActions->StorageProvider()->Put(null,
|
||||
\RainLoop\Providers\Storage\Enumerations\StorageType::NOBODY,
|
||||
$this->FacebookUserLoginStorageKey($oFacebook, $mData),
|
||||
\RainLoop\Utils::EncodeKeyValues($aUserData));
|
||||
|
||||
$iErrorCode = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$bLogin = true;
|
||||
|
||||
if ($mData && 0 < \strlen($mData))
|
||||
{
|
||||
$sUserData = $this->oActions->StorageProvider()->Get(null,
|
||||
\RainLoop\Providers\Storage\Enumerations\StorageType::NOBODY,
|
||||
$this->FacebookUserLoginStorageKey($oFacebook, $mData));
|
||||
|
||||
if ($sUserData)
|
||||
{
|
||||
$aUserData = \RainLoop\Utils::DecodeKeyValues($sUserData);
|
||||
}
|
||||
}
|
||||
|
||||
if ($aUserData && \is_array($aUserData) &&
|
||||
!empty($aUserData['Email']) && isset($aUserData['Password']))
|
||||
{
|
||||
$oAccount = $this->oActions->LoginProcess($aUserData['Email'], $aUserData['Password']);
|
||||
if ($oAccount instanceof \RainLoop\Account)
|
||||
{
|
||||
$this->oActions->AuthToken($oAccount);
|
||||
|
||||
$iErrorCode = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$iErrorCode = \RainLoop\Notifications::SocialFacebookLoginAccessDisable;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (\Exception $oException)
|
||||
{
|
||||
$this->oActions->Logger()->WriteException($oException, \MailSo\Log\Enumerations\Type::ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
if ($sLoginUrl)
|
||||
{
|
||||
$this->oActions->Location($sLoginUrl);
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->oHttp->ServerNoCache();
|
||||
|
||||
@\header('Content-Type: text/html; charset=utf-8');
|
||||
|
||||
$sCallBackType = $bLogin ? '_login' : '';
|
||||
$sConnectionFunc = 'rl_'.\md5(\RainLoop\Utils::GetConnectionToken()).'_facebook'.$sCallBackType.'_service';
|
||||
$sResult = '<script data-cfasync="false">opener && opener.'.$sConnectionFunc.' && opener.'.
|
||||
$sConnectionFunc.'('.$iErrorCode.'); self && self.close && self.close();</script>';
|
||||
}
|
||||
|
||||
return $sResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function TwitterPopupService()
|
||||
{
|
||||
$sResult = '';
|
||||
$sLoginUrl = '';
|
||||
|
||||
$sSocialName = '';
|
||||
|
||||
$bLogin = false;
|
||||
$iErrorCode = \RainLoop\Notifications::UnknownError;
|
||||
|
||||
$sRedirectUrl = $this->oHttp->GetFullUrl().'?SocialTwitter';
|
||||
if (0 < strlen($this->oActions->GetSpecAuthToken()))
|
||||
{
|
||||
$sRedirectUrl .= '&rlah='.$this->oActions->GetSpecAuthToken();
|
||||
}
|
||||
else if ($this->oHttp->HasQuery('rlah'))
|
||||
{
|
||||
$this->oActions->SetSpecAuthToken($this->oHttp->GetQuery('rlah', ''));
|
||||
$sRedirectUrl .= '&rlah='.$this->oActions->GetSpecAuthToken();
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
$oTwitter = $this->TwitterConnector();
|
||||
if ($oTwitter)
|
||||
{
|
||||
$sSessionKey = \implode('_', array('twitter',
|
||||
\md5($oTwitter->config['consumer_secret']), \md5(\RainLoop\Utils::GetConnectionToken()), 'AuthSessionData'));
|
||||
|
||||
$oAccount = $this->oActions->GetAccount();
|
||||
if ($oAccount)
|
||||
{
|
||||
if (isset($_REQUEST['oauth_verifier']))
|
||||
{
|
||||
$sAuth = $this->oActions->Cacher()->Get($sSessionKey);
|
||||
$oAuth = $sAuth ? \json_decode($sAuth, true) : null;
|
||||
|
||||
if ($oAuth && !empty($oAuth['oauth_token']) && !empty($oAuth['oauth_token_secret']))
|
||||
{
|
||||
$oTwitter->config['user_token'] = $oAuth['oauth_token'];
|
||||
$oTwitter->config['user_secret'] = $oAuth['oauth_token_secret'];
|
||||
|
||||
$iCode = $oTwitter->request('POST', $oTwitter->url('oauth/access_token', ''), array(
|
||||
'oauth_callback' => $sRedirectUrl,
|
||||
'oauth_verifier' => $_REQUEST['oauth_verifier']
|
||||
));
|
||||
|
||||
if (200 === $iCode && isset($oTwitter->response['response']))
|
||||
{
|
||||
$this->oActions->Logger()->WriteDump($oTwitter->response['response']);
|
||||
$aAccessToken = $oTwitter->extract_params($oTwitter->response['response']);
|
||||
$this->oActions->Logger()->WriteDump($aAccessToken);
|
||||
if ($aAccessToken && isset($aAccessToken['oauth_token']) && !empty($aAccessToken['user_id']))
|
||||
{
|
||||
$oTwitter->config['user_token'] = $aAccessToken['oauth_token'];
|
||||
$oTwitter->config['user_secret'] = $aAccessToken['oauth_token_secret'];
|
||||
|
||||
$sSocialName = !empty($aAccessToken['screen_name']) ? '@'.$aAccessToken['screen_name'] : $aAccessToken['user_id'];
|
||||
$sSocialName = \trim($sSocialName);
|
||||
|
||||
$aUserData = array(
|
||||
'Email' => $oAccount->Email(),
|
||||
'Password' => $oAccount->Password()
|
||||
);
|
||||
|
||||
$oSettings = $this->oActions->SettingsProvider()->Load($oAccount);
|
||||
$oSettings->SetConf('TwitterAccessToken', \RainLoop\Utils::EncodeKeyValues($aAccessToken));
|
||||
$oSettings->SetConf('TwitterSocialName', $sSocialName);
|
||||
$this->oActions->SettingsProvider()->Save($oAccount, $oSettings);
|
||||
|
||||
$this->oActions->StorageProvider()->Put(null,
|
||||
\RainLoop\Providers\Storage\Enumerations\StorageType::NOBODY,
|
||||
$this->TwitterUserLoginStorageKey($oTwitter, $aAccessToken['user_id']),
|
||||
\RainLoop\Utils::EncodeKeyValues($aUserData));
|
||||
|
||||
$iErrorCode = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$aParams = array(
|
||||
'oauth_callback' => $sRedirectUrl,
|
||||
'x_auth_access_type' => 'read'
|
||||
);
|
||||
|
||||
$iCode = $oTwitter->request('POST', $oTwitter->url('oauth/request_token', ''), $aParams);
|
||||
if (200 === $iCode && isset($oTwitter->response['response']))
|
||||
{
|
||||
$oAuth = $oTwitter->extract_params($oTwitter->response['response']);
|
||||
if (!empty($oAuth['oauth_token']))
|
||||
{
|
||||
$this->oActions->Cacher()->Set($sSessionKey, \json_encode($oAuth));
|
||||
$sLoginUrl = $oTwitter->url('oauth/authenticate', '').'?oauth_token='.$oAuth['oauth_token'];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$bLogin = true;
|
||||
|
||||
if (isset($_REQUEST['oauth_verifier']))
|
||||
{
|
||||
$sAuth = $this->oActions->Cacher()->Get($sSessionKey);
|
||||
$oAuth = $sAuth ? \json_decode($sAuth, true) : null;
|
||||
if ($oAuth && !empty($oAuth['oauth_token']) && !empty($oAuth['oauth_token_secret']))
|
||||
{
|
||||
$oTwitter->config['user_token'] = $oAuth['oauth_token'];
|
||||
$oTwitter->config['user_secret'] = $oAuth['oauth_token_secret'];
|
||||
|
||||
$iCode = $oTwitter->request('POST', $oTwitter->url('oauth/access_token', ''), array(
|
||||
'oauth_callback' => $sRedirectUrl,
|
||||
'oauth_verifier' => $_REQUEST['oauth_verifier']
|
||||
));
|
||||
|
||||
if (200 === $iCode && isset($oTwitter->response['response']))
|
||||
{
|
||||
$aAccessToken = $oTwitter->extract_params($oTwitter->response['response']);
|
||||
if ($aAccessToken && isset($aAccessToken['oauth_token']) && !empty($aAccessToken['user_id']))
|
||||
{
|
||||
$sUserData = $this->oActions->StorageProvider()->Get(null,
|
||||
\RainLoop\Providers\Storage\Enumerations\StorageType::NOBODY,
|
||||
$this->TwitterUserLoginStorageKey($oTwitter, $aAccessToken['user_id'])
|
||||
);
|
||||
|
||||
$aUserData = \RainLoop\Utils::DecodeKeyValues($sUserData);
|
||||
|
||||
if ($aUserData && \is_array($aUserData) &&
|
||||
!empty($aUserData['Email']) &&
|
||||
isset($aUserData['Password']))
|
||||
{
|
||||
$oAccount = $this->oActions->LoginProcess($aUserData['Email'], $aUserData['Password']);
|
||||
if ($oAccount instanceof \RainLoop\Account)
|
||||
{
|
||||
$this->oActions->AuthToken($oAccount);
|
||||
|
||||
$iErrorCode = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$iErrorCode = \RainLoop\Notifications::SocialTwitterLoginAccessDisable;
|
||||
}
|
||||
|
||||
$this->oActions->Cacher()->Delete($sSessionKey);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$aParams = array(
|
||||
'oauth_callback' => $sRedirectUrl,
|
||||
'x_auth_access_type' => 'read'
|
||||
);
|
||||
|
||||
$iCode = $oTwitter->request('POST', $oTwitter->url('oauth/request_token', ''), $aParams);
|
||||
if (200 === $iCode && isset($oTwitter->response['response']))
|
||||
{
|
||||
$oAuth = $oTwitter->extract_params($oTwitter->response['response']);
|
||||
if (!empty($oAuth['oauth_token']))
|
||||
{
|
||||
$this->oActions->Cacher()->Set($sSessionKey, \json_encode($oAuth));
|
||||
$sLoginUrl = $oTwitter->url('oauth/authenticate', '').'?oauth_token='.$oAuth['oauth_token'];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (\Exception $oException)
|
||||
{
|
||||
$this->oActions->Logger()->WriteException($oException, \MailSo\Log\Enumerations\Type::ERROR);
|
||||
}
|
||||
|
||||
if ($sLoginUrl)
|
||||
{
|
||||
$this->oActions->Location($sLoginUrl);
|
||||
}
|
||||
else
|
||||
{
|
||||
@\header('Content-Type: text/html; charset=utf-8');
|
||||
$sCallBackType = $bLogin ? '_login' : '';
|
||||
$sConnectionFunc = 'rl_'.\md5(\RainLoop\Utils::GetConnectionToken()).'_twitter'.$sCallBackType.'_service';
|
||||
$sResult = '<script data-cfasync="false">opener && opener.'.$sConnectionFunc.' && opener.'.
|
||||
$sConnectionFunc.'('.$iErrorCode.'); self && self.close && self.close();</script>';
|
||||
}
|
||||
|
||||
return $sResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \OAuth2\Client|null
|
||||
*/
|
||||
public function GoogleConnector()
|
||||
{
|
||||
$oGoogle = false;
|
||||
$oConfig = $this->oActions->Config();
|
||||
if ($oConfig->Get('social', 'google_enable', false) &&
|
||||
'' !== \trim($oConfig->Get('social', 'google_client_id', '')) &&
|
||||
'' !== \trim($oConfig->Get('social', 'google_client_secret', '')))
|
||||
{
|
||||
include_once APP_VERSION_ROOT_PATH.'app/libraries/PHP-OAuth2/Client.php';
|
||||
include_once APP_VERSION_ROOT_PATH.'app/libraries/PHP-OAuth2/GrantType/IGrantType.php';
|
||||
include_once APP_VERSION_ROOT_PATH.'app/libraries/PHP-OAuth2/GrantType/AuthorizationCode.php';
|
||||
include_once APP_VERSION_ROOT_PATH.'app/libraries/PHP-OAuth2/GrantType/RefreshToken.php';
|
||||
|
||||
try
|
||||
{
|
||||
$oGoogle = new \OAuth2\Client(
|
||||
\trim($oConfig->Get('social', 'google_client_id', '')),
|
||||
\trim($oConfig->Get('social', 'google_client_secret', '')));
|
||||
|
||||
$sProxy = $this->oActions->Config()->Get('labs', 'curl_proxy', '');
|
||||
if (0 < \strlen($sProxy))
|
||||
{
|
||||
$oGoogle->setCurlOption(CURLOPT_PROXY, $sProxy);
|
||||
|
||||
$sProxyAuth = $this->oActions->Config()->Get('labs', 'curl_proxy_auth', '');
|
||||
if (0 < \strlen($sProxyAuth))
|
||||
{
|
||||
$oGoogle->setCurlOption(CURLOPT_PROXYUSERPWD, $sProxyAuth);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (\Exception $oException)
|
||||
{
|
||||
$this->oActions->Logger()->WriteException($oException, \MailSo\Log\Enumerations\Type::ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
return false === $oGoogle ? null : $oGoogle;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \tmhOAuth|null
|
||||
*/
|
||||
public function TwitterConnector()
|
||||
{
|
||||
$oTwitter = false;
|
||||
$oConfig = $this->oActions->Config();
|
||||
if ($oConfig->Get('social', 'twitter_enable', false) &&
|
||||
'' !== \trim($oConfig->Get('social', 'twitter_consumer_key', '')) &&
|
||||
'' !== \trim($oConfig->Get('social', 'twitter_consumer_secret', '')))
|
||||
{
|
||||
include_once APP_VERSION_ROOT_PATH.'app/libraries/tmhOAuth/tmhOAuth.php';
|
||||
include_once APP_VERSION_ROOT_PATH.'app/libraries/tmhOAuth/tmhUtilities.php';
|
||||
|
||||
$sProxy = $this->oActions->Config()->Get('labs', 'curl_proxy', '');
|
||||
$sProxyAuth = $this->oActions->Config()->Get('labs', 'curl_proxy_auth', '');
|
||||
|
||||
$oTwitter = new \tmhOAuth(array(
|
||||
'consumer_key' => \trim($oConfig->Get('social', 'twitter_consumer_key', '')),
|
||||
'consumer_secret' => \trim($oConfig->Get('social', 'twitter_consumer_secret', '')),
|
||||
'curl_proxy' => 0 < \strlen($sProxy) ? $sProxy : false,
|
||||
'curl_proxyuserpwd' => 0 < \strlen($sProxyAuth) ? $sProxyAuth : false
|
||||
));
|
||||
}
|
||||
|
||||
return false === $oTwitter ? null : $oTwitter;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \RainLoop\Account|null $oAccount = null
|
||||
*
|
||||
* @return \RainLoop\Common\RainLoopFacebookRedirectLoginHelper|null
|
||||
*/
|
||||
public function FacebookConnector($oAccount = null)
|
||||
{
|
||||
$oFacebook = false;
|
||||
$oConfig = $this->oActions->Config();
|
||||
$sAppID = \trim($oConfig->Get('social', 'fb_app_id', ''));
|
||||
|
||||
if (\version_compare(PHP_VERSION, '5.4.0', '>=') &&
|
||||
$oConfig->Get('social', 'fb_enable', false) && '' !== $sAppID &&
|
||||
'' !== \trim($oConfig->Get('social', 'fb_app_secret', '')))
|
||||
{
|
||||
\Facebook\FacebookSession::setDefaultApplication($sAppID,
|
||||
\trim($oConfig->Get('social', 'fb_app_secret', '')));
|
||||
|
||||
$sRedirectUrl = $this->oHttp->GetFullUrl().'?SocialFacebook';
|
||||
if (0 < \strlen($this->oActions->GetSpecAuthToken()))
|
||||
{
|
||||
$sRedirectUrl .= '&rlah='.$this->oActions->GetSpecAuthToken();
|
||||
}
|
||||
else if ($this->oHttp->HasQuery('rlah'))
|
||||
{
|
||||
$this->oActions->SetSpecAuthToken($this->oHttp->GetQuery('rlah', ''));
|
||||
$sRedirectUrl .= '&rlah='.$this->oActions->GetSpecAuthToken();
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
$oAccount = $this->oActions->GetAccount();
|
||||
|
||||
$oFacebook = new \RainLoop\Common\RainLoopFacebookRedirectLoginHelper($sRedirectUrl);
|
||||
$oFacebook->initRainLoopData(array(
|
||||
'rlAppId' => $sAppID,
|
||||
'rlAccount' => $oAccount,
|
||||
'rlUserHash' => \RainLoop\Utils::GetConnectionToken(),
|
||||
'rlStorageProvaider' => $this->oActions->StorageProvider()
|
||||
));
|
||||
}
|
||||
catch (\Exception $oException)
|
||||
{
|
||||
$this->oActions->Logger()->WriteException($oException, \MailSo\Log\Enumerations\Type::ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
return false === $oFacebook ? null : $oFacebook;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function GoogleUserLoginStorageKey($oGoogle, $sGoogleUserId)
|
||||
{
|
||||
return \implode('_', array('google', \md5($oGoogle->getClientId()), $sGoogleUserId, APP_SALT));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function FacebookUserLoginStorageKey($oFacebook, $sFacebookUserId)
|
||||
{
|
||||
return \implode('_', array('facebookNew', \md5($oFacebook->GetRLAppId()), $sFacebookUserId, APP_SALT));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function TwitterUserLoginStorageKey($oTwitter, $sTwitterUserId)
|
||||
{
|
||||
return \implode('_', array('twitter', \md5($oTwitter->config['consumer_secret']), $sTwitterUserId, APP_SALT));
|
||||
}
|
||||
}
|
||||
|
|
@ -1,356 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace RainLoop;
|
||||
|
||||
class Utils
|
||||
{
|
||||
static $Cookies = null;
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
private function __construct()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sString
|
||||
* @param string $sKey
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
static public function EncryptString($sString, $sKey)
|
||||
{
|
||||
return \MailSo\Base\Crypt::XxteaEncrypt($sString, $sKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sEncriptedString
|
||||
* @param string $sKey
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
static public function DecryptString($sEncriptedString, $sKey)
|
||||
{
|
||||
return \MailSo\Base\Crypt::XxteaDecrypt($sEncriptedString, $sKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $aValues
|
||||
* @param string $sCustomKey = ''
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
static public function EncodeKeyValues(array $aValues, $sCustomKey = '')
|
||||
{
|
||||
return \MailSo\Base\Utils::UrlSafeBase64Encode(
|
||||
\RainLoop\Utils::EncryptString(\serialize($aValues), \md5(APP_SALT.$sCustomKey)));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sEncodedValues
|
||||
* @param string $sCustomKey = ''
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
static public function DecodeKeyValues($sEncodedValues, $sCustomKey = '')
|
||||
{
|
||||
$aResult = \unserialize(
|
||||
\RainLoop\Utils::DecryptString(
|
||||
\MailSo\Base\Utils::UrlSafeBase64Decode($sEncodedValues), \md5(APP_SALT.$sCustomKey)));
|
||||
|
||||
return \is_array($aResult) ? $aResult : array();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
static public function GetConnectionToken()
|
||||
{
|
||||
$sKey = 'rltoken';
|
||||
|
||||
$sToken = \RainLoop\Utils::GetCookie($sKey, null);
|
||||
if (null === $sToken)
|
||||
{
|
||||
$sToken = \md5(\rand(10000, 99999).\microtime(true).APP_SALT);
|
||||
\RainLoop\Utils::SetCookie($sKey, $sToken, \time() + 60 * 60 * 24 * 30, '/', null, null, true);
|
||||
}
|
||||
|
||||
return \md5('Connection'.APP_SALT.$sToken.'Token'.APP_SALT);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
static public function Fingerprint()
|
||||
{
|
||||
return \md5(empty($_SERVER['HTTP_USER_AGENT']) ? 'RainLoopFingerprint' : $_SERVER['HTTP_USER_AGENT']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
static public function GetShortToken()
|
||||
{
|
||||
$sKey = 'rlsession';
|
||||
|
||||
$sToken = \RainLoop\Utils::GetCookie($sKey, null);
|
||||
if (null === $sToken)
|
||||
{
|
||||
$sToken = \md5(\rand(10000, 99999).\microtime(true).APP_SALT);
|
||||
\RainLoop\Utils::SetCookie($sKey, $sToken, 0, '/', null, null, true);
|
||||
}
|
||||
|
||||
return \md5('Session'.APP_SALT.$sToken.'Token'.APP_SALT);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
static public function UpdateConnectionToken()
|
||||
{
|
||||
$sKey = 'rltoken';
|
||||
|
||||
$sToken = \RainLoop\Utils::GetCookie($sKey, '');
|
||||
if (!empty($sToken))
|
||||
{
|
||||
\RainLoop\Utils::SetCookie($sKey, $sToken, \time() + 60 * 60 * 24 * 30, '/', null, null, true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
static public function GetCsrfToken()
|
||||
{
|
||||
return \md5('Csrf'.APP_SALT.self::GetConnectionToken().'Token'.APP_SALT);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sPath
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function PathMD5($sPath)
|
||||
{
|
||||
$sResult = '';
|
||||
if (@\is_dir($sPath))
|
||||
{
|
||||
$oDirIterator = new \RecursiveDirectoryIterator($sPath);
|
||||
$oIterator = new \RecursiveIteratorIterator($oDirIterator, \RecursiveIteratorIterator::SELF_FIRST);
|
||||
|
||||
foreach ($oIterator as $oFile)
|
||||
{
|
||||
$sResult = \md5($sResult.($oFile->isFile() ? \md5_file($oFile) : $oFile));
|
||||
}
|
||||
}
|
||||
|
||||
return $sResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $FileName
|
||||
* @param array $aResultLang
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function ReadAndAddLang($FileName, &$aResultLang)
|
||||
{
|
||||
if (\file_exists($FileName))
|
||||
{
|
||||
$aLang = @\parse_ini_file($FileName, true);
|
||||
if (\is_array($aLang))
|
||||
{
|
||||
foreach ($aLang as $sKey => $mValue)
|
||||
{
|
||||
if (\is_array($mValue))
|
||||
{
|
||||
foreach ($mValue as $sSecKey => $mSecValue)
|
||||
{
|
||||
$aResultLang[$sKey.'/'.$sSecKey] = $mSecValue;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$aResultLang[$sKey] = $mValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sDir
|
||||
* @param string $sType = ''
|
||||
* @return array
|
||||
*/
|
||||
public static function FolderFiles($sDir, $sType = '')
|
||||
{
|
||||
$aResult = array();
|
||||
if (@\is_dir($sDir))
|
||||
{
|
||||
if (false !== ($rDirHandle = @\opendir($sDir)))
|
||||
{
|
||||
while (false !== ($sFile = @\readdir($rDirHandle)))
|
||||
{
|
||||
if (empty($sType) || $sType === \substr($sFile, -\strlen($sType)))
|
||||
{
|
||||
if (\is_file($sDir.'/'.$sFile))
|
||||
{
|
||||
$aResult[] = $sFile;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@\closedir($rDirHandle);
|
||||
}
|
||||
}
|
||||
|
||||
return $aResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sHtml
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function ClearHtmlOutput($sHtml)
|
||||
{
|
||||
// return $sHtml;
|
||||
return \str_replace('> <', '><',
|
||||
\preg_replace('/[\s]+ /i', ' ',
|
||||
\preg_replace('/ [\s]+/i', ' ',
|
||||
\preg_replace('/[\r\n\t]+/', ' ',
|
||||
$sHtml
|
||||
))));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sKey
|
||||
* @return bool
|
||||
*/
|
||||
public static function FastCheck($sKey)
|
||||
{
|
||||
$bResult = false;
|
||||
|
||||
$aMatches = array();
|
||||
if (!empty($sKey) && 0 < \strlen($sKey) && \preg_match('/^(RL[\d]+)\-(.+)\-([^\-]+)$/', $sKey, $aMatches) && 3 === \count($aMatches))
|
||||
{
|
||||
$bResult = $aMatches[3] === \strtoupper(\base_convert(\crc32(\md5(
|
||||
$aMatches[1].'-'.$aMatches[2].'-')), 10, 32));
|
||||
}
|
||||
|
||||
return $bResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sDirName
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function CompileTemplates($sDirName, $oAction)
|
||||
{
|
||||
$sResult = '';
|
||||
if (\file_exists($sDirName))
|
||||
{
|
||||
$aList = \RainLoop\Utils::FolderFiles($sDirName, '.html');
|
||||
|
||||
foreach ($aList as $sName)
|
||||
{
|
||||
$sTemplateName = \substr($sName, 0, -5);
|
||||
$sResult .= '<script id="'.\preg_replace('/[^a-zA-Z0-9]/', '', $sTemplateName).'" type="text/html" data-cfasync="false">'.
|
||||
$oAction->ProcessTemplate($sTemplateName, \file_get_contents($sDirName.'/'.$sName)).'</script>';
|
||||
}
|
||||
|
||||
$sResult = \trim($sResult);
|
||||
}
|
||||
|
||||
return $sResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sName
|
||||
* @param mixed $mDefault = null
|
||||
* @return mixed
|
||||
*/
|
||||
public static function GetCookie($sName, $mDefault = null)
|
||||
{
|
||||
if (null === self::$Cookies)
|
||||
{
|
||||
self::$Cookies = is_array($_COOKIE) ? $_COOKIE : array();
|
||||
}
|
||||
|
||||
return isset(self::$Cookies[$sName]) ? self::$Cookies[$sName] : $mDefault;
|
||||
}
|
||||
|
||||
public static function SetCookie($sName, $sValue = '', $iExpire = 0, $sPath = '/', $sDomain = '', $sSecure = false, $bHttpOnly = false)
|
||||
{
|
||||
if (null === self::$Cookies)
|
||||
{
|
||||
self::$Cookies = is_array($_COOKIE) ? $_COOKIE : array();
|
||||
}
|
||||
|
||||
self::$Cookies[$sName] = $sValue;
|
||||
@\setcookie($sName, $sValue, $iExpire, $sPath, $sDomain, $sSecure, $bHttpOnly);
|
||||
}
|
||||
|
||||
public static function ClearCookie($sName)
|
||||
{
|
||||
if (null === self::$Cookies)
|
||||
{
|
||||
self::$Cookies = is_array($_COOKIE) ? $_COOKIE : array();
|
||||
}
|
||||
|
||||
unset(self::$Cookies[$sName]);
|
||||
@\setcookie($sName, '', \time() - 3600 * 24 * 30, '/');
|
||||
}
|
||||
|
||||
public static function CustomBaseConvert($sNumberInput, $sFromBaseInput = '0123456789', $sToBaseInput = '0123456789')
|
||||
{
|
||||
if ($sFromBaseInput === $sToBaseInput)
|
||||
{
|
||||
return $sNumberInput;
|
||||
}
|
||||
|
||||
$mFromBase = \str_split($sFromBaseInput, 1);
|
||||
$mToBase = \str_split($sToBaseInput, 1);
|
||||
$aNumber = \str_split($sNumberInput, 1);
|
||||
$iFromLen = \strlen($sFromBaseInput);
|
||||
$iToLen = \strlen($sToBaseInput);
|
||||
$numberLen = \strlen($sNumberInput);
|
||||
$mRetVal = '';
|
||||
|
||||
if ($sToBaseInput === '0123456789')
|
||||
{
|
||||
$mRetVal = 0;
|
||||
for ($iIndex = 1; $iIndex <= $numberLen; $iIndex++)
|
||||
{
|
||||
$mRetVal = \bcadd($mRetVal, \bcmul(\array_search($aNumber[$iIndex - 1], $mFromBase), \bcpow($iFromLen, $numberLen - $iIndex)));
|
||||
}
|
||||
|
||||
return $mRetVal;
|
||||
}
|
||||
|
||||
if ($sFromBaseInput != '0123456789')
|
||||
{
|
||||
$sBase10 = \RainLoop\Utils::CustomBaseConvert($sNumberInput, $sFromBaseInput, '0123456789');
|
||||
}
|
||||
else
|
||||
{
|
||||
$sBase10 = $sNumberInput;
|
||||
}
|
||||
|
||||
if ($sBase10 < \strlen($sToBaseInput))
|
||||
{
|
||||
return $mToBase[$sBase10];
|
||||
}
|
||||
|
||||
while ($sBase10 !== '0')
|
||||
{
|
||||
$mRetVal = $mToBase[\bcmod($sBase10, $iToLen)].$mRetVal;
|
||||
$sBase10 = \bcdiv($sBase10, $iToLen, 0);
|
||||
}
|
||||
|
||||
return $mRetVal;
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue