mirror of
https://github.com/the-djmaze/snappymail.git
synced 2026-09-02 14:07:04 +03:00
Privacy/GDPR friendly version (removed: Social, Gravatar, Facebook, Google, Twitter, DropBox, OwnCloud)
Also removed: POP3, OAuth2 and update feature Added: admin password_hash/password_verify Requires: PHP 7.3+ Replaced: CRLF with LF Replaced: pclZip with ZipArchive
This commit is contained in:
parent
15ceddc202
commit
2cada68f41
293 changed files with 23728 additions and 85420 deletions
File diff suppressed because it is too large
Load diff
|
|
@ -1,275 +1,244 @@
|
|||
<?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::$MessageListPermanentFilter =
|
||||
\trim(\RainLoop\Api::Config()->Get('labs', 'imap_message_list_permanent_filter', ''));
|
||||
|
||||
\MailSo\Config::$MessageAllHeaders =
|
||||
!!\RainLoop\Api::Config()->Get('labs', 'imap_message_all_headers', false);
|
||||
|
||||
\MailSo\Config::$LargeThreadLimit =
|
||||
(int) \RainLoop\Api::Config()->Get('labs', 'imap_large_thread_limit', 50);
|
||||
|
||||
\MailSo\Config::$ImapTimeout =
|
||||
(int) \RainLoop\Api::Config()->Get('labs', 'imap_timeout', 300);
|
||||
|
||||
\MailSo\Config::$BoundaryPrefix = '_RainLoop_';
|
||||
|
||||
\MailSo\Config::$SystemLogger = \RainLoop\Api::Logger();
|
||||
|
||||
$sSslCafile = \RainLoop\Api::Config()->Get('ssl', 'cafile', '');
|
||||
$sSslCapath = \RainLoop\Api::Config()->Get('ssl', 'capath', '');
|
||||
|
||||
\RainLoop\Utils::$CookieDefaultPath = \RainLoop\Api::Config()->Get('labs', 'cookie_default_path', '');
|
||||
if (\RainLoop\Api::Config()->Get('labs', 'cookie_default_secure', false))
|
||||
{
|
||||
\RainLoop\Utils::$CookieDefaultSecure = true;
|
||||
}
|
||||
|
||||
if (!empty($sSslCafile) || !empty($sSslCapath))
|
||||
{
|
||||
\MailSo\Hooks::Add('Net.NetClient.StreamContextSettings/Filter', function (&$aStreamContextSettings) use ($sSslCafile, $sSslCapath) {
|
||||
if (isset($aStreamContextSettings['ssl']) && \is_array($aStreamContextSettings['ssl']))
|
||||
{
|
||||
if (empty($aStreamContextSettings['ssl']['cafile']) && !empty($sSslCafile))
|
||||
{
|
||||
$aStreamContextSettings['ssl']['cafile'] = $sSslCafile;
|
||||
}
|
||||
|
||||
if (empty($aStreamContextSettings['ssl']['capath']) && !empty($sSslCapath))
|
||||
{
|
||||
$aStreamContextSettings['ssl']['capath'] = $sSslCapath;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
\MailSo\Config::$HtmlStrictDebug = !!\RainLoop\Api::Config()->Get('debug', 'enable', false);
|
||||
|
||||
\MailSo\Config::$CheckNewMessages = !!\RainLoop\Api::Config()->Get('labs', 'check_new_messages', true);
|
||||
|
||||
if (\RainLoop\Api::Config()->Get('labs', 'strict_html_parser', true))
|
||||
{
|
||||
\MailSo\Config::$HtmlStrictAllowedAttributes = array(
|
||||
// rainloop
|
||||
'data-wrp',
|
||||
// defaults
|
||||
'name',
|
||||
'dir', 'lang', 'style', 'title',
|
||||
'background', 'bgcolor', 'alt', 'height', 'width', 'src', 'href',
|
||||
'border', 'bordercolor', 'charset', 'direction', 'language',
|
||||
// a
|
||||
'coords', 'download', 'hreflang', 'shape',
|
||||
// body
|
||||
'alink', 'bgproperties', 'bottommargin', 'leftmargin', 'link', 'rightmargin', 'text', 'topmargin', 'vlink',
|
||||
'marginwidth', 'marginheight', 'offset',
|
||||
// button,
|
||||
'disabled', 'type', 'value',
|
||||
// col
|
||||
'align', 'valign',
|
||||
// font
|
||||
'color', 'face', 'size',
|
||||
// form
|
||||
'novalidate',
|
||||
// hr
|
||||
'noshade',
|
||||
// img
|
||||
'hspace', 'sizes', 'srcset', 'vspace', 'usemap',
|
||||
// input, textarea
|
||||
'checked', 'max', 'min', 'maxlength', 'multiple', 'pattern', 'placeholder', 'readonly', 'required', 'step', 'wrap',
|
||||
// label
|
||||
'for',
|
||||
// meter
|
||||
'low', 'high', 'optimum',
|
||||
// ol
|
||||
'reversed', 'start',
|
||||
// option
|
||||
'selected', 'label',
|
||||
// table
|
||||
'cols', 'rows', 'frame', 'rules', 'summary', 'cellpadding', 'cellspacing',
|
||||
// td
|
||||
'abbr', 'axis', 'colspan', 'rowspan', 'headers', 'nowrap'
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public static function Version()
|
||||
{
|
||||
return APP_VERSION;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sEmail
|
||||
* @param string $sPassword
|
||||
* @param array $aAdditionalOptions = array()
|
||||
* @param bool $bUseTimeout = true
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function GetUserSsoHash($sEmail, $sPassword, $aAdditionalOptions = array(), $bUseTimeout = true)
|
||||
{
|
||||
$sSsoHash = \MailSo\Base\Utils::Sha1Rand(\md5($sEmail).\md5($sPassword));
|
||||
|
||||
return \RainLoop\Api::Actions()->Cacher()->Set(\RainLoop\KeyPathHelper::SsoCacherKey($sSsoHash),
|
||||
\RainLoop\Utils::EncodeKeyValuesQ(array(
|
||||
'Email' => $sEmail,
|
||||
'Password' => $sPassword,
|
||||
'AdditionalOptions' => $aAdditionalOptions,
|
||||
'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())
|
||||
{
|
||||
$oStorageProvider->DeleteStorage($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;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public static function ExitOnEnd()
|
||||
{
|
||||
if (!\defined('RAINLOOP_EXIT_ON_END'))
|
||||
{
|
||||
\define('RAINLOOP_EXIT_ON_END', true);
|
||||
}
|
||||
}
|
||||
}
|
||||
<?php
|
||||
|
||||
namespace RainLoop;
|
||||
|
||||
class Api
|
||||
{
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
private function __construct()
|
||||
{
|
||||
}
|
||||
|
||||
public static function RunResult() : bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @staticvar bool $bOne
|
||||
*/
|
||||
public static function Handle() : bool
|
||||
{
|
||||
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();
|
||||
}
|
||||
|
||||
public static function SetupDefaultMailSoConfig() : string
|
||||
{
|
||||
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::$MessageListPermanentFilter =
|
||||
\trim(\RainLoop\Api::Config()->Get('labs', 'imap_message_list_permanent_filter', ''));
|
||||
|
||||
\MailSo\Config::$MessageAllHeaders =
|
||||
!!\RainLoop\Api::Config()->Get('labs', 'imap_message_all_headers', false);
|
||||
|
||||
\MailSo\Config::$LargeThreadLimit =
|
||||
(int) \RainLoop\Api::Config()->Get('labs', 'imap_large_thread_limit', 50);
|
||||
|
||||
\MailSo\Config::$ImapTimeout =
|
||||
(int) \RainLoop\Api::Config()->Get('labs', 'imap_timeout', 300);
|
||||
|
||||
\MailSo\Config::$BoundaryPrefix = '_RainLoop_';
|
||||
|
||||
\MailSo\Config::$SystemLogger = \RainLoop\Api::Logger();
|
||||
|
||||
$sSslCafile = \RainLoop\Api::Config()->Get('ssl', 'cafile', '');
|
||||
$sSslCapath = \RainLoop\Api::Config()->Get('ssl', 'capath', '');
|
||||
|
||||
\RainLoop\Utils::$CookieDefaultPath = \RainLoop\Api::Config()->Get('labs', 'cookie_default_path', '');
|
||||
if (\RainLoop\Api::Config()->Get('labs', 'cookie_default_secure', false))
|
||||
{
|
||||
\RainLoop\Utils::$CookieDefaultSecure = true;
|
||||
}
|
||||
|
||||
if (!empty($sSslCafile) || !empty($sSslCapath))
|
||||
{
|
||||
\MailSo\Hooks::Add('Net.NetClient.StreamContextSettings/Filter', function (&$aStreamContextSettings) use ($sSslCafile, $sSslCapath) {
|
||||
if (isset($aStreamContextSettings['ssl']) && \is_array($aStreamContextSettings['ssl']))
|
||||
{
|
||||
if (empty($aStreamContextSettings['ssl']['cafile']) && !empty($sSslCafile))
|
||||
{
|
||||
$aStreamContextSettings['ssl']['cafile'] = $sSslCafile;
|
||||
}
|
||||
|
||||
if (empty($aStreamContextSettings['ssl']['capath']) && !empty($sSslCapath))
|
||||
{
|
||||
$aStreamContextSettings['ssl']['capath'] = $sSslCapath;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
\MailSo\Config::$HtmlStrictDebug = !!\RainLoop\Api::Config()->Get('debug', 'enable', false);
|
||||
|
||||
\MailSo\Config::$CheckNewMessages = !!\RainLoop\Api::Config()->Get('labs', 'check_new_messages', true);
|
||||
|
||||
if (\RainLoop\Api::Config()->Get('labs', 'strict_html_parser', true))
|
||||
{
|
||||
\MailSo\Config::$HtmlStrictAllowedAttributes = array(
|
||||
// rainloop
|
||||
'data-wrp',
|
||||
// defaults
|
||||
'name',
|
||||
'dir', 'lang', 'style', 'title',
|
||||
'background', 'bgcolor', 'alt', 'height', 'width', 'src', 'href',
|
||||
'border', 'bordercolor', 'charset', 'direction', 'language',
|
||||
// a
|
||||
'coords', 'download', 'hreflang', 'shape',
|
||||
// body
|
||||
'alink', 'bgproperties', 'bottommargin', 'leftmargin', 'link', 'rightmargin', 'text', 'topmargin', 'vlink',
|
||||
'marginwidth', 'marginheight', 'offset',
|
||||
// button,
|
||||
'disabled', 'type', 'value',
|
||||
// col
|
||||
'align', 'valign',
|
||||
// font
|
||||
'color', 'face', 'size',
|
||||
// form
|
||||
'novalidate',
|
||||
// hr
|
||||
'noshade',
|
||||
// img
|
||||
'hspace', 'sizes', 'srcset', 'vspace', 'usemap',
|
||||
// input, textarea
|
||||
'checked', 'max', 'min', 'maxlength', 'multiple', 'pattern', 'placeholder', 'readonly', 'required', 'step', 'wrap',
|
||||
// label
|
||||
'for',
|
||||
// meter
|
||||
'low', 'high', 'optimum',
|
||||
// ol
|
||||
'reversed', 'start',
|
||||
// option
|
||||
'selected', 'label',
|
||||
// table
|
||||
'cols', 'rows', 'frame', 'rules', 'summary', 'cellpadding', 'cellspacing',
|
||||
// td
|
||||
'abbr', 'axis', 'colspan', 'rowspan', 'headers', 'nowrap'
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static function Version() : string
|
||||
{
|
||||
return APP_VERSION;
|
||||
}
|
||||
|
||||
public static function GetUserSsoHash(string $sEmail, string $sPassword, array $aAdditionalOptions = array(), bool $bUseTimeout = true) : string
|
||||
{
|
||||
$sSsoHash = \MailSo\Base\Utils::Sha1Rand(\md5($sEmail).\md5($sPassword));
|
||||
|
||||
return \RainLoop\Api::Actions()->Cacher()->Set(\RainLoop\KeyPathHelper::SsoCacherKey($sSsoHash),
|
||||
\RainLoop\Utils::EncodeKeyValuesQ(array(
|
||||
'Email' => $sEmail,
|
||||
'Password' => $sPassword,
|
||||
'AdditionalOptions' => $aAdditionalOptions,
|
||||
'Time' => $bUseTimeout ? \time() : 0
|
||||
))) ? $sSsoHash : '';
|
||||
}
|
||||
|
||||
public static function ClearUserSsoHash(string $sSsoHash) : bool
|
||||
{
|
||||
return \RainLoop\Api::Actions()->Cacher()->Delete(\RainLoop\KeyPathHelper::SsoCacherKey($sSsoHash));
|
||||
}
|
||||
|
||||
public static function ClearUserData(string $sEmail) : bool
|
||||
{
|
||||
if (0 < \strlen($sEmail))
|
||||
{
|
||||
$sEmail = \MailSo\Base\Utils::IdnToAscii($sEmail);
|
||||
|
||||
$oStorageProvider = \RainLoop\Api::Actions()->StorageProvider();
|
||||
if ($oStorageProvider && $oStorageProvider->IsActive())
|
||||
{
|
||||
$oStorageProvider->DeleteStorage($sEmail);
|
||||
}
|
||||
|
||||
if (\RainLoop\Api::Actions()->AddressBookProvider() &&
|
||||
\RainLoop\Api::Actions()->AddressBookProvider()->IsActive())
|
||||
{
|
||||
\RainLoop\Api::Actions()->AddressBookProvider()->DeleteAllContacts($sEmail);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static function LogoutCurrentLogginedUser() : bool
|
||||
{
|
||||
\RainLoop\Utils::ClearCookie('rlsession');
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public static function ExitOnEnd()
|
||||
{
|
||||
if (!\defined('RAINLOOP_EXIT_ON_END'))
|
||||
{
|
||||
\define('RAINLOOP_EXIT_ON_END', true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace RainLoop;
|
||||
|
||||
class Account {}
|
||||
|
|
@ -1,81 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace RainLoop\Common;
|
||||
|
||||
class FacebookRainLoopPersistentDataHandler implements \Facebook\PersistentData\PersistentDataInterface
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $rlUserHash;
|
||||
|
||||
/**
|
||||
* @var mixed
|
||||
*/
|
||||
private $rlAccount;
|
||||
|
||||
/**
|
||||
* @var mixed
|
||||
*/
|
||||
private $rlStorageProvaider;
|
||||
|
||||
public function __construct($rlAccount, $rlUserHash, $rlStorageProvaider)
|
||||
{
|
||||
$this->rlAccount = $rlAccount;
|
||||
$this->rlUserHash = $rlUserHash;
|
||||
$this->rlStorageProvaider = $rlStorageProvaider;
|
||||
|
||||
if (!class_exists('RainLoop\Providers\Storage\Enumerations\StorageType') || '' === $this->rlUserHash)
|
||||
{
|
||||
$this->rlStorageProvaider = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a value from a persistent data store.
|
||||
*
|
||||
* @param string $key
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function get($key)
|
||||
{
|
||||
if ($this->rlStorageProvaider)
|
||||
{
|
||||
return $this->rlStorageProvaider->Get(
|
||||
$this->rlAccount ? $this->rlAccount : null,
|
||||
$this->rlAccount ? \RainLoop\Providers\Storage\Enumerations\StorageType::USER :
|
||||
\RainLoop\Providers\Storage\Enumerations\StorageType::NOBODY,
|
||||
$this->generateSessionVariableName($key), false);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a value in the persistent data store.
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
*/
|
||||
public function set($key, $value)
|
||||
{
|
||||
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($key), $value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $key
|
||||
* @return string
|
||||
*/
|
||||
private function generateSessionVariableName($key)
|
||||
{
|
||||
return implode('/', array('Fackebook', \md5($this->rlUserHash), 'Storage', $key));
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
@ -29,37 +29,22 @@ abstract class PdoAbstract
|
|||
*/
|
||||
protected $sDbType;
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function IsSupported()
|
||||
public function IsSupported() : bool
|
||||
{
|
||||
return !!\class_exists('PDO');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \MailSo\Log\Logger $oLogger
|
||||
*/
|
||||
public function SetLogger($oLogger)
|
||||
public function SetLogger(?\MailSo\Log\Logger $oLogger)
|
||||
{
|
||||
$this->oLogger = $oLogger instanceof \MailSo\Log\Logger ? $oLogger : null;
|
||||
$this->oLogger = $oLogger;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
protected function getPdoAccessData()
|
||||
protected function getPdoAccessData() : array
|
||||
{
|
||||
return array('', '', '', '');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sStr1
|
||||
* @param string $sStr2
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function sqliteNoCaseCollationHelper($sStr1, $sStr2)
|
||||
public function sqliteNoCaseCollationHelper(string $sStr1, string $sStr2) : int
|
||||
{
|
||||
$this->oLogger->WriteDump(array($sStr1, $sStr2));
|
||||
return \strcmp(\mb_strtoupper($sStr1, 'UTF-8'), \mb_strtoupper($sStr2, 'UTF-8'));
|
||||
|
|
@ -124,7 +109,7 @@ abstract class PdoAbstract
|
|||
// $this->oLogger->Write('PDO:'.$sPdoType.($bCaseFunc ? '/SQLITE_NOCASE_UTF8' : ''));
|
||||
}
|
||||
}
|
||||
catch (\Exception $oException)
|
||||
catch (\Throwable $oException)
|
||||
{
|
||||
throw $oException;
|
||||
}
|
||||
|
|
@ -141,13 +126,7 @@ abstract class PdoAbstract
|
|||
return $oPdo;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sTabelName = null
|
||||
* @param string $sColumnName = null
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function lastInsertId($sTabelName = null, $sColumnName = null)
|
||||
protected function lastInsertId(?string $sTabelName = null, ?string $sColumnName = null) : string
|
||||
{
|
||||
$mName = null;
|
||||
if ('pgsql' === $this->sDbType &&
|
||||
|
|
@ -159,39 +138,25 @@ abstract class PdoAbstract
|
|||
return null === $mName ? $this->getPDO()->lastInsertId() : $this->getPDO()->lastInsertId($mName);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
protected function beginTransaction()
|
||||
protected function beginTransaction() : bool
|
||||
{
|
||||
return $this->getPDO()->beginTransaction();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
protected function commit()
|
||||
protected function commit() : bool
|
||||
{
|
||||
return $this->getPDO()->commit();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
protected function rollBack()
|
||||
protected function rollBack() : bool
|
||||
{
|
||||
return $this->getPDO()->rollBack();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sSql
|
||||
* @param array $aParams
|
||||
* @param bool $bMultiplyParams = false
|
||||
* @param bool $bLogParams = false
|
||||
*
|
||||
* @return \PDOStatement|null
|
||||
*/
|
||||
protected function prepareAndExecute($sSql, $aParams = array(), $bMultiplyParams = false, $bLogParams = false)
|
||||
protected function prepareAndExecute(string $sSql, array $aParams = array(), bool $bMultiplyParams = false, bool $bLogParams = false)
|
||||
{
|
||||
if ($this->bExplain && !$bMultiplyParams)
|
||||
{
|
||||
|
|
@ -230,11 +195,7 @@ abstract class PdoAbstract
|
|||
return $mResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sSql
|
||||
* @param array $aParams
|
||||
*/
|
||||
protected function prepareAndExplain($sSql, $aParams = array())
|
||||
protected function prepareAndExplain(string $sSql, array $aParams = array())
|
||||
{
|
||||
$mResult = null;
|
||||
if (0 === strpos($sSql, 'SELECT '))
|
||||
|
|
@ -274,14 +235,7 @@ abstract class PdoAbstract
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sEmail
|
||||
* @param bool $bSkipInsert = false
|
||||
* @param bool $bCache = true
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
protected function getUserId($sEmail, $bSkipInsert = false, $bCache = true)
|
||||
protected function getUserId(string $sEmail, bool $bSkipInsert = false, bool $bCache = true) : int
|
||||
{
|
||||
static $aCache = array();
|
||||
if ($bCache && isset($aCache[$sEmail]))
|
||||
|
|
@ -332,24 +286,16 @@ abstract class PdoAbstract
|
|||
throw new \Exception('id_user = 0');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sValue
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function quoteValue($sValue)
|
||||
public function quoteValue(string $sValue) : string
|
||||
{
|
||||
$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)
|
||||
protected function getSystemValue(string $sName, bool $bReturnIntValue = true)
|
||||
{
|
||||
$oPdo = $this->getPDO();
|
||||
if ($oPdo)
|
||||
|
|
@ -383,22 +329,14 @@ abstract class PdoAbstract
|
|||
}
|
||||
|
||||
/**
|
||||
* @param string $sName
|
||||
*
|
||||
* @return int|string|bool
|
||||
*/
|
||||
protected function getVersion($sName)
|
||||
protected function getVersion(string $sName)
|
||||
{
|
||||
return $this->getSystemValue($sName.'_version', true);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sName
|
||||
* @param int $iVersion
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function setVersion($sName, $iVersion)
|
||||
protected function setVersion(string $sName, int $iVersion) : bool
|
||||
{
|
||||
$bResult = false;
|
||||
$oPdo = $this->getPDO();
|
||||
|
|
@ -426,8 +364,6 @@ abstract class PdoAbstract
|
|||
}
|
||||
|
||||
/**
|
||||
* @param bool $bWatchVersion = true
|
||||
*
|
||||
* @throws \Exception
|
||||
*/
|
||||
protected function initSystemTables()
|
||||
|
|
@ -506,7 +442,7 @@ rl_email text NOT NULL DEFAULT \'\'
|
|||
}
|
||||
}
|
||||
}
|
||||
catch (\Exception $oException)
|
||||
catch (\Throwable $oException)
|
||||
{
|
||||
$this->writeLog($oException);
|
||||
throw $oException;
|
||||
|
|
@ -517,13 +453,7 @@ rl_email text NOT NULL DEFAULT \'\'
|
|||
return $bResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sName
|
||||
* @param array $aData = array()
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function dataBaseUpgrade($sName, $aData = array())
|
||||
protected function dataBaseUpgrade(string $sName, array $aData = array()) : bool
|
||||
{
|
||||
$iFromVersion = null;
|
||||
try
|
||||
|
|
@ -547,10 +477,10 @@ rl_email text NOT NULL DEFAULT \'\'
|
|||
}
|
||||
}
|
||||
|
||||
$bResult = false;
|
||||
if (\is_int($iFromVersion) && 0 <= $iFromVersion)
|
||||
{
|
||||
$oPdo = false;
|
||||
$bResult = false;
|
||||
|
||||
foreach ($aData as $iVersion => $aQuery)
|
||||
{
|
||||
|
|
@ -582,7 +512,7 @@ rl_email text NOT NULL DEFAULT \'\'
|
|||
}
|
||||
}
|
||||
}
|
||||
catch (\Exception $oException)
|
||||
catch (\Throwable $oException)
|
||||
{
|
||||
$this->writeLog($oException);
|
||||
throw $oException;
|
||||
|
|
@ -600,4 +530,4 @@ rl_email text NOT NULL DEFAULT \'\'
|
|||
|
||||
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,343 +1,305 @@
|
|||
<?php
|
||||
|
||||
namespace RainLoop\Config;
|
||||
|
||||
abstract class AbstractConfig
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sFile;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sAdditionalFile;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $aData;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $bUseApcCache;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sFileHeader;
|
||||
|
||||
/**
|
||||
* @param string $sFileName
|
||||
* @param string $sFileHeader = ''
|
||||
* @param string $sAdditionalFileName = ''
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($sFileName, $sFileHeader = '', $sAdditionalFileName = '')
|
||||
{
|
||||
$this->sFile = \APP_PRIVATE_DATA.'configs/'.\trim($sFileName);
|
||||
|
||||
$sAdditionalFileName = \trim($sAdditionalFileName);
|
||||
$this->sAdditionalFile = \APP_PRIVATE_DATA.'configs/'.$sAdditionalFileName;
|
||||
$this->sAdditionalFile = 0 < \strlen($sAdditionalFileName) &&
|
||||
\file_exists($this->sAdditionalFile) ? $this->sAdditionalFile : '';
|
||||
|
||||
$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 'float':
|
||||
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).':'.\sha1($this->sAdditionalFile).':';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
private function loadDataFromCache()
|
||||
{
|
||||
if ($this->bUseApcCache)
|
||||
{
|
||||
$iMTime = @\filemtime($this->sFile);
|
||||
$iMTime = \is_int($iMTime) && 0 < $iMTime ? $iMTime : 0;
|
||||
|
||||
$iATime = $this->sAdditionalFile ? @\filemtime($this->sAdditionalFile) : 0;
|
||||
$iATime = \is_int($iATime) && 0 < $iATime ? $iATime : 0;
|
||||
|
||||
if (0 < $iMTime)
|
||||
{
|
||||
$sKey = $this->cacheKey();
|
||||
|
||||
$sTimeHash = \apc_fetch($sKey.'time');
|
||||
if ($sTimeHash && $sTimeHash === \md5($iMTime.'/'.$iATime))
|
||||
{
|
||||
$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);
|
||||
$iMTime = \is_int($iMTime) && 0 < $iMTime ? $iMTime : 0;
|
||||
|
||||
$iATime = $this->sAdditionalFile ? @\filemtime($this->sAdditionalFile) : 0;
|
||||
$iATime = \is_int($iATime) && 0 < $iATime ? $iATime : 0;
|
||||
|
||||
if (0 < $iMTime)
|
||||
{
|
||||
$sKey = $this->cacheKey();
|
||||
|
||||
\apc_store($sKey.'time', \md5($iMTime.'/'.$iATime));
|
||||
\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 IsFileExists()
|
||||
{
|
||||
return \file_exists($this->sFile);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function Load()
|
||||
{
|
||||
if (\file_exists($this->sFile) && \is_readable($this->sFile))
|
||||
{
|
||||
if ($this->loadDataFromCache())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
$aData = \RainLoop\Utils::CustomParseIniFile($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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unset($aData);
|
||||
|
||||
if (\file_exists($this->sAdditionalFile) && \is_readable($this->sAdditionalFile))
|
||||
{
|
||||
$aSubData = \RainLoop\Utils::CustomParseIniFile($this->sAdditionalFile, true);
|
||||
if (\is_array($aSubData) && 0 < \count($aSubData))
|
||||
{
|
||||
foreach ($aSubData as $sSectionKey => $aSectionValue)
|
||||
{
|
||||
if (\is_array($aSectionValue))
|
||||
{
|
||||
foreach ($aSectionValue as $sParamKey => $mParamValue)
|
||||
{
|
||||
$this->Set($sSectionKey, $sParamKey, $mParamValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unset($aSubData);
|
||||
}
|
||||
|
||||
$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 = '"'.\str_replace('"', '\"', $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));
|
||||
}
|
||||
}
|
||||
<?php
|
||||
|
||||
namespace RainLoop\Config;
|
||||
|
||||
abstract class AbstractConfig
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sFile;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sAdditionalFile;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $aData;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $bUseApcCache;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sFileHeader;
|
||||
|
||||
public function __construct(string $sFileName, string $sFileHeader = '', string $sAdditionalFileName = '')
|
||||
{
|
||||
$this->sFile = \APP_PRIVATE_DATA.'configs/'.\trim($sFileName);
|
||||
|
||||
$sAdditionalFileName = \trim($sAdditionalFileName);
|
||||
$this->sAdditionalFile = \APP_PRIVATE_DATA.'configs/'.$sAdditionalFileName;
|
||||
$this->sAdditionalFile = 0 < \strlen($sAdditionalFileName) &&
|
||||
\file_exists($this->sAdditionalFile) ? $this->sAdditionalFile : '';
|
||||
|
||||
$this->sFileHeader = $sFileHeader;
|
||||
$this->aData = $this->defaultValues();
|
||||
|
||||
$this->bUseApcCache = APP_USE_APC_CACHE &&
|
||||
\MailSo\Base\Utils::FunctionExistsAndEnabled(array('apc_fetch', 'apc_store'));
|
||||
}
|
||||
|
||||
protected abstract function defaultValues() : array;
|
||||
|
||||
public function IsInited() : bool
|
||||
{
|
||||
return \is_array($this->aData) && 0 < \count($this->aData);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $mDefault = null
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function Get(string $sSection, string $sName, $mDefault = null)
|
||||
{
|
||||
$mResult = $mDefault;
|
||||
if (isset($this->aData[$sSection][$sName][0]))
|
||||
{
|
||||
$mResult = $this->aData[$sSection][$sName][0];
|
||||
}
|
||||
return $mResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $mParamValue
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function Set(string $sSectionKey, string $sParamKey, $mParamValue)
|
||||
{
|
||||
if (isset($this->aData[$sSectionKey][$sParamKey][0]))
|
||||
{
|
||||
$sType = \gettype($this->aData[$sSectionKey][$sParamKey][0]);
|
||||
switch ($sType)
|
||||
{
|
||||
default:
|
||||
case 'float':
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
private function cacheKey() : string
|
||||
{
|
||||
return 'config:'.\sha1($this->sFile).':'.\sha1($this->sAdditionalFile).':';
|
||||
}
|
||||
|
||||
private function loadDataFromCache() : bool
|
||||
{
|
||||
if ($this->bUseApcCache)
|
||||
{
|
||||
$iMTime = @\filemtime($this->sFile);
|
||||
$iMTime = \is_int($iMTime) && 0 < $iMTime ? $iMTime : 0;
|
||||
|
||||
$iATime = $this->sAdditionalFile ? @\filemtime($this->sAdditionalFile) : 0;
|
||||
$iATime = \is_int($iATime) && 0 < $iATime ? $iATime : 0;
|
||||
|
||||
if (0 < $iMTime)
|
||||
{
|
||||
$sKey = $this->cacheKey();
|
||||
|
||||
$sTimeHash = \apc_fetch($sKey.'time');
|
||||
if ($sTimeHash && $sTimeHash === \md5($iMTime.'/'.$iATime))
|
||||
{
|
||||
$aFetchData = \apc_fetch($sKey.'data');
|
||||
if (\is_array($aFetchData))
|
||||
{
|
||||
$this->aData = $aFetchData;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private function storeDataToCache() : bool
|
||||
{
|
||||
if ($this->bUseApcCache)
|
||||
{
|
||||
$iMTime = @\filemtime($this->sFile);
|
||||
$iMTime = \is_int($iMTime) && 0 < $iMTime ? $iMTime : 0;
|
||||
|
||||
$iATime = $this->sAdditionalFile ? @\filemtime($this->sAdditionalFile) : 0;
|
||||
$iATime = \is_int($iATime) && 0 < $iATime ? $iATime : 0;
|
||||
|
||||
if (0 < $iMTime)
|
||||
{
|
||||
$sKey = $this->cacheKey();
|
||||
|
||||
\apc_store($sKey.'time', \md5($iMTime.'/'.$iATime));
|
||||
\apc_store($sKey.'data', $this->aData);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private function clearCache() : bool
|
||||
{
|
||||
if ($this->bUseApcCache)
|
||||
{
|
||||
$sKey = $this->cacheKey();
|
||||
|
||||
\apc_delete($sKey.'time');
|
||||
\apc_delete($sKey.'data');
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function IsFileExists() : bool
|
||||
{
|
||||
return \file_exists($this->sFile);
|
||||
}
|
||||
|
||||
public function Load() : bool
|
||||
{
|
||||
if (\file_exists($this->sFile) && \is_readable($this->sFile))
|
||||
{
|
||||
if ($this->loadDataFromCache())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
$aData = \RainLoop\Utils::CustomParseIniFile($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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unset($aData);
|
||||
|
||||
if (\file_exists($this->sAdditionalFile) && \is_readable($this->sAdditionalFile))
|
||||
{
|
||||
$aSubData = \RainLoop\Utils::CustomParseIniFile($this->sAdditionalFile, true);
|
||||
if (\is_array($aSubData) && 0 < \count($aSubData))
|
||||
{
|
||||
foreach ($aSubData as $sSectionKey => $aSectionValue)
|
||||
{
|
||||
if (\is_array($aSectionValue))
|
||||
{
|
||||
foreach ($aSectionValue as $sParamKey => $mParamValue)
|
||||
{
|
||||
$this->Set($sSectionKey, $sParamKey, $mParamValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unset($aSubData);
|
||||
}
|
||||
|
||||
$this->storeDataToCache();
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function Save() : bool
|
||||
{
|
||||
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 = '"'.\str_replace('"', '\"', $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,474 +1,424 @@
|
|||
<?php
|
||||
|
||||
namespace RainLoop\Config;
|
||||
|
||||
class Application extends \RainLoop\Config\AbstractConfig
|
||||
{
|
||||
private $aReplaceEnv = null;
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct('application.ini',
|
||||
'; RainLoop Webmail configuration file
|
||||
; Please don\'t add custom parameters here, those will be overwritten',
|
||||
defined('APP_ADDITIONAL_CONFIGURATION_NAME') ? APP_ADDITIONAL_CONFIGURATION_NAME : '');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sSection
|
||||
* @param string $sName
|
||||
* @param mixed $mDefault = null
|
||||
* @param bool $bUseEnvReplace = true
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function Load()
|
||||
{
|
||||
parent::Load();
|
||||
|
||||
$this->aReplaceEnv = null;
|
||||
if ((isset($_ENV) && \is_array($_ENV) && 0 < \count($_ENV)) ||
|
||||
(isset($_SERVER) && \is_array($_SERVER) && 0 < \count($_SERVER)))
|
||||
{
|
||||
$sEnvNames = $this->Get('labs', 'replace_env_in_configuration', '');
|
||||
if (0 < \strlen($sEnvNames))
|
||||
{
|
||||
$this->aReplaceEnv = \explode(',', $sEnvNames);
|
||||
if (\is_array($this->aReplaceEnv))
|
||||
{
|
||||
$this->aReplaceEnv = \array_map('trim', $this->aReplaceEnv);
|
||||
$this->aReplaceEnv = \array_map('strtolower', $this->aReplaceEnv);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!\is_array($this->aReplaceEnv) || 0 === \count($this->aReplaceEnv))
|
||||
{
|
||||
$this->aReplaceEnv = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sSection
|
||||
* @param string $sName
|
||||
* @param mixed $mDefault = null
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function Get($sSection, $sName, $mDefault = null)
|
||||
{
|
||||
$mResult = parent::Get($sSection, $sName, $mDefault);
|
||||
if ($this->aReplaceEnv && \is_string($mResult))
|
||||
{
|
||||
$sKey = \strtolower($sSection.'.'.$sName);
|
||||
if (\in_array($sKey, $this->aReplaceEnv) && false !== strpos($mResult, '$'))
|
||||
{
|
||||
$mResult = \preg_replace_callback('/\$([^\s]+)/', function($aMatch) {
|
||||
|
||||
if (!empty($aMatch[0]) && !empty($aMatch[1]))
|
||||
{
|
||||
if (!empty($_ENV[$aMatch[1]]))
|
||||
{
|
||||
return $_SERVER[$aMatch[1]];
|
||||
}
|
||||
|
||||
if (!empty($_SERVER[$aMatch[1]]))
|
||||
{
|
||||
return $_SERVER[$aMatch[1]];
|
||||
}
|
||||
|
||||
return $aMatch[0];
|
||||
}
|
||||
|
||||
return '';
|
||||
|
||||
}, $mResult);
|
||||
}
|
||||
}
|
||||
|
||||
return $mResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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 && '12345' === $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'),
|
||||
'favicon_url' => array('', ''),
|
||||
|
||||
'theme' => array('Default', 'Theme used by default'),
|
||||
'allow_themes' => array(true, 'Allow theme selection on settings screen'),
|
||||
'allow_user_background' => array(false),
|
||||
|
||||
'language' => array('en', 'Language used by default'),
|
||||
'language_admin' => array('en', 'Admin Panel interface language'),
|
||||
'allow_languages_on_settings' => array(true, 'Allow language selection on settings screen'),
|
||||
|
||||
'allow_additional_accounts' => array(true, ''),
|
||||
'allow_additional_identities' => array(true, ''),
|
||||
|
||||
'messages_per_page' => array(20, ' Number of messages displayed on page by default'),
|
||||
|
||||
'attachment_size_limit' => array(25,
|
||||
'File size limit (MB) for file upload on compose screen
|
||||
0 for unlimited.')
|
||||
),
|
||||
|
||||
'interface' => array(
|
||||
'show_attachment_thumbnail' => array(true, ''),
|
||||
'use_native_scrollbars' => array(false),
|
||||
'new_move_to_folder_button' => array(true)
|
||||
),
|
||||
|
||||
'branding' => array(
|
||||
'login_logo' => array(''),
|
||||
'login_background' => array(''),
|
||||
'login_desc' => array(''),
|
||||
'login_css' => array(''),
|
||||
|
||||
'user_css' => array(''),
|
||||
'user_logo' => array(''),
|
||||
'user_logo_title' => array(''),
|
||||
'user_logo_message' => array(''),
|
||||
'user_iframe_message' => array(''),
|
||||
|
||||
'welcome_page_url' => array(''),
|
||||
'welcome_page_display' => array('none')
|
||||
),
|
||||
|
||||
'contacts' => array(
|
||||
'enable' => array(false, 'Enable contacts'),
|
||||
'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(''),
|
||||
'x_xss_protection_header' => array('1; mode=block'),
|
||||
|
||||
'openpgp' => 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),
|
||||
'force_two_factor_auth' => array(false),
|
||||
'hide_x_mailer_header' => array(false),
|
||||
'admin_panel_host' => array(''),
|
||||
'admin_panel_key' => array('admin'),
|
||||
'content_security_policy' => array(''),
|
||||
'core_install_access_domain' => array('')
|
||||
),
|
||||
|
||||
'ssl' => array(
|
||||
'verify_certificate' => array(false, 'Require verification of SSL certificate used.'),
|
||||
'allow_self_signed' => array(true, 'Allow self-signed certificates. Requires verify_certificate.'),
|
||||
'cafile' => array('', 'Location of Certificate Authority file on local filesystem (/etc/ssl/certs/ca-certificates.crt)'),
|
||||
'capath' => array('', 'capath must be a correctly hashed certificate directory. (/etc/ssl/certs/)'),
|
||||
'client_cert' => array('', 'Location of client certificate file (pem format with private key) on local filesystem'),
|
||||
),
|
||||
|
||||
'capa' => array(
|
||||
'folders' => array(true),
|
||||
'composer' => array(true),
|
||||
'contacts' => array(true),
|
||||
'settings' => array(true),
|
||||
'quota' => array(true),
|
||||
'help' => array(true),
|
||||
'reload' => array(true),
|
||||
'search' => array(true),
|
||||
'search_adv' => array(true),
|
||||
'filters' => array(true),
|
||||
'x-templates' => array(false),
|
||||
'dangerous_actions' => array(true),
|
||||
'message_actions' => array(true),
|
||||
'messagelist_actions' => array(true),
|
||||
'attachments_actions' => array(true)
|
||||
),
|
||||
|
||||
'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, ''),
|
||||
|
||||
'welcome_page' => array(false, ''),
|
||||
|
||||
'hide_submit_button' => array(true),
|
||||
|
||||
'forgot_password_link_url' => array('', ''),
|
||||
'registration_link_url' => array('', ''),
|
||||
|
||||
'login_lowercase' => array(true, ''),
|
||||
|
||||
'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'),
|
||||
),
|
||||
|
||||
'defaults' => array(
|
||||
'view_editor_type' => array('Html', 'Editor mode used by default (Plain, Html, HtmlForced or PlainForced)'),
|
||||
'view_layout' => array(1, 'layout: 0 - no preview, 1 - side preview, 2 - bottom preview'),
|
||||
'view_use_checkboxes' => array(true),
|
||||
'autologout' => array(30),
|
||||
'show_images' => array(false),
|
||||
'contacts_autosave' => array(true),
|
||||
'mail_use_threads' => array(false),
|
||||
'allow_draft_autosave' => array(true),
|
||||
'mail_reply_same_folder' => array(false)
|
||||
),
|
||||
|
||||
'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.'),
|
||||
|
||||
'time_offset' => array('0'),
|
||||
'session_filter' => array(''),
|
||||
|
||||
'sentry_dsn' => array(''),
|
||||
|
||||
'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}
|
||||
{request:ip} - Replaced by user\'s IP address
|
||||
|
||||
Others:
|
||||
{imap:login} {imap:host} {imap:port}
|
||||
{smtp:login} {smtp:host} {smtp:port}
|
||||
|
||||
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"'),
|
||||
|
||||
'auth_logging' => array(false, 'Enable auth logging in a separate file (for fail2ban)'),
|
||||
'auth_logging_filename' => array('fail2ban/auth-{date:Y-m-d}.txt'),
|
||||
'auth_logging_format' => array('[{date:Y-m-d H:i:s}] Auth failed: ip={request:ip} user={imap:login} host={imap:host} port={imap:port}')
|
||||
),
|
||||
|
||||
'debug' => array(
|
||||
'enable' => array(false, 'Special option required for development purposes')
|
||||
),
|
||||
|
||||
'social' => array(
|
||||
'google_enable' => array(false, 'Google'),
|
||||
'google_enable_auth' => array(false),
|
||||
'google_enable_auth_gmail' => array(false),
|
||||
'google_enable_drive' => array(false),
|
||||
'google_enable_preview' => array(false),
|
||||
'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, redis (beta)'),
|
||||
'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'),
|
||||
'http_expires' => array(3600, 'Browser-level cache time (seconds, Expires header)'),
|
||||
|
||||
'server_uids' => array(true, 'Caching message UIDs when searching and sorting (threading)')
|
||||
),
|
||||
|
||||
'labs' => array(
|
||||
'allow_mobile_version' => array(true,
|
||||
'Experimental settings. Handle with care.
|
||||
'),
|
||||
'ignore_folders_subscription' => array(false),
|
||||
'check_new_password_strength' => array(true),
|
||||
'update_channel' => array('stable'),
|
||||
'allow_gravatar' => array(true),
|
||||
'allow_prefetch' => array(true),
|
||||
'allow_smart_html_links' => array(true),
|
||||
'cache_system_data' => array(true),
|
||||
'date_from_headers' => array(true),
|
||||
'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),
|
||||
'allow_html_editor_biti_buttons' => array(false),
|
||||
'allow_ctrl_enter_on_compose' => array(true),
|
||||
'try_to_detect_hidden_images' => array(false),
|
||||
'hide_dangerous_actions' => array(false),
|
||||
'use_app_debug_js' => array(false),
|
||||
'use_mobile_version_for_tablets' => array(false),
|
||||
'use_app_debug_css' => array(false),
|
||||
'use_imap_sort' => array(true),
|
||||
'use_imap_force_selection' => array(false),
|
||||
'use_imap_list_subscribe' => array(true),
|
||||
'use_imap_thread' => array(true),
|
||||
'use_imap_move' => 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_message_list_permanent_filter' => array(''),
|
||||
'imap_message_all_headers' => array(false),
|
||||
'imap_large_thread_limit' => array(50),
|
||||
'imap_folder_list_limit' => array(200),
|
||||
'imap_show_login_alert' => array(true),
|
||||
'imap_use_auth_plain' => array(true),
|
||||
'imap_use_auth_cram_md5' => array(false),
|
||||
'smtp_show_server_errors' => array(false),
|
||||
'smtp_use_auth_plain' => array(true),
|
||||
'smtp_use_auth_cram_md5' => array(false),
|
||||
'sieve_allow_raw_script' => array(false),
|
||||
'sieve_utf8_folder_name' => array(true),
|
||||
'sieve_auth_plain_initial' => array(true),
|
||||
'sieve_allow_fileinto_inbox' => array(false),
|
||||
'imap_timeout' => array(300),
|
||||
'smtp_timeout' => array(60),
|
||||
'sieve_timeout' => array(10),
|
||||
'domain_list_limit' => array(99),
|
||||
'mail_func_clear_headers' => array(true),
|
||||
'mail_func_additional_parameters' => array(false),
|
||||
'favicon_status' => array(true),
|
||||
'folders_spec_limit' => array(50),
|
||||
'owncloud_save_folder' => array('Attachments'),
|
||||
'owncloud_suggestions' => array(true),
|
||||
'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(''),
|
||||
'http_client_ip_check_proxy' => array(false),
|
||||
'fast_cache_memcache_host' => array('127.0.0.1'),
|
||||
'fast_cache_memcache_port' => array(11211),
|
||||
'fast_cache_redis_host' => array('127.0.0.1'),
|
||||
'fast_cache_redis_port' => array(6379),
|
||||
'use_local_proxy_for_external_images' => array(false),
|
||||
'detect_image_exif_orientation' => array(true),
|
||||
'cookie_default_path' => array(''),
|
||||
'cookie_default_secure' => array(false),
|
||||
'check_new_messages' => array(true),
|
||||
'replace_env_in_configuration' => array(''),
|
||||
'startup_url' => array(''),
|
||||
'strict_html_parser' => array(false),
|
||||
'allow_cmd' => array(false),
|
||||
'dev_email' => array(''),
|
||||
'dev_password' => array('')
|
||||
),
|
||||
|
||||
'version' => array(
|
||||
'current' => array(''),
|
||||
'saved' => array('')
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
<?php
|
||||
|
||||
namespace RainLoop\Config;
|
||||
|
||||
class Application extends \RainLoop\Config\AbstractConfig
|
||||
{
|
||||
private $aReplaceEnv = null;
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct('application.ini',
|
||||
'; RainLoop Webmail configuration file
|
||||
; Please don\'t add custom parameters here, those will be overwritten',
|
||||
defined('APP_ADDITIONAL_CONFIGURATION_NAME') ? APP_ADDITIONAL_CONFIGURATION_NAME : '');
|
||||
}
|
||||
|
||||
public function Load()
|
||||
{
|
||||
parent::Load();
|
||||
|
||||
$this->aReplaceEnv = null;
|
||||
if ((isset($_ENV) && \is_array($_ENV) && 0 < \count($_ENV)) ||
|
||||
(isset($_SERVER) && \is_array($_SERVER) && 0 < \count($_SERVER)))
|
||||
{
|
||||
$sEnvNames = $this->Get('labs', 'replace_env_in_configuration', '');
|
||||
if (0 < \strlen($sEnvNames))
|
||||
{
|
||||
$this->aReplaceEnv = \explode(',', $sEnvNames);
|
||||
if (\is_array($this->aReplaceEnv))
|
||||
{
|
||||
$this->aReplaceEnv = \array_map('trim', $this->aReplaceEnv);
|
||||
$this->aReplaceEnv = \array_map('strtolower', $this->aReplaceEnv);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!\is_array($this->aReplaceEnv) || 0 === \count($this->aReplaceEnv))
|
||||
{
|
||||
$this->aReplaceEnv = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $mDefault = null
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function Get(string $sSection, string $sName, $mDefault = null)
|
||||
{
|
||||
$mResult = parent::Get($sSection, $sName, $mDefault);
|
||||
if ($this->aReplaceEnv && \is_string($mResult))
|
||||
{
|
||||
$sKey = \strtolower($sSection.'.'.$sName);
|
||||
if (\in_array($sKey, $this->aReplaceEnv) && false !== strpos($mResult, '$'))
|
||||
{
|
||||
$mResult = \preg_replace_callback('/\$([^\s]+)/', function($aMatch) {
|
||||
|
||||
if (!empty($aMatch[0]) && !empty($aMatch[1]))
|
||||
{
|
||||
if (!empty($_ENV[$aMatch[1]]))
|
||||
{
|
||||
return $_SERVER[$aMatch[1]];
|
||||
}
|
||||
|
||||
if (!empty($_SERVER[$aMatch[1]]))
|
||||
{
|
||||
return $_SERVER[$aMatch[1]];
|
||||
}
|
||||
|
||||
return $aMatch[0];
|
||||
}
|
||||
|
||||
return '';
|
||||
|
||||
}, $mResult);
|
||||
}
|
||||
}
|
||||
|
||||
return $mResult;
|
||||
}
|
||||
|
||||
public function SetPassword(string $sPassword)
|
||||
{
|
||||
$this->Set('security', 'admin_password', \password_hash($sPassword));
|
||||
}
|
||||
|
||||
public function ValidatePassword(string $sPassword) : bool
|
||||
{
|
||||
$sConfigPassword = (string) $this->Get('security', 'admin_password', '');
|
||||
if (32 == \strlen($sPassword) && \md5(APP_SALT.$sPassword.APP_SALT) === $sConfigPassword) {
|
||||
$this->SetPassword($sPassword);
|
||||
return true;
|
||||
}
|
||||
return 0 < \strlen($sPassword) && \password_verify($sPassword, $sConfigPassword);
|
||||
}
|
||||
|
||||
public function Save() : bool
|
||||
{
|
||||
$this->Set('version', 'current', APP_VERSION);
|
||||
$this->Set('version', 'saved', \gmdate('r'));
|
||||
|
||||
return parent::Save();
|
||||
}
|
||||
|
||||
protected function defaultValues() : array
|
||||
{
|
||||
return array(
|
||||
|
||||
'webmail' => array(
|
||||
|
||||
'title' => array('RainLoop Webmail', 'Text displayed as page title'),
|
||||
'loading_description' => array('RainLoop', 'Text displayed on startup'),
|
||||
'favicon_url' => array('', ''),
|
||||
|
||||
'theme' => array('Default', 'Theme used by default'),
|
||||
'allow_themes' => array(true, 'Allow theme selection on settings screen'),
|
||||
'allow_user_background' => array(false),
|
||||
|
||||
'language' => array('en', 'Language used by default'),
|
||||
'language_admin' => array('en', 'Admin Panel interface language'),
|
||||
'allow_languages_on_settings' => array(true, 'Allow language selection on settings screen'),
|
||||
|
||||
'allow_additional_accounts' => array(true, ''),
|
||||
'allow_additional_identities' => array(true, ''),
|
||||
|
||||
'messages_per_page' => array(20, ' Number of messages displayed on page by default'),
|
||||
|
||||
'attachment_size_limit' => array(25,
|
||||
'File size limit (MB) for file upload on compose screen
|
||||
0 for unlimited.')
|
||||
),
|
||||
|
||||
'interface' => array(
|
||||
'show_attachment_thumbnail' => array(true, ''),
|
||||
'use_native_scrollbars' => array(false),
|
||||
'new_move_to_folder_button' => array(true)
|
||||
),
|
||||
|
||||
'branding' => array(
|
||||
'login_logo' => array(''),
|
||||
'login_background' => array(''),
|
||||
'login_desc' => array(''),
|
||||
'login_css' => array(''),
|
||||
|
||||
'user_css' => array(''),
|
||||
'user_logo' => array(''),
|
||||
'user_logo_title' => array(''),
|
||||
'user_logo_message' => array(''),
|
||||
'user_iframe_message' => array(''),
|
||||
|
||||
'welcome_page_url' => array(''),
|
||||
'welcome_page_display' => array('none')
|
||||
),
|
||||
|
||||
'contacts' => array(
|
||||
'enable' => array(false, 'Enable contacts'),
|
||||
'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(''),
|
||||
'x_xss_protection_header' => array('1; mode=block'),
|
||||
|
||||
'openpgp' => array(false),
|
||||
|
||||
'admin_login' => array('admin', 'Login and password for web admin panel'),
|
||||
'admin_password' => array(\password_hash('12345')),
|
||||
'allow_admin_panel' => array(true, 'Access settings'),
|
||||
'allow_two_factor_auth' => array(false),
|
||||
'force_two_factor_auth' => array(false),
|
||||
'hide_x_mailer_header' => array(false),
|
||||
'admin_panel_host' => array(''),
|
||||
'admin_panel_key' => array('admin'),
|
||||
'content_security_policy' => array(''),
|
||||
'core_install_access_domain' => array('')
|
||||
),
|
||||
|
||||
'ssl' => array(
|
||||
'verify_certificate' => array(false, 'Require verification of SSL certificate used.'),
|
||||
'allow_self_signed' => array(true, 'Allow self-signed certificates. Requires verify_certificate.'),
|
||||
'cafile' => array('', 'Location of Certificate Authority file on local filesystem (/etc/ssl/certs/ca-certificates.crt)'),
|
||||
'capath' => array('', 'capath must be a correctly hashed certificate directory. (/etc/ssl/certs/)'),
|
||||
'client_cert' => array('', 'Location of client certificate file (pem format with private key) on local filesystem'),
|
||||
),
|
||||
|
||||
'capa' => array(
|
||||
'folders' => array(true),
|
||||
'composer' => array(true),
|
||||
'contacts' => array(true),
|
||||
'settings' => array(true),
|
||||
'quota' => array(true),
|
||||
'help' => array(true),
|
||||
'reload' => array(true),
|
||||
'search' => array(true),
|
||||
'search_adv' => array(true),
|
||||
'filters' => array(true),
|
||||
'x-templates' => array(false),
|
||||
'dangerous_actions' => array(true),
|
||||
'message_actions' => array(true),
|
||||
'messagelist_actions' => array(true),
|
||||
'attachments_actions' => array(true)
|
||||
),
|
||||
|
||||
'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, ''),
|
||||
|
||||
'welcome_page' => array(false, ''),
|
||||
|
||||
'hide_submit_button' => array(true),
|
||||
|
||||
'forgot_password_link_url' => array('', ''),
|
||||
'registration_link_url' => array('', ''),
|
||||
|
||||
'login_lowercase' => array(true, ''),
|
||||
|
||||
'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'),
|
||||
),
|
||||
|
||||
'defaults' => array(
|
||||
'view_editor_type' => array('Html', 'Editor mode used by default (Plain, Html, HtmlForced or PlainForced)'),
|
||||
'view_layout' => array(1, 'layout: 0 - no preview, 1 - side preview, 2 - bottom preview'),
|
||||
'view_use_checkboxes' => array(true),
|
||||
'autologout' => array(30),
|
||||
'show_images' => array(false),
|
||||
'contacts_autosave' => array(true),
|
||||
'mail_use_threads' => array(false),
|
||||
'allow_draft_autosave' => array(true),
|
||||
'mail_reply_same_folder' => array(false)
|
||||
),
|
||||
|
||||
'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.'),
|
||||
|
||||
'time_offset' => array('0'),
|
||||
'session_filter' => array(''),
|
||||
|
||||
'sentry_dsn' => array(''),
|
||||
|
||||
'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}
|
||||
{request:ip} - Replaced by user\'s IP address
|
||||
|
||||
Others:
|
||||
{imap:login} {imap:host} {imap:port}
|
||||
{smtp:login} {smtp:host} {smtp:port}
|
||||
|
||||
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"'),
|
||||
|
||||
'auth_logging' => array(false, 'Enable auth logging in a separate file (for fail2ban)'),
|
||||
'auth_logging_filename' => array('fail2ban/auth-{date:Y-m-d}.txt'),
|
||||
'auth_logging_format' => array('[{date:Y-m-d H:i:s}] Auth failed: ip={request:ip} user={imap:login} host={imap:host} port={imap:port}')
|
||||
),
|
||||
|
||||
'debug' => array(
|
||||
'enable' => array(false, 'Special option required for development purposes')
|
||||
),
|
||||
|
||||
'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, redis (beta)'),
|
||||
'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'),
|
||||
'http_expires' => array(3600, 'Browser-level cache time (seconds, Expires header)'),
|
||||
|
||||
'server_uids' => array(true, 'Caching message UIDs when searching and sorting (threading)')
|
||||
),
|
||||
|
||||
'labs' => array(
|
||||
'allow_mobile_version' => array(true,
|
||||
'Experimental settings. Handle with care.
|
||||
'),
|
||||
'ignore_folders_subscription' => array(false),
|
||||
'check_new_password_strength' => array(true),
|
||||
'update_channel' => array('stable'),
|
||||
'allow_prefetch' => array(true),
|
||||
'allow_smart_html_links' => array(true),
|
||||
'cache_system_data' => array(true),
|
||||
'date_from_headers' => array(true),
|
||||
'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),
|
||||
'allow_html_editor_biti_buttons' => array(false),
|
||||
'allow_ctrl_enter_on_compose' => array(true),
|
||||
'try_to_detect_hidden_images' => array(false),
|
||||
'hide_dangerous_actions' => array(false),
|
||||
'use_app_debug_js' => array(false),
|
||||
'use_mobile_version_for_tablets' => array(false),
|
||||
'use_app_debug_css' => array(false),
|
||||
'use_imap_sort' => array(true),
|
||||
'use_imap_force_selection' => array(false),
|
||||
'use_imap_list_subscribe' => array(true),
|
||||
'use_imap_thread' => array(true),
|
||||
'use_imap_move' => 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_message_list_permanent_filter' => array(''),
|
||||
'imap_message_all_headers' => array(false),
|
||||
'imap_large_thread_limit' => array(50),
|
||||
'imap_folder_list_limit' => array(200),
|
||||
'imap_show_login_alert' => array(true),
|
||||
'imap_use_auth_plain' => array(true),
|
||||
'imap_use_auth_cram_md5' => array(false),
|
||||
'smtp_show_server_errors' => array(false),
|
||||
'smtp_use_auth_plain' => array(true),
|
||||
'smtp_use_auth_cram_md5' => array(false),
|
||||
'sieve_allow_raw_script' => array(false),
|
||||
'sieve_utf8_folder_name' => array(true),
|
||||
'sieve_auth_plain_initial' => array(true),
|
||||
'sieve_allow_fileinto_inbox' => array(false),
|
||||
'imap_timeout' => array(300),
|
||||
'smtp_timeout' => array(60),
|
||||
'sieve_timeout' => array(10),
|
||||
'domain_list_limit' => array(99),
|
||||
'mail_func_clear_headers' => array(true),
|
||||
'mail_func_additional_parameters' => array(false),
|
||||
'favicon_status' => array(true),
|
||||
'folders_spec_limit' => array(50),
|
||||
'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(''),
|
||||
'http_client_ip_check_proxy' => array(false),
|
||||
'fast_cache_memcache_host' => array('127.0.0.1'),
|
||||
'fast_cache_memcache_port' => array(11211),
|
||||
'fast_cache_redis_host' => array('127.0.0.1'),
|
||||
'fast_cache_redis_port' => array(6379),
|
||||
'use_local_proxy_for_external_images' => array(false),
|
||||
'detect_image_exif_orientation' => array(true),
|
||||
'cookie_default_path' => array(''),
|
||||
'cookie_default_secure' => array(false),
|
||||
'check_new_messages' => array(true),
|
||||
'replace_env_in_configuration' => array(''),
|
||||
'startup_url' => array(''),
|
||||
'strict_html_parser' => array(false),
|
||||
'allow_cmd' => array(false),
|
||||
'dev_email' => array(''),
|
||||
'dev_password' => array('')
|
||||
),
|
||||
|
||||
'version' => array(
|
||||
'current' => array(''),
|
||||
'saved' => array('')
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,21 +9,14 @@ class Plugin extends \RainLoop\Config\AbstractConfig
|
|||
*/
|
||||
private $aMap;
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($sPluginName, $aMap = array())
|
||||
public function __construct(string $sPluginName, array $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)
|
||||
private function convertConfigMap(array $aMap) : array
|
||||
{
|
||||
if (0 < \count($aMap))
|
||||
{
|
||||
|
|
@ -49,11 +42,8 @@ class Plugin extends \RainLoop\Config\AbstractConfig
|
|||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
protected function defaultValues()
|
||||
protected function defaultValues() : array
|
||||
{
|
||||
return $this->aMap;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@ class Capa
|
|||
const TWO_FACTOR_FORCE = 'TWO_FACTOR_FORCE';
|
||||
const OPEN_PGP = 'OPEN_PGP';
|
||||
const PREFETCH = 'PREFETCH';
|
||||
const GRAVATAR = 'GRAVATAR';
|
||||
const THEMES = 'THEMES';
|
||||
const USER_BACKGROUND = 'USER_BACKGROUND';
|
||||
const SIEVE = 'SIEVE';
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ namespace RainLoop\Exceptions;
|
|||
class ClientException extends Exception
|
||||
{
|
||||
/**
|
||||
* @var boolen
|
||||
* @var bool
|
||||
*/
|
||||
private $bLogoutOnException;
|
||||
|
||||
|
|
@ -18,13 +18,7 @@ class ClientException extends Exception
|
|||
*/
|
||||
private $sAdditionalMessage;
|
||||
|
||||
/**
|
||||
* @param int $iCode
|
||||
* @param \Exception $oPrevious = null
|
||||
* @param string $sAdditionalMessage = ''
|
||||
* @param boolean $bLogoutOnException = false
|
||||
*/
|
||||
public function __construct($iCode, $oPrevious = null, $sAdditionalMessage = '', $bLogoutOnException = false)
|
||||
public function __construct(int $iCode, ?\Exception $oPrevious = null, string $sAdditionalMessage = '', bool $bLogoutOnException = false)
|
||||
{
|
||||
parent::__construct(\RainLoop\Notifications::GetNotificationsMessage($iCode, $oPrevious),
|
||||
$iCode, $oPrevious);
|
||||
|
|
@ -34,29 +28,17 @@ class ClientException extends Exception
|
|||
$this->setLogoutOnException($bLogoutOnException);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getAdditionalMessage()
|
||||
public function getAdditionalMessage() : string
|
||||
{
|
||||
return $this->sAdditionalMessage;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return boolen
|
||||
*/
|
||||
public function getLogoutOnException()
|
||||
public function getLogoutOnException() : bool
|
||||
{
|
||||
return $this->bLogoutOnException;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param boolean $bLogoutOnException
|
||||
* @param string $sAdditionalLogoutMessage = ''
|
||||
*
|
||||
* @return ClientException
|
||||
*/
|
||||
public function setLogoutOnException($bLogoutOnException, $sAdditionalLogoutMessage = '')
|
||||
public function setLogoutOnException(bool $bLogoutOnException, string $sAdditionalLogoutMessage = '') : self
|
||||
{
|
||||
$this->bLogoutOnException = !!$bLogoutOnException;
|
||||
|
||||
|
|
|
|||
|
|
@ -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 {}
|
||||
|
|
@ -4,140 +4,57 @@ namespace RainLoop;
|
|||
|
||||
class KeyPathHelper
|
||||
{
|
||||
/**
|
||||
* @param string $sHash
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
static public function PublicFile($sHash)
|
||||
static public function PublicFile(string $sHash) : string
|
||||
{
|
||||
return '/Public/Files/'.sha1($sHash).'/Data/';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sSsoHash
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
static public function SsoCacherKey($sSsoHash)
|
||||
static public function SsoCacherKey(string $sSsoHash) : string
|
||||
{
|
||||
return '/Sso/Data/'.$sSsoHash.'/Login/';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sHash
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
static public function RsaCacherKey($sHash)
|
||||
static public function RsaCacherKey(string $sHash) : string
|
||||
{
|
||||
return '/Rsa/Data/'.$sHash.'/';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sDomain
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
static public function LicensingDomainKeyValue($sDomain)
|
||||
{
|
||||
return '/Licensing/DomainKey/Value/'.$sDomain;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sDomain
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
static public function LicensingDomainKeyOtherValue($sDomain)
|
||||
{
|
||||
return '/Licensing/DomainKeyOther/Value/'.$sDomain;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sRepo
|
||||
* @param string $sRepoFile
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
static public function RepositoryCacheFile($sRepo, $sRepoFile)
|
||||
static public function RepositoryCacheFile(string $sRepo, string $sRepoFile) : string
|
||||
{
|
||||
return '/RepositoryCache/Repo/'.$sRepo.'/File/'.$sRepoFile;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sRepo
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
static public function RepositoryCacheCore($sRepo)
|
||||
static public function RepositoryCacheCore(string $sRepo) : string
|
||||
{
|
||||
return '/RepositoryCache/CoreRepo/'.$sRepo;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sEmail
|
||||
* @param string $sFolderFullName
|
||||
* @param string $sUid
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
static public function ReadReceiptCache($sEmail, $sFolderFullName, $sUid)
|
||||
static public function ReadReceiptCache(string $sEmail, string $sFolderFullName, string $sUid) : string
|
||||
{
|
||||
return '/ReadReceipt/'.$sEmail.'/'.$sFolderFullName.'/'.$sUid;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sLanguage
|
||||
* @param bool $bAdmim
|
||||
* @param string $sPluginsHash
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
static public function LangCache($sLanguage, $bAdmim, $sPluginsHash)
|
||||
static public function LangCache(string $sLanguage, bool $bAdmim, string $sPluginsHash) : string
|
||||
{
|
||||
return '/LangCache/'.$sPluginsHash.'/'.$sLanguage.'/'.($bAdmim ? 'Admin' : 'App').'/'.APP_VERSION.'/';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $bAdmin
|
||||
* @param string $sPluginsHash
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
static public function TemplatesCache($bAdmin, $sPluginsHash)
|
||||
static public function TemplatesCache(bool $bAdmin, string $sPluginsHash) : string
|
||||
{
|
||||
return '/TemplatesCache/'.$sPluginsHash.'/'.($bAdmin ? 'Admin' : 'App').'/'.APP_VERSION.'/';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sPluginsHash
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
static public function PluginsJsCache($sPluginsHash)
|
||||
static public function PluginsJsCache(string $sPluginsHash) : string
|
||||
{
|
||||
return '/PluginsJsCache/'.$sPluginsHash.'/'.APP_VERSION.'/';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sTheme
|
||||
* @param string $sHash
|
||||
* @param string $sPublickHash
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
static public function CssCache($sTheme, $sHash)
|
||||
static public function CssCache(string $sTheme, string $sHash) : string
|
||||
{
|
||||
return '/CssCache/'.$sHash.'/'.$sTheme.'/'.APP_VERSION.'/';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sRand
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
static public function SessionAdminKey($sRand)
|
||||
static public function SessionAdminKey(string $sRand) : string
|
||||
{
|
||||
return '/Session/AdminKey/'.\md5($sRand).'/';
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -98,29 +98,11 @@ class Domain
|
|||
*/
|
||||
private $sAliasName;
|
||||
|
||||
/**
|
||||
* @param string $sName
|
||||
* @param string $sIncHost
|
||||
* @param int $iIncPort
|
||||
* @param int $iIncSecure
|
||||
* @param bool $bIncShortLogin
|
||||
* @param bool $bUseSieve
|
||||
* @param string $sSieveHost
|
||||
* @param int $iSievePort
|
||||
* @param int $iSieveSecure
|
||||
* @param string $sOutHost
|
||||
* @param int $iOutPort
|
||||
* @param int $iOutSecure
|
||||
* @param bool $bOutShortLogin
|
||||
* @param bool $bOutAuth
|
||||
* @param bool $bOutUsePhpMail = false
|
||||
* @param string $sWhiteList = ''
|
||||
*/
|
||||
private function __construct($sName,
|
||||
$sIncHost, $iIncPort, $iIncSecure, $bIncShortLogin,
|
||||
$bUseSieve, $sSieveHost, $iSievePort, $iSieveSecure,
|
||||
$sOutHost, $iOutPort, $iOutSecure, $bOutShortLogin, $bOutAuth, $bOutUsePhpMail = false,
|
||||
$sWhiteList = '')
|
||||
private function __construct(string $sName,
|
||||
string $sIncHost, int $iIncPort, int $iIncSecure, bool $bIncShortLogin,
|
||||
bool $bUseSieve, string $sSieveHost, int $iSievePort, int $iSieveSecure,
|
||||
string $sOutHost, int $iOutPort, int $iOutSecure, bool $bOutShortLogin,
|
||||
bool $bOutAuth, bool $bOutUsePhpMail = false, string $sWhiteList = '')
|
||||
{
|
||||
$this->sName = $sName;
|
||||
$this->sIncHost = $sIncHost;
|
||||
|
|
@ -146,31 +128,11 @@ class Domain
|
|||
$this->sAliasName = '';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sName
|
||||
* @param string $sIncHost
|
||||
* @param int $iIncPort
|
||||
* @param int $iIncSecure
|
||||
* @param bool $bIncShortLogin
|
||||
* @param bool $bUseSieve
|
||||
* @param string $sSieveHost
|
||||
* @param int $iSievePort
|
||||
* @param int $iSieveSecure
|
||||
* @param string $sOutHost
|
||||
* @param int $iOutPort
|
||||
* @param int $iOutSecure
|
||||
* @param bool $bOutShortLogin
|
||||
* @param bool $bOutAuth
|
||||
* @param bool $bOutUsePhpMail = false
|
||||
* @param string $sWhiteList = ''
|
||||
*
|
||||
* @return \RainLoop\Model\Domain
|
||||
*/
|
||||
public static function NewInstance($sName,
|
||||
$sIncHost, $iIncPort, $iIncSecure, $bIncShortLogin,
|
||||
$bUseSieve, $sSieveHost, $iSievePort, $iSieveSecure,
|
||||
$sOutHost, $iOutPort, $iOutSecure, $bOutShortLogin, $bOutAuth, $bOutUsePhpMail,
|
||||
$sWhiteList = '')
|
||||
public static function NewInstance(string $sName,
|
||||
string $sIncHost, int $iIncPort, int $iIncSecure, bool $bIncShortLogin,
|
||||
bool $bUseSieve, string $sSieveHost, int $iSievePort, int $iSieveSecure,
|
||||
string $sOutHost, int $iOutPort, int $iOutSecure, bool $bOutShortLogin,
|
||||
bool $bOutAuth, bool $bOutUsePhpMail, string $sWhiteList = '') : self
|
||||
{
|
||||
return new self($sName,
|
||||
$sIncHost, $iIncPort, $iIncSecure, $bIncShortLogin,
|
||||
|
|
@ -185,7 +147,7 @@ class Domain
|
|||
*
|
||||
* @return \RainLoop\Model\Domain|null
|
||||
*/
|
||||
public static function NewInstanceFromDomainConfigArray($sName, $aDomain)
|
||||
public static function NewInstanceFromDomainConfigArray(string $sName, $aDomain)
|
||||
{
|
||||
$oDomain = null;
|
||||
|
||||
|
|
@ -196,8 +158,8 @@ class Domain
|
|||
$iIncSecure = self::StrConnectionSecurityTypeToCons(
|
||||
!empty($aDomain['imap_secure']) ? $aDomain['imap_secure'] : '');
|
||||
|
||||
$bUseSieve = isset($aDomain['sieve_use']) ? (bool) $aDomain['sieve_use'] : false;
|
||||
$bSieveAllowRaw = isset($aDomain['sieve_allow_raw']) ? (bool) $aDomain['sieve_allow_raw'] : false;
|
||||
$bUseSieve = !empty($aDomain['sieve_use']);
|
||||
$bSieveAllowRaw = !empty($aDomain['sieve_allow_raw']);
|
||||
|
||||
$sSieveHost = empty($aDomain['sieve_host']) ? '' : (string) $aDomain['sieve_host'];
|
||||
$iSievePort = empty($aDomain['sieve_port']) ? 4190 : (int) $aDomain['sieve_port'];
|
||||
|
|
@ -209,12 +171,12 @@ class Domain
|
|||
$iOutSecure = self::StrConnectionSecurityTypeToCons(
|
||||
!empty($aDomain['smtp_secure']) ? $aDomain['smtp_secure'] : '');
|
||||
|
||||
$bOutAuth = isset($aDomain['smtp_auth']) ? (bool) $aDomain['smtp_auth'] : true;
|
||||
$bOutUsePhpMail = isset($aDomain['smtp_php_mail']) ? (bool) $aDomain['smtp_php_mail'] : false;
|
||||
$sWhiteList = (string) (isset($aDomain['white_list']) ? $aDomain['white_list'] : '');
|
||||
$bOutAuth = !empty($aDomain['smtp_auth']);
|
||||
$bOutUsePhpMail = !empty($aDomain['smtp_php_mail']);
|
||||
$sWhiteList = (string) ($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;
|
||||
$bIncShortLogin = !empty($aDomain['imap_short_login']);
|
||||
$bOutShortLogin = !empty($aDomain['smtp_short_login']);
|
||||
|
||||
$oDomain = self::NewInstance($sName,
|
||||
$sIncHost, $iIncPort, $iIncSecure, $bIncShortLogin,
|
||||
|
|
@ -228,12 +190,7 @@ class Domain
|
|||
return $oDomain;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sStr
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function encodeIniString($sStr)
|
||||
private function encodeIniString(string $sStr) : string
|
||||
{
|
||||
return str_replace('"', '\\"', $sStr);
|
||||
}
|
||||
|
|
@ -261,10 +218,7 @@ class Domain
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function ToIniString()
|
||||
public function ToIniString() : string
|
||||
{
|
||||
$this->Normalize();
|
||||
return \implode("\n", array(
|
||||
|
|
@ -287,12 +241,7 @@ class Domain
|
|||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sType
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public static function StrConnectionSecurityTypeToCons($sType)
|
||||
public static function StrConnectionSecurityTypeToCons(string $sType) : int
|
||||
{
|
||||
$iSecurityType = ConnectionSecurityType::NONE;
|
||||
switch (strtoupper($sType))
|
||||
|
|
@ -307,12 +256,7 @@ class Domain
|
|||
return $iSecurityType;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $iSecurityType
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function ConstConnectionSecurityTypeToStr($iSecurityType)
|
||||
public static function ConstConnectionSecurityTypeToStr(int $iSecurityType) : string
|
||||
{
|
||||
$sType = 'None';
|
||||
switch ($iSecurityType)
|
||||
|
|
@ -328,27 +272,11 @@ class Domain
|
|||
return $sType;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sIncHost
|
||||
* @param int $iIncPort
|
||||
* @param int $iIncSecure
|
||||
* @param bool $bIncShortLogin
|
||||
* @param bool $bUseSieve
|
||||
* @param string $sOutHost
|
||||
* @param int $iOutPort
|
||||
* @param int $iOutSecure
|
||||
* @param bool $bOutShortLogin
|
||||
* @param bool $bOutAuth
|
||||
* @param bool $bOutUsePhpMail = false
|
||||
* @param string $sWhiteList = ''
|
||||
*
|
||||
* @return \RainLoop\Model\Domain
|
||||
*/
|
||||
public function UpdateInstance(
|
||||
$sIncHost, $iIncPort, $iIncSecure, $bIncShortLogin,
|
||||
$bUseSieve, $sSieveHost, $iSievePort, $iSieveSecure,
|
||||
$sOutHost, $iOutPort, $iOutSecure, $bOutShortLogin, $bOutAuth, $bOutUsePhpMail,
|
||||
$sWhiteList = '')
|
||||
string $sIncHost, int $iIncPort, int $iIncSecure, bool $bIncShortLogin,
|
||||
bool $bUseSieve, string $sSieveHost, int $iSievePort, int $iSieveSecure,
|
||||
string $sOutHost, int $iOutPort, int $iOutSecure, bool $bOutShortLogin,
|
||||
bool $bOutAuth, bool $bOutUsePhpMail, string $sWhiteList = '') : self
|
||||
{
|
||||
$this->sIncHost = \MailSo\Base\Utils::IdnToAscii($sIncHost);
|
||||
$this->iIncPort = $iIncPort;
|
||||
|
|
@ -372,176 +300,109 @@ class Domain
|
|||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function Name()
|
||||
public function Name() : string
|
||||
{
|
||||
return $this->sName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function IncHost()
|
||||
public function IncHost() : string
|
||||
{
|
||||
return $this->sIncHost;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function IncPort()
|
||||
public function IncPort() : int
|
||||
{
|
||||
return $this->iIncPort;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function IncSecure()
|
||||
public function IncSecure() : int
|
||||
{
|
||||
return $this->iIncSecure;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function IncShortLogin()
|
||||
public function IncShortLogin() : bool
|
||||
{
|
||||
return $this->bIncShortLogin;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function UseSieve()
|
||||
public function UseSieve() : bool
|
||||
{
|
||||
return $this->bUseSieve;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function SieveHost()
|
||||
public function SieveHost() : string
|
||||
{
|
||||
return $this->sSieveHost;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function SievePort()
|
||||
public function SievePort() : int
|
||||
{
|
||||
return $this->iSievePort;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function SieveSecure()
|
||||
public function SieveSecure() : int
|
||||
{
|
||||
return $this->iSieveSecure;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function SieveAllowRaw()
|
||||
public function SieveAllowRaw() : bool
|
||||
{
|
||||
return $this->bSieveAllowRaw;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $bSieveAllowRaw
|
||||
*/
|
||||
public function SetSieveAllowRaw($bSieveAllowRaw)
|
||||
public function SetSieveAllowRaw(bool $bSieveAllowRaw)
|
||||
{
|
||||
$this->bSieveAllowRaw = !!$bSieveAllowRaw;
|
||||
$this->bSieveAllowRaw = $bSieveAllowRaw;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function OutHost()
|
||||
public function OutHost() : string
|
||||
{
|
||||
return $this->sOutHost;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function OutPort()
|
||||
public function OutPort() : int
|
||||
{
|
||||
return $this->iOutPort;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function OutSecure()
|
||||
public function OutSecure() : int
|
||||
{
|
||||
return $this->iOutSecure;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function OutShortLogin()
|
||||
public function OutShortLogin() : bool
|
||||
{
|
||||
return $this->bOutShortLogin;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function OutAuth()
|
||||
public function OutAuth() : bool
|
||||
{
|
||||
return $this->bOutAuth;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function OutUsePhpMail()
|
||||
public function OutUsePhpMail() : bool
|
||||
{
|
||||
return $this->bOutUsePhpMail;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function WhiteList()
|
||||
public function WhiteList() : string
|
||||
{
|
||||
return $this->sWhiteList;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function AliasName()
|
||||
public function AliasName() : string
|
||||
{
|
||||
return $this->sAliasName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sAliasName
|
||||
* @return self
|
||||
*/
|
||||
public function SetAliasName($sAliasName)
|
||||
public function SetAliasName(string $sAliasName) : self
|
||||
{
|
||||
$this->sAliasName = $sAliasName;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sEmail
|
||||
* @param string $sLogin = ''
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function ValidateWhiteList($sEmail, $sLogin = '')
|
||||
public function ValidateWhiteList(string $sEmail, string $sLogin = '') : bool
|
||||
{
|
||||
$sW = \trim($this->sWhiteList);
|
||||
if (0 < strlen($sW))
|
||||
|
|
@ -559,12 +420,7 @@ class Domain
|
|||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $bAjax = false
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function ToSimpleJSON($bAjax = false)
|
||||
public function ToSimpleJSON(bool $bAjax = false) : array
|
||||
{
|
||||
return array(
|
||||
'Name' => $bAjax ? \MailSo\Base\Utils::IdnToUtf8($this->Name()) : $this->Name(),
|
||||
|
|
|
|||
|
|
@ -40,12 +40,9 @@ class Identity
|
|||
private $bSignatureInsertBefore;
|
||||
|
||||
/**
|
||||
* @param string $sId = ''
|
||||
* @param string $sEmail = ''
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function __construct($sId = '', $sEmail = '')
|
||||
protected function __construct(string $sId = '', string $sEmail = '')
|
||||
{
|
||||
$this->sId = empty($sId) ? '' : $sId;
|
||||
$this->sEmail = empty($sEmail) ? '' : $sEmail;
|
||||
|
|
@ -56,101 +53,59 @@ class Identity
|
|||
$this->bSignatureInsertBefore = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \RainLoop\Model\Identity
|
||||
*/
|
||||
public static function NewInstance()
|
||||
public static function NewInstance() : self
|
||||
{
|
||||
return new self();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \RainLoop\Model\Account $oAccount
|
||||
*
|
||||
* @return \RainLoop\Model\Identity
|
||||
*/
|
||||
public static function NewInstanceFromAccount(\RainLoop\Model\Account $oAccount)
|
||||
public static function NewInstanceFromAccount(\RainLoop\Model\Account $oAccount) : self
|
||||
{
|
||||
return new self('', $oAccount->Email());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $bFillOnEmpty = false
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function Id($bFillOnEmpty = false)
|
||||
public function Id(bool $bFillOnEmpty = false) : string
|
||||
{
|
||||
return $bFillOnEmpty ? ('' === $this->sId ? '---' : $this->sId) : $this->sId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function Email()
|
||||
public function Email() : string
|
||||
{
|
||||
return $this->sEmail;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sEmail
|
||||
*
|
||||
* @return \RainLoop\Model\Identity
|
||||
*/
|
||||
public function SetEmail($sEmail)
|
||||
public function SetEmail(string $sEmail) : self
|
||||
{
|
||||
$this->sEmail = $sEmail;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function Name()
|
||||
public function Name() : string
|
||||
{
|
||||
return $this->sName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function ReplyTo()
|
||||
public function ReplyTo() : string
|
||||
{
|
||||
return $this->sReplyTo;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function Bcc()
|
||||
public function Bcc() : string
|
||||
{
|
||||
return $this->sBcc;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function Signature()
|
||||
public function Signature() : string
|
||||
{
|
||||
return $this->sSignature;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function SignatureInsertBefore()
|
||||
public function SignatureInsertBefore() : bool
|
||||
{
|
||||
return $this->bSignatureInsertBefore;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $aData
|
||||
* @param bool $bAjax = false
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function FromJSON($aData, $bAjax = false)
|
||||
public function FromJSON(array $aData, bool $bAjax = false) : bool
|
||||
{
|
||||
if (!empty($aData['Email']))
|
||||
{
|
||||
|
|
@ -169,12 +124,7 @@ class Identity
|
|||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $bAjax = false
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function ToSimpleJSON($bAjax = false)
|
||||
public function ToSimpleJSON(bool $bAjax = false) : array
|
||||
{
|
||||
return array(
|
||||
'Id' => $this->Id(),
|
||||
|
|
@ -187,18 +137,12 @@ class Identity
|
|||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function Validate()
|
||||
public function Validate() : bool
|
||||
{
|
||||
return !empty($this->sEmail);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function IsAccountIdentities()
|
||||
public function IsAccountIdentities() : bool
|
||||
{
|
||||
return '' === $this->Id();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,13 +25,9 @@ class Template
|
|||
private $bPopulateAlways;
|
||||
|
||||
/**
|
||||
* @param string $sId = ''
|
||||
* @param string $sName = ''
|
||||
* @param string $sBody = ''
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function __construct($sId = '', $sName = '', $sBody = '')
|
||||
protected function __construct(string $sId = '', string $sName = '', string $sBody = '')
|
||||
{
|
||||
$this->sId = $sId;
|
||||
$this->sName = $sName;
|
||||
|
|
@ -39,57 +35,32 @@ class Template
|
|||
$this->bPopulateAlways = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sId = ''
|
||||
* @param string $sName = ''
|
||||
* @param string $sBody = ''
|
||||
*
|
||||
* @return \RainLoop\Model\Template
|
||||
*/
|
||||
public static function NewInstance($sId = '', $sName = '', $sBody = '')
|
||||
public static function NewInstance(string $sId = '', string $sName = '', string $sBody = '') : self
|
||||
{
|
||||
return new self($sId, $sBody);
|
||||
return new self($sId, $sName, $sBody);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function Id()
|
||||
public function Id() : string
|
||||
{
|
||||
return $this->sId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function Name()
|
||||
public function Name() : string
|
||||
{
|
||||
return $this->sName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function Body()
|
||||
public function Body() : string
|
||||
{
|
||||
return $this->sBody;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $bPopulateAlways
|
||||
*/
|
||||
public function SetPopulateAlways($bPopulateAlways)
|
||||
public function SetPopulateAlways(bool $bPopulateAlways)
|
||||
{
|
||||
$this->bPopulateAlways = !!$bPopulateAlways;
|
||||
$this->bPopulateAlways = $bPopulateAlways;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $aData
|
||||
* @param bool $bAjax = false
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function FromJSON($aData, $bAjax = false)
|
||||
public function FromJSON(array $aData, bool $bAjax = false) : bool
|
||||
{
|
||||
if (isset($aData['ID'], $aData['Name'], $aData['Body']))
|
||||
{
|
||||
|
|
@ -103,12 +74,7 @@ class Template
|
|||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $bAjax = false
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function ToSimpleJSON($bAjax = false)
|
||||
public function ToSimpleJSON(bool $bAjax = false) : array
|
||||
{
|
||||
$sBody = $this->Body();
|
||||
$bPopulated = true;
|
||||
|
|
@ -136,18 +102,12 @@ class Template
|
|||
return $aResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function GenerateID()
|
||||
public function GenerateID() : bool
|
||||
{
|
||||
return $this->sId = \MailSo\Base\Utils::Md5Rand();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function Validate()
|
||||
public function Validate() : bool
|
||||
{
|
||||
return 0 < \strlen($this->sBody);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -75,13 +75,8 @@ class Notifications
|
|||
|
||||
/**
|
||||
* @staticvar array $aMap
|
||||
*
|
||||
* @param int $iCode
|
||||
* @param \Exception|null $oPrevious
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
static public function GetNotificationsMessage($iCode, $oPrevious = null)
|
||||
static public function GetNotificationsMessage(int $iCode, ?\Exception $oPrevious = null) : string
|
||||
{
|
||||
static $aMap = array(
|
||||
self::InvalidToken => 'InvalidToken',
|
||||
|
|
@ -150,4 +145,4 @@ class Notifications
|
|||
|
||||
return isset($aMap[$iCode]) ? $aMap[$iCode].'['.$iCode.']' : 'UnknownNotification['.$iCode.']';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -85,73 +85,50 @@ abstract class AbstractPlugin
|
|||
return $this->oPluginManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function Path()
|
||||
public function Path() : string
|
||||
{
|
||||
return $this->sPath;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function Name()
|
||||
public function Name() : string
|
||||
{
|
||||
return $this->sName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function Version()
|
||||
public function Version() : string
|
||||
{
|
||||
return $this->sVersion;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool | null $bLangs = null
|
||||
* @return bool
|
||||
*/
|
||||
public function UseLangs($bLangs = null)
|
||||
public function UseLangs(?bool $bLangs = null) : bool
|
||||
{
|
||||
if (null !== $bLangs)
|
||||
{
|
||||
$this->bLangs = (bool) $bLangs;
|
||||
$this->bLangs = $bLangs;
|
||||
}
|
||||
|
||||
return $this->bLangs;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
protected function configMapping()
|
||||
protected function configMapping() : array
|
||||
{
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function Hash()
|
||||
public function Hash() : string
|
||||
{
|
||||
return \md5($this->sName.'@'.$this->sVersion);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function Supported()
|
||||
public function Supported() : string
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* @final
|
||||
* @return array
|
||||
*/
|
||||
final public function ConfigMap()
|
||||
final public function ConfigMap() : array
|
||||
{
|
||||
if (null === $this->aConfigMap)
|
||||
{
|
||||
|
|
@ -165,36 +142,21 @@ abstract class AbstractPlugin
|
|||
return $this->aConfigMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sPath
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function SetPath($sPath)
|
||||
public function SetPath(string $sPath) : self
|
||||
{
|
||||
$this->sPath = $sPath;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sName
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function SetName($sName)
|
||||
public function SetName(string $sName) : self
|
||||
{
|
||||
$this->sName = $sName;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sVersion
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function SetVersion($sVersion)
|
||||
public function SetVersion(string $sVersion) : self
|
||||
{
|
||||
if (0 < \strlen($sVersion))
|
||||
{
|
||||
|
|
@ -204,24 +166,14 @@ abstract class AbstractPlugin
|
|||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \RainLoop\Plugins\Manager $oPluginManager
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function SetPluginManager(\RainLoop\Plugins\Manager $oPluginManager)
|
||||
public function SetPluginManager(\RainLoop\Plugins\Manager $oPluginManager) : self
|
||||
{
|
||||
$this->oPluginManager = $oPluginManager;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \RainLoop\Config\Plugin $oPluginConfig
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function SetPluginConfig(\RainLoop\Config\Plugin $oPluginConfig)
|
||||
public function SetPluginConfig(\RainLoop\Config\Plugin $oPluginConfig) : self
|
||||
{
|
||||
$this->oPluginConfig = $oPluginConfig;
|
||||
|
||||
|
|
@ -245,24 +197,14 @@ abstract class AbstractPlugin
|
|||
}
|
||||
|
||||
/**
|
||||
* @param bool $bAdmin
|
||||
* @param bool $bAuth
|
||||
* @param array $aConfig
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function FilterAppDataPluginSection($bAdmin, $bAuth, &$aConfig)
|
||||
public function FilterAppDataPluginSection(bool $bAdmin, bool $bAuth, array &$aConfig)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sHookName
|
||||
* @param string $sFunctionName
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
protected function addHook($sHookName, $sFunctionName)
|
||||
protected function addHook(string $sHookName, string $sFunctionName) : self
|
||||
{
|
||||
if ($this->oPluginManager)
|
||||
{
|
||||
|
|
@ -272,13 +214,7 @@ abstract class AbstractPlugin
|
|||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sFile
|
||||
* @param bool $bAdminScope = false
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
protected function addJs($sFile, $bAdminScope = false)
|
||||
protected function addJs(string $sFile, bool $bAdminScope = false) : self
|
||||
{
|
||||
if ($this->oPluginManager)
|
||||
{
|
||||
|
|
@ -288,13 +224,7 @@ abstract class AbstractPlugin
|
|||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sFile
|
||||
* @param bool $bAdminScope = false
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
protected function addTemplate($sFile, $bAdminScope = false)
|
||||
protected function addTemplate(string $sFile, bool $bAdminScope = false) : self
|
||||
{
|
||||
if ($this->oPluginManager)
|
||||
{
|
||||
|
|
@ -304,13 +234,7 @@ abstract class AbstractPlugin
|
|||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sFile
|
||||
* @param bool $bAdminScope = false
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
protected function replaceTemplate($sFile, $bAdminScope = false)
|
||||
protected function replaceTemplate(string $sFile, bool $bAdminScope = false) : self
|
||||
{
|
||||
if ($this->oPluginManager)
|
||||
{
|
||||
|
|
@ -320,13 +244,7 @@ abstract class AbstractPlugin
|
|||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sActionName
|
||||
* @param string $sFunctionName
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
protected function addPartHook($sActionName, $sFunctionName)
|
||||
protected function addPartHook(string $sActionName, string $sFunctionName) : self
|
||||
{
|
||||
if ($this->oPluginManager)
|
||||
{
|
||||
|
|
@ -336,13 +254,7 @@ abstract class AbstractPlugin
|
|||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sActionName
|
||||
* @param string $sFunctionName
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
protected function addAjaxHook($sActionName, $sFunctionName)
|
||||
protected function addAjaxHook(string $sActionName, string $sFunctionName) : self
|
||||
{
|
||||
if ($this->oPluginManager)
|
||||
{
|
||||
|
|
@ -352,15 +264,7 @@ abstract class AbstractPlugin
|
|||
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)
|
||||
protected function addTemplateHook(string $sName, string $sPlace, string $sLocalTemplateName, bool $bPrepend = false) : self
|
||||
{
|
||||
if ($this->oPluginManager)
|
||||
{
|
||||
|
|
@ -371,15 +275,7 @@ abstract class AbstractPlugin
|
|||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sName
|
||||
* @param string $sPlace
|
||||
* @param string $sHtml
|
||||
* @param bool $bPrepend = false
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
protected function ajaxResponse($sFunctionName, $aData)
|
||||
protected function ajaxResponse(string $sFunctionName, array $aData) : self
|
||||
{
|
||||
if ($this->oPluginManager)
|
||||
{
|
||||
|
|
@ -391,12 +287,11 @@ abstract class AbstractPlugin
|
|||
}
|
||||
|
||||
/**
|
||||
* @param string $sKey
|
||||
* @param mixed $mDefault = null
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function ajaxParam($sKey, $mDefault = null)
|
||||
public function ajaxParam(string $sKey, $mDefault = null)
|
||||
{
|
||||
if ($this->oPluginManager)
|
||||
{
|
||||
|
|
@ -406,10 +301,7 @@ abstract class AbstractPlugin
|
|||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getUserSettings()
|
||||
public function getUserSettings() : array
|
||||
{
|
||||
if ($this->oPluginManager)
|
||||
{
|
||||
|
|
@ -419,12 +311,7 @@ abstract class AbstractPlugin
|
|||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $aSettings
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function saveUserSettings($aSettings)
|
||||
public function saveUserSettings(array $aSettings) : bool
|
||||
{
|
||||
if ($this->oPluginManager && \is_array($aSettings))
|
||||
{
|
||||
|
|
|
|||
|
|
@ -11,17 +11,10 @@ class Helper
|
|||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sString
|
||||
* @param string $sWildcardValues
|
||||
* @param string $sFoundedValue = ''
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
static public function ValidateWildcardValues($sString, $sWildcardValues, &$sFoundedValue = '')
|
||||
static public function ValidateWildcardValues(string $sString, string $sWildcardValues, string &$sFoundedValue) : bool
|
||||
{
|
||||
$sFoundedValue = '';
|
||||
|
||||
|
||||
$sString = \trim($sString);
|
||||
if ('' === $sString)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -64,9 +64,6 @@ class Manager
|
|||
*/
|
||||
private $oLogger;
|
||||
|
||||
/**
|
||||
* @param \RainLoop\Actions $oActions
|
||||
*/
|
||||
public function __construct(\RainLoop\Actions $oActions)
|
||||
{
|
||||
$this->oLogger = null;
|
||||
|
|
@ -112,12 +109,7 @@ class Manager
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sName
|
||||
*
|
||||
* @return \RainLoop\Plugins\AbstractPlugin|null
|
||||
*/
|
||||
public function CreatePluginByName($sName)
|
||||
public function CreatePluginByName(string $sName) : ?\RainLoop\Plugins\AbstractPlugin
|
||||
{
|
||||
$oPlugin = null;
|
||||
if (\preg_match('/^[a-z0-9\-]+$/', $sName) &&
|
||||
|
|
@ -154,10 +146,7 @@ class Manager
|
|||
return $oPlugin;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function InstalledPlugins()
|
||||
public function InstalledPlugins() : array
|
||||
{
|
||||
$aList = array();
|
||||
|
||||
|
|
@ -187,12 +176,7 @@ class Manager
|
|||
return $aList;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sFolderName
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function convertPluginFolderNameToClassName($sFolderName)
|
||||
public function convertPluginFolderNameToClassName(string $sFolderName) : string
|
||||
{
|
||||
$aParts = \array_map('ucfirst', \array_map('strtolower',
|
||||
\explode(' ', \preg_replace('/[^a-z0-9]+/', ' ', $sFolderName))));
|
||||
|
|
@ -200,18 +184,12 @@ class Manager
|
|||
return \implode($aParts).'Plugin';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \RainLoop\Actions
|
||||
*/
|
||||
public function Actions()
|
||||
public function Actions() : \RainLoop\Actions
|
||||
{
|
||||
return $this->oActions;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function Hash()
|
||||
public function Hash() : string
|
||||
{
|
||||
$sResult = \md5(APP_VERSION);
|
||||
foreach ($this->aPlugins as $oPlugin)
|
||||
|
|
@ -222,12 +200,7 @@ class Manager
|
|||
return $sResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $bAdminScope = false
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function HaveJs($bAdminScope = false)
|
||||
public function HaveJs(bool $bAdminScope = false) : bool
|
||||
{
|
||||
$bResult = false;
|
||||
|
||||
|
|
@ -239,12 +212,7 @@ class Manager
|
|||
return $bResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $bAdminScope = false
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function CompileJs($bAdminScope = false)
|
||||
public function CompileJs(bool $bAdminScope = false) : string
|
||||
{
|
||||
$aResult = array();
|
||||
if ($this->bIsEnabled)
|
||||
|
|
@ -264,21 +232,13 @@ class Manager
|
|||
|
||||
/**
|
||||
* @todo
|
||||
* @param bool $bAdminScope = false
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function CompileCss($bAdminScope = false)
|
||||
public function CompileCss(bool $bAdminScope = false) : string
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $aList
|
||||
* @param bool $bAdminScope = false
|
||||
* @return string
|
||||
*/
|
||||
public function CompileTemplate(&$aList, $bAdminScope = false)
|
||||
public function CompileTemplate(array &$aList, bool $bAdminScope = false) : string
|
||||
{
|
||||
if ($this->bIsEnabled)
|
||||
{
|
||||
|
|
@ -294,14 +254,7 @@ class Manager
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $bAdmin
|
||||
* @param array $aAppData
|
||||
* @param \RainLoop\Model\Account|null $oAccount = null
|
||||
*
|
||||
* @return \RainLoop\Plugins\Manager
|
||||
*/
|
||||
public function InitAppData($bAdmin, &$aAppData, $oAccount = null)
|
||||
public function InitAppData(bool $bAdmin, array &$aAppData, ?\RainLoop\Model\Account $oAccount = null) : self
|
||||
{
|
||||
if ($this->bIsEnabled && isset($aAppData['Plugins']) && \is_array($aAppData['Plugins']))
|
||||
{
|
||||
|
|
@ -348,12 +301,9 @@ class Manager
|
|||
}
|
||||
|
||||
/**
|
||||
* @param string $sHookName
|
||||
* @param mixed $mCallbak
|
||||
*
|
||||
* @return \RainLoop\Plugins\Manager
|
||||
*/
|
||||
public function AddHook($sHookName, $mCallbak)
|
||||
public function AddHook(string $sHookName, $mCallbak) : self
|
||||
{
|
||||
if ($this->bIsEnabled && \is_callable($mCallbak))
|
||||
{
|
||||
|
|
@ -368,13 +318,7 @@ class Manager
|
|||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sFile
|
||||
* @param bool $bAdminScope = false
|
||||
*
|
||||
* @return \RainLoop\Plugins\Manager
|
||||
*/
|
||||
public function AddJs($sFile, $bAdminScope = false)
|
||||
public function AddJs(string $sFile, bool $bAdminScope = false) : self
|
||||
{
|
||||
if ($this->bIsEnabled)
|
||||
{
|
||||
|
|
@ -391,13 +335,7 @@ class Manager
|
|||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sFile
|
||||
* @param bool $bAdminScope = false
|
||||
*
|
||||
* @return \RainLoop\Plugins\Manager
|
||||
*/
|
||||
public function AddTemplate($sFile, $bAdminScope = false)
|
||||
public function AddTemplate(string $sFile, bool $bAdminScope = false) : self
|
||||
{
|
||||
if ($this->bIsEnabled)
|
||||
{
|
||||
|
|
@ -414,14 +352,7 @@ class Manager
|
|||
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)
|
||||
public function RunHook(string $sHookName, array $aArg = array(), bool $bLogHook = true) : self
|
||||
{
|
||||
if ($this->bIsEnabled)
|
||||
{
|
||||
|
|
@ -443,12 +374,9 @@ class Manager
|
|||
}
|
||||
|
||||
/**
|
||||
* @param string $sActionName
|
||||
* @param mixed $mCallbak
|
||||
*
|
||||
* @return \RainLoop\Plugins\Manager
|
||||
*/
|
||||
public function AddAdditionalPartAction($sActionName, $mCallbak)
|
||||
public function AddAdditionalPartAction(string $sActionName, $mCallbak) : self
|
||||
{
|
||||
if ($this->bIsEnabled && \is_callable($mCallbak))
|
||||
{
|
||||
|
|
@ -464,13 +392,7 @@ class Manager
|
|||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sActionName
|
||||
* @param array $aParts = array()
|
||||
*
|
||||
* @return \RainLoop\Plugins\Manager
|
||||
*/
|
||||
public function RunAdditionalPart($sActionName, $aParts = array())
|
||||
public function RunAdditionalPart(string $sActionName, array $aParts = array()) : self
|
||||
{
|
||||
$bResult = false;
|
||||
if ($this->bIsEnabled)
|
||||
|
|
@ -492,15 +414,7 @@ class Manager
|
|||
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)
|
||||
public function AddProcessTemplateAction(string $sName, string $sPlace, string $sHtml, bool $bPrepend = false) : self
|
||||
{
|
||||
if ($this->bIsEnabled)
|
||||
{
|
||||
|
|
@ -528,12 +442,9 @@ class Manager
|
|||
}
|
||||
|
||||
/**
|
||||
* @param string $sActionName
|
||||
* @param mixed $mCallback
|
||||
*
|
||||
* @return \RainLoop\Plugins\Manager
|
||||
*/
|
||||
public function AddAdditionalAjaxAction($sActionName, $mCallback)
|
||||
public function AddAdditionalAjaxAction(string $sActionName, $mCallback) : self
|
||||
{
|
||||
if ($this->bIsEnabled && \is_callable($mCallback) && 0 < \strlen($sActionName))
|
||||
{
|
||||
|
|
@ -548,22 +459,15 @@ class Manager
|
|||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sActionName
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function HasAdditionalAjax($sActionName)
|
||||
public function HasAdditionalAjax(string $sActionName) : bool
|
||||
{
|
||||
return $this->bIsEnabled && isset($this->aAdditionalAjax[$sActionName]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sActionName
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function RunAdditionalAjax($sActionName)
|
||||
public function RunAdditionalAjax(string $sActionName)
|
||||
{
|
||||
if ($this->bIsEnabled)
|
||||
{
|
||||
|
|
@ -577,22 +481,16 @@ class Manager
|
|||
}
|
||||
|
||||
/**
|
||||
* @param string $sFunctionName
|
||||
* @param mixed $mData
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function AjaxResponseHelper($sFunctionName, $mData)
|
||||
public function AjaxResponseHelper(string $sFunctionName, $mData)
|
||||
{
|
||||
return $this->oActions->DefaultResponse($sFunctionName, $mData);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sPluginName
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function GetUserPluginSettings($sPluginName)
|
||||
public function GetUserPluginSettings(string $sPluginName) : array
|
||||
{
|
||||
$oAccount = $this->oActions->GetAccount();
|
||||
if ($oAccount)
|
||||
|
|
@ -611,13 +509,7 @@ class Manager
|
|||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sPluginName
|
||||
* @param array $aSettings
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function SaveUserPluginSettings($sPluginName, $aSettings)
|
||||
public function SaveUserPluginSettings(string $sPluginName, array $aSettings) : bool
|
||||
{
|
||||
$oAccount = $this->oActions->GetAccount();
|
||||
if ($oAccount && \is_array($aSettings))
|
||||
|
|
@ -652,13 +544,7 @@ class Manager
|
|||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sLang
|
||||
* @param array $sActionName
|
||||
*
|
||||
* @return \RainLoop\Plugins\Manager
|
||||
*/
|
||||
public function ReadLang($sLang, &$aLang)
|
||||
public function ReadLang(string $sLang, array &$aLang) : self
|
||||
{
|
||||
if ($this->bIsEnabled)
|
||||
{
|
||||
|
|
@ -680,13 +566,7 @@ class Manager
|
|||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sName
|
||||
* @param string $sHtml
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function ProcessTemplate($sName, $sHtml)
|
||||
public function ProcessTemplate(string $sName, string $sHtml) : string
|
||||
{
|
||||
if (isset($this->aProcessTemplate[$sName]))
|
||||
{
|
||||
|
|
@ -705,18 +585,12 @@ class Manager
|
|||
return $sHtml;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function bIsEnabled()
|
||||
public function bIsEnabled() : bool
|
||||
{
|
||||
return $this->bIsEnabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function Count()
|
||||
public function Count() : int
|
||||
{
|
||||
return $this->bIsEnabled ? \count($this->aPlugins) : 0;
|
||||
}
|
||||
|
|
@ -724,11 +598,9 @@ class Manager
|
|||
/**
|
||||
* @param \MailSo\Log\Logger $oLogger
|
||||
*
|
||||
* @return \RainLoop\Plugins\Manager
|
||||
*
|
||||
* @throws \MailSo\Base\Exceptions\InvalidArgumentException
|
||||
*/
|
||||
public function SetLogger($oLogger)
|
||||
public function SetLogger($oLogger) : self
|
||||
{
|
||||
if (!($oLogger instanceof \MailSo\Log\Logger))
|
||||
{
|
||||
|
|
@ -741,12 +613,9 @@ class Manager
|
|||
}
|
||||
|
||||
/**
|
||||
* @param string $sDesc
|
||||
* @param int $iType = \MailSo\Log\Enumerations\Type::INFO
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function WriteLog($sDesc, $iType = \MailSo\Log\Enumerations\Type::INFO)
|
||||
public function WriteLog(string $sDesc, int $iType = \MailSo\Log\Enumerations\Type::INFO)
|
||||
{
|
||||
if ($this->oLogger)
|
||||
{
|
||||
|
|
@ -755,12 +624,9 @@ class Manager
|
|||
}
|
||||
|
||||
/**
|
||||
* @param string $sDesc
|
||||
* @param int $iType = \MailSo\Log\Enumerations\Type::INFO
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function WriteException($sDesc, $iType = \MailSo\Log\Enumerations\Type::INFO)
|
||||
public function WriteException(string $sDesc, int $iType = \MailSo\Log\Enumerations\Type::INFO)
|
||||
{
|
||||
if ($this->oLogger)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ class Property
|
|||
* @var string
|
||||
*/
|
||||
private $sName;
|
||||
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
|
|
@ -18,7 +18,7 @@ class Property
|
|||
* @var string
|
||||
*/
|
||||
private $sDesc;
|
||||
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
|
|
@ -28,7 +28,7 @@ class Property
|
|||
* @var bool
|
||||
*/
|
||||
private $bAllowedInJs;
|
||||
|
||||
|
||||
/**
|
||||
* @var mixed
|
||||
*/
|
||||
|
|
@ -38,8 +38,8 @@ class Property
|
|||
* @var string
|
||||
*/
|
||||
private $sPlaceholder;
|
||||
|
||||
private function __construct($sName)
|
||||
|
||||
private function __construct(string $sName)
|
||||
{
|
||||
$this->sName = $sName;
|
||||
$this->iType = \RainLoop\Enumerations\PluginPropertyType::STRING;
|
||||
|
|
@ -49,128 +49,82 @@ class Property
|
|||
$this->bAllowedInJs = false;
|
||||
$this->sPlaceholder = '';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sName
|
||||
*
|
||||
* @return \RainLoop\Plugins\Property
|
||||
*/
|
||||
public static function NewInstance($sName)
|
||||
|
||||
public static function NewInstance(string $sName) : self
|
||||
{
|
||||
return new self($sName);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $iType
|
||||
*
|
||||
* @return \RainLoop\Plugins\Property
|
||||
*/
|
||||
public function SetType($iType)
|
||||
|
||||
public function SetType(int $iType) : self
|
||||
{
|
||||
$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
|
||||
* @param mixed $mDefaultValue
|
||||
*/
|
||||
public function SetPlaceholder($sPlaceholder)
|
||||
public function SetDefaultValue($mDefaultValue) : self
|
||||
{
|
||||
$this->mDefaultValue = $mDefaultValue;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function SetPlaceholder(string $sPlaceholder) : self
|
||||
{
|
||||
$this->sPlaceholder = $sPlaceholder;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sLabel
|
||||
*
|
||||
* @return \RainLoop\Plugins\Property
|
||||
*/
|
||||
public function SetLabel($sLabel)
|
||||
|
||||
public function SetLabel(string $sLabel) : self
|
||||
{
|
||||
$this->sLabel = $sLabel;
|
||||
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sDesc
|
||||
*
|
||||
* @return \RainLoop\Plugins\Property
|
||||
*/
|
||||
public function SetDescription($sDesc)
|
||||
public function SetDescription(string $sDesc) : self
|
||||
{
|
||||
$this->sDesc = $sDesc;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $bValue = true
|
||||
* @return \RainLoop\Plugins\Property
|
||||
*/
|
||||
public function SetAllowedInJs($bValue = true)
|
||||
public function SetAllowedInJs(bool $bValue = true) : self
|
||||
{
|
||||
$this->bAllowedInJs = !!$bValue;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function Name()
|
||||
|
||||
public function Name() : string
|
||||
{
|
||||
return $this->sName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function AllowedInJs()
|
||||
public function AllowedInJs() : bool
|
||||
{
|
||||
return $this->bAllowedInJs;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function Description()
|
||||
|
||||
public function Description() : string
|
||||
{
|
||||
return $this->sDesc;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function Label()
|
||||
public function Label() : string
|
||||
{
|
||||
return $this->sLabel;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function Type()
|
||||
|
||||
public function Type() : int
|
||||
{
|
||||
return $this->iType;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
|
|
@ -179,18 +133,12 @@ class Property
|
|||
return $this->mDefaultValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function Placeholder()
|
||||
public function Placeholder() : string
|
||||
{
|
||||
return $this->sPlaceholder;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function ToArray()
|
||||
|
||||
public function ToArray() : array
|
||||
{
|
||||
return array(
|
||||
'',
|
||||
|
|
|
|||
|
|
@ -8,37 +8,25 @@ abstract class AbstractProvider
|
|||
* @var \RainLoop\Model\Account
|
||||
*/
|
||||
protected $oAccount;
|
||||
|
||||
|
||||
/**
|
||||
* @var \MailSo\Log\Logger
|
||||
*/
|
||||
protected $oLogger = null;
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function IsActive()
|
||||
public function IsActive() : bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \RainLoop\Model\Account $oAccount
|
||||
*/
|
||||
public function SetAccount($oAccount)
|
||||
public function SetAccount(\RainLoop\Model\Account $oAccount)
|
||||
{
|
||||
$this->oAccount = $oAccount;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \MailSo\Log\Logger $oLogger
|
||||
*/
|
||||
public function SetLogger($oLogger)
|
||||
public function SetLogger(?\MailSo\Log\Logger $oLogger)
|
||||
{
|
||||
if ($oLogger instanceof \MailSo\Log\Logger)
|
||||
{
|
||||
$this->oLogger = $oLogger;
|
||||
}
|
||||
$this->oLogger = $oLogger;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -12,171 +12,93 @@ class AddressBook extends \RainLoop\Providers\AbstractProvider
|
|||
private $oDriver;
|
||||
|
||||
/**
|
||||
* @param \RainLoop\Providers\AddressBook\Interface $oDriver
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($oDriver)
|
||||
public function __construct(?\RainLoop\Providers\AddressBook\AddressBookInterface $oDriver)
|
||||
{
|
||||
$this->oDriver = null;
|
||||
if ($oDriver instanceof \RainLoop\Providers\AddressBook\AddressBookInterface)
|
||||
{
|
||||
$this->oDriver = $oDriver;
|
||||
}
|
||||
$this->oDriver = $oDriver;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function Test()
|
||||
public function Test() : string
|
||||
{
|
||||
\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()
|
||||
public function IsActive() : bool
|
||||
{
|
||||
return $this->oDriver instanceof \RainLoop\Providers\AddressBook\AddressBookInterface &&
|
||||
$this->oDriver->IsSupported();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function IsSupported()
|
||||
public function IsSupported() : bool
|
||||
{
|
||||
return $this->oDriver instanceof \RainLoop\Providers\AddressBook\AddressBookInterface &&
|
||||
$this->oDriver->IsSupported();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function IsSharingAllowed()
|
||||
public function IsSharingAllowed() : bool
|
||||
{
|
||||
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)
|
||||
public function Sync(string $sEmail, string $sUrl, string $sUser, string $sPassword) : bool
|
||||
{
|
||||
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')
|
||||
public function Export(string $sEmail, string $sType = 'vcf') : bool
|
||||
{
|
||||
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)
|
||||
public function ContactSave(string $sEmail, \RainLoop\Providers\AddressBook\Classes\Contact $oContact) : bool
|
||||
{
|
||||
return $this->IsActive() ? $this->oDriver->ContactSave($sEmail, $oContact) : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sEmail
|
||||
* @param array $aContactIds
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function DeleteContacts($sEmail, $aContactIds)
|
||||
public function DeleteContacts(string $sEmail, array $aContactIds) : bool
|
||||
{
|
||||
return $this->IsActive() ? $this->oDriver->DeleteContacts($sEmail, $aContactIds) : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sEmail
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function DeleteAllContacts($sEmail)
|
||||
public function DeleteAllContacts(string $sEmail) : bool
|
||||
{
|
||||
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)
|
||||
public function GetContacts(string $sEmail, int $iOffset = 0, int $iLimit = 20, string $sSearch = '', int &$iResultCount = 0) : array
|
||||
{
|
||||
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)
|
||||
public function GetContactByID(string $sEmail, $mID, bool $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)
|
||||
public function GetSuggestions(string $sEmail, string $sSearch, int $iLimit = 20) : array
|
||||
{
|
||||
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)
|
||||
public function IncFrec(string $sEmail, array $aEmails, bool $bCreateAuto = true) : bool
|
||||
{
|
||||
return $this->IsActive() ? $this->oDriver->IncFrec($sEmail, $aEmails, $bCreateAuto) : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sCsvName
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
private function csvNameToTypeConvertor($sCsvName)
|
||||
private function csvNameToTypeConvertor(string $sCsvName) : int
|
||||
{
|
||||
static $aMap = null;
|
||||
if (null === $aMap)
|
||||
|
|
@ -256,13 +178,7 @@ class AddressBook extends \RainLoop\Providers\AbstractProvider
|
|||
return !empty($sCsvNameLower) && isset($aMap[$sCsvNameLower]) ? $aMap[$sCsvNameLower] : PropertyType::UNKNOWN;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sEmail
|
||||
* @param array $aCsvData
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function ImportCsvArray($sEmail, $aCsvData)
|
||||
public function ImportCsvArray(string $sEmail, array $aCsvData) : int
|
||||
{
|
||||
$iCount = 0;
|
||||
if ($this->IsActive() && \is_array($aCsvData) && 0 < \count($aCsvData))
|
||||
|
|
@ -311,13 +227,7 @@ class AddressBook extends \RainLoop\Providers\AbstractProvider
|
|||
return $iCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sEmail
|
||||
* @param string $sVcfData
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function ImportVcfFile($sEmail, $sVcfData)
|
||||
public function ImportVcfFile(string $sEmail, string $sVcfData) : int
|
||||
{
|
||||
$iCount = 0;
|
||||
|
||||
|
|
@ -334,7 +244,7 @@ class AddressBook extends \RainLoop\Providers\AbstractProvider
|
|||
{
|
||||
$oVCardSplitter = new \SabreForRainLoop\VObject\Splitter\VCard($sVcfData);
|
||||
}
|
||||
catch (\Exception $oExc)
|
||||
catch (\Throwable $oExc)
|
||||
{
|
||||
$this->Logger()->WriteException($oExc);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,8 +4,5 @@ namespace RainLoop\Providers\AddressBook;
|
|||
|
||||
interface AddressBookInterface
|
||||
{
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function IsSupported();
|
||||
}
|
||||
public function IsSupported() : bool;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ class Contact
|
|||
$this->Etag = '';
|
||||
}
|
||||
|
||||
public function PopulateDisplayAndFullNameValue($bForceFullNameReplace = false)
|
||||
public function PopulateDisplayAndFullNameValue(bool $bForceFullNameReplace = false)
|
||||
{
|
||||
$sFullName = '';
|
||||
$sLastName = '';
|
||||
|
|
@ -161,19 +161,13 @@ class Contact
|
|||
$this->PopulateDisplayAndFullNameValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function RegenerateContactStr()
|
||||
public function RegenerateContactStr() : array
|
||||
{
|
||||
$this->IdContactStr = \class_exists('SabreForRainLoop\DAV\Client') ?
|
||||
\SabreForRainLoop\DAV\UUIDUtil::getUUID() : \MailSo\Base\Utils::Md5Rand();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function GetEmails()
|
||||
public function GetEmails() : array
|
||||
{
|
||||
$aResult = array();
|
||||
foreach ($this->Properties as /* @var $oProperty \RainLoop\Providers\AddressBook\Classes\Property */ &$oProperty)
|
||||
|
|
@ -187,18 +181,12 @@ class Contact
|
|||
return \array_unique($aResult);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function CardDavNameUri()
|
||||
public function CardDavNameUri() : string
|
||||
{
|
||||
return $this->IdContactStr.'.vcf';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function ToVCard($sPreVCard = '', $oLogger = null)
|
||||
public function ToVCard(string $sPreVCard = '', $oLogger = null) : string
|
||||
{
|
||||
$this->UpdateDependentValues();
|
||||
|
||||
|
|
@ -219,7 +207,7 @@ class Contact
|
|||
{
|
||||
$oVCard = \SabreForRainLoop\VObject\Reader::read($sPreVCard);
|
||||
}
|
||||
catch (\Exception $oExc)
|
||||
catch (\Throwable $oExc)
|
||||
{
|
||||
if ($oLogger)
|
||||
{
|
||||
|
|
@ -309,10 +297,7 @@ class Contact
|
|||
return (string) $oVCard->serialize();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function ToCsv($bWithHeader = false)
|
||||
public function ToCsv(bool $bWithHeader = false) : string
|
||||
{
|
||||
$aData = array();
|
||||
if ($bWithHeader)
|
||||
|
|
@ -470,10 +455,8 @@ class Contact
|
|||
|
||||
/**
|
||||
* @param mixed $oProp
|
||||
* @param bool $bOldVersion
|
||||
* @return string
|
||||
*/
|
||||
private function getPropertyValueHelper($oProp, $bOldVersion)
|
||||
private function getPropertyValueHelper($oProp, bool $bOldVersion) : string
|
||||
{
|
||||
$sValue = \trim($oProp);
|
||||
if ($bOldVersion && !isset($oProp->parameters['CHARSET']))
|
||||
|
|
@ -495,10 +478,8 @@ class Contact
|
|||
|
||||
/**
|
||||
* @param mixed $oProp
|
||||
* @param bool $bOldVersion
|
||||
* @return string
|
||||
*/
|
||||
private function addArrayPropertyHelper(&$aProperties, $oArrayProp, $iType)
|
||||
private function addArrayPropertyHelper(array &$aProperties, $oArrayProp, int $iType) : string
|
||||
{
|
||||
foreach ($oArrayProp as $oProp)
|
||||
{
|
||||
|
|
@ -520,7 +501,7 @@ class Contact
|
|||
}
|
||||
}
|
||||
|
||||
public function PopulateByVCard($sUid, $sVCard, $sEtag = '', $oLogger = null)
|
||||
public function PopulateByVCard(string $sUid, string $sVCard, string $sEtag = '', $oLogger = null)
|
||||
{
|
||||
if ("\xef\xbb\xbf" === \substr($sVCard, 0, 3))
|
||||
{
|
||||
|
|
@ -545,7 +526,7 @@ class Contact
|
|||
{
|
||||
$oVCard = \SabreForRainLoop\VObject\Reader::read($sVCard);
|
||||
}
|
||||
catch (\Exception $oExc)
|
||||
catch (\Throwable $oExc)
|
||||
{
|
||||
if ($oLogger)
|
||||
{
|
||||
|
|
@ -559,14 +540,10 @@ class Contact
|
|||
// $oLogger->WriteDump($sVCard);
|
||||
// }
|
||||
|
||||
$bOwnCloud = false;
|
||||
$aProperties = array();
|
||||
|
||||
if ($oVCard)
|
||||
{
|
||||
$bOwnCloud = empty($oVCard->PRODID) ? false :
|
||||
false !== \strpos(\strtolower($oVCard->PRODID), 'owncloud');
|
||||
|
||||
$bOldVersion = empty($oVCard->VERSION) ? false :
|
||||
\in_array((string) $oVCard->VERSION, array('2.1', '2.0', '1.0'));
|
||||
|
||||
|
|
|
|||
|
|
@ -65,51 +65,33 @@ class Property
|
|||
$this->Frec = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function IsName()
|
||||
public function IsName() : bool
|
||||
{
|
||||
return \in_array($this->Type, array(PropertyType::FULLNAME, PropertyType::FIRST_NAME,
|
||||
PropertyType::LAST_NAME, PropertyType::MIDDLE_NAME, PropertyType::NICK_NAME));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function IsEmail()
|
||||
public function IsEmail() : bool
|
||||
{
|
||||
return PropertyType::EMAIl === $this->Type;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function IsPhone()
|
||||
public function IsPhone() : bool
|
||||
{
|
||||
return PropertyType::PHONE === $this->Type;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function IsWeb()
|
||||
public function IsWeb() : bool
|
||||
{
|
||||
return PropertyType::WEB_PAGE === $this->Type;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function IsValueForLower()
|
||||
public function IsValueForLower() : bool
|
||||
{
|
||||
return $this->IsEmail() || $this->IsName() || $this->IsWeb();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function TypesAsArray()
|
||||
public function TypesAsArray() : bool
|
||||
{
|
||||
$aResult = array();
|
||||
if (!empty($this->TypeStr))
|
||||
|
|
@ -121,10 +103,7 @@ class Property
|
|||
return $aResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function TypesUpperAsArray()
|
||||
public function TypesUpperAsArray() : array
|
||||
{
|
||||
return \array_map('strtoupper', $this->TypesAsArray());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ class PdoAddressBook
|
|||
*/
|
||||
private $sPassword;
|
||||
|
||||
public function __construct($sDsn, $sUser = '', $sPassword = '', $sDsnType = 'mysql')
|
||||
public function __construct(string $sDsn, string $sUser = '', string $sPassword = '', string $sDsnType = 'mysql')
|
||||
{
|
||||
$this->sDsn = $sDsn;
|
||||
$this->sUser = $sUser;
|
||||
|
|
@ -38,31 +38,25 @@ class PdoAddressBook
|
|||
$this->bExplain = false; // debug
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function IsSupported()
|
||||
public function IsSupported() : bool
|
||||
{
|
||||
$aDrivers = \class_exists('PDO') ? \PDO::getAvailableDrivers() : array();
|
||||
return \is_array($aDrivers) ? \in_array($this->sDsnType, $aDrivers) : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function IsSharingAllowed()
|
||||
public function IsSharingAllowed() : bool
|
||||
{
|
||||
return $this->IsSupported() && false; // TODO
|
||||
}
|
||||
|
||||
private function flushDeletedContacts($iUserID)
|
||||
private function flushDeletedContacts(int $iUserID)
|
||||
{
|
||||
return !!$this->prepareAndExecute('DELETE FROM rainloop_ab_contacts WHERE id_user = :id_user AND deleted = 1', array(
|
||||
':id_user' => array($iUserID, \PDO::PARAM_INT)
|
||||
));
|
||||
}
|
||||
|
||||
private function updateContactEtagAndTime($iUserID, $mID, $sEtag, $iChanged)
|
||||
private function updateContactEtagAndTime(int $iUserID, int $mID, string $sEtag, int $iChanged)
|
||||
{
|
||||
return !!$this->prepareAndExecute('UPDATE rainloop_ab_contacts SET changed = :changed, etag = :etag '.
|
||||
'WHERE id_user = :id_user AND id_contact = :id_contact', array(
|
||||
|
|
@ -74,7 +68,7 @@ class PdoAddressBook
|
|||
);
|
||||
}
|
||||
|
||||
private function prepearDatabaseSyncData($iUserID)
|
||||
private function prepearDatabaseSyncData(int $iUserID)
|
||||
{
|
||||
$aResult = array();
|
||||
$oStmt = $this->prepareAndExecute('SELECT id_contact, id_contact_str, changed, deleted, etag FROM rainloop_ab_contacts WHERE id_user = :id_user', array(
|
||||
|
|
@ -110,7 +104,7 @@ class PdoAddressBook
|
|||
return $aResult;
|
||||
}
|
||||
|
||||
private function prepearRemoteSyncData($oClient, $sPath)
|
||||
private function prepearRemoteSyncData($oClient, string $sPath)
|
||||
{
|
||||
$mResult = false;
|
||||
$aResponse = null;
|
||||
|
|
@ -126,7 +120,7 @@ class PdoAddressBook
|
|||
|
||||
// $this->oLogger->WriteDump($aResponse);
|
||||
}
|
||||
catch (\Exception $oException)
|
||||
catch (\Throwable $oException)
|
||||
{
|
||||
$this->oLogger->WriteException($oException);
|
||||
}
|
||||
|
|
@ -181,7 +175,7 @@ class PdoAddressBook
|
|||
return $mResult;
|
||||
}
|
||||
|
||||
private function davClientRequest($oClient, $sCmd, $sUrl, $mData = null)
|
||||
private function davClientRequest($oClient, string $sCmd, string $sUrl, $mData = null)
|
||||
{
|
||||
\MailSo\Base\Utils::ResetTimeLimit();
|
||||
|
||||
|
|
@ -212,7 +206,7 @@ class PdoAddressBook
|
|||
// $this->oLogger->WriteDump($oResponse, \MailSo\Log\Enumerations\Type::INFO, 'DAV');
|
||||
// }
|
||||
}
|
||||
catch (\Exception $oException)
|
||||
catch (\Throwable $oException)
|
||||
{
|
||||
$this->oLogger->WriteException($oException);
|
||||
}
|
||||
|
|
@ -220,13 +214,7 @@ class PdoAddressBook
|
|||
return $oResponse;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \SabreForRainLoop\DAV\Client $oClient
|
||||
* @param string $sPath
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function detectionPropFind($oClient, $sPath)
|
||||
private function detectionPropFind(\SabreForRainLoop\DAV\Client $oClient, string $sPath) : bool
|
||||
{
|
||||
$aResponse = null;
|
||||
|
||||
|
|
@ -243,7 +231,7 @@ class PdoAddressBook
|
|||
|
||||
// $this->oLogger->WriteDump($aResponse);
|
||||
}
|
||||
catch (\Exception $oException)
|
||||
catch (\Throwable $oException)
|
||||
{
|
||||
$this->oLogger->WriteException($oException);
|
||||
}
|
||||
|
|
@ -251,15 +239,7 @@ class PdoAddressBook
|
|||
return $aResponse;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \SabreForRainLoop\DAV\Client $oClient
|
||||
* @param string $sUser
|
||||
* @param string $sPassword
|
||||
* @param string $sProxy = ''
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function getContactsPaths(&$oClient, $sUser, $sPassword, $sProxy = '')
|
||||
private function getContactsPaths(\SabreForRainLoop\DAV\Client &$oClient, string $sUser, string $sPassword, string $sProxy = '') : array
|
||||
{
|
||||
$aContactsPaths = array();
|
||||
|
||||
|
|
@ -445,13 +425,7 @@ class PdoAddressBook
|
|||
return $aContactsPaths;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \SabreForRainLoop\DAV\Client $oClient
|
||||
* @param string $sPath
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function checkContactsPath(&$oClient, $sPath)
|
||||
private function checkContactsPath(\SabreForRainLoop\DAV\Client &$oClient, string $sPath) : bool
|
||||
{
|
||||
if (!$oClient)
|
||||
{
|
||||
|
|
@ -469,7 +443,7 @@ class PdoAddressBook
|
|||
|
||||
// $this->oLogger->WriteDump($aResponse);
|
||||
}
|
||||
catch (\Exception $oException)
|
||||
catch (\Throwable $oException)
|
||||
{
|
||||
$this->oLogger->WriteException($oException);
|
||||
}
|
||||
|
|
@ -501,7 +475,7 @@ class PdoAddressBook
|
|||
return $bGood;
|
||||
}
|
||||
|
||||
public function getDavClientFromUrl($sUrl, $sUser, $sPassword, $sProxy = '')
|
||||
public function getDavClientFromUrl(string $sUrl, string $sUser, string $sPassword, string $sProxy = '')
|
||||
{
|
||||
if (!\preg_match('/^http[s]?:\/\//i', $sUrl))
|
||||
{
|
||||
|
|
@ -553,16 +527,7 @@ class PdoAddressBook
|
|||
return $oClient;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sEmail
|
||||
* @param string $sUrl
|
||||
* @param string $sUser
|
||||
* @param string $sPassword
|
||||
* @param string $sProxy = ''
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function getDavClient($sUrl, $sUser, $sPassword, $sProxy = '')
|
||||
public function getDavClient(string $sUrl, string $sUser, string $sPassword, string $sProxy = '') : bool
|
||||
{
|
||||
if (!\class_exists('SabreForRainLoop\DAV\Client'))
|
||||
{
|
||||
|
|
@ -655,16 +620,7 @@ class PdoAddressBook
|
|||
return $oClient;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sEmail
|
||||
* @param string $sUrl
|
||||
* @param string $sUser
|
||||
* @param string $sPassword
|
||||
* @param string $sProxy = ''
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function Sync($sEmail, $sUrl, $sUser, $sPassword, $sProxy = '')
|
||||
public function Sync(string $sEmail, string $sUrl, string $sUser, string $sPassword, string $sProxy = '') : bool
|
||||
{
|
||||
$this->SyncDatabase();
|
||||
|
||||
|
|
@ -815,13 +771,7 @@ class PdoAddressBook
|
|||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sEmail
|
||||
* @param string $sType = 'vcf'
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function Export($sEmail, $sType = 'vcf')
|
||||
public function Export(string $sEmail, string $sType = 'vcf') : bool
|
||||
{
|
||||
$this->SyncDatabase();
|
||||
|
||||
|
|
@ -861,14 +811,7 @@ class PdoAddressBook
|
|||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sEmail
|
||||
* @param \RainLoop\Providers\AddressBook\Classes\Contact $oContact
|
||||
* @param bool $bSyncDb = true
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function ContactSave($sEmail, &$oContact, $bSyncDb = true)
|
||||
public function ContactSave(string $sEmail, \RainLoop\Providers\AddressBook\Classes\Contact $oContact, bool $bSyncDb = true) : bool
|
||||
{
|
||||
if ($bSyncDb)
|
||||
{
|
||||
|
|
@ -973,7 +916,7 @@ class PdoAddressBook
|
|||
}
|
||||
}
|
||||
}
|
||||
catch (\Exception $oException)
|
||||
catch (\Throwable $oException)
|
||||
{
|
||||
throw $oException;
|
||||
}
|
||||
|
|
@ -981,14 +924,7 @@ class PdoAddressBook
|
|||
return 0 < $iIdContact;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sEmail
|
||||
* @param array $aContactIds
|
||||
* @param bool $bSyncDb = true
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function DeleteContacts($sEmail, $aContactIds, $bSyncDb = true)
|
||||
public function DeleteContacts(string $sEmail, array $aContactIds, bool $bSyncDb = true) : bool
|
||||
{
|
||||
if ($bSyncDb)
|
||||
{
|
||||
|
|
@ -1023,13 +959,7 @@ class PdoAddressBook
|
|||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sEmail
|
||||
* @param bool $bSyncDb = true
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function DeleteAllContacts($sEmail, $bSyncDb = true)
|
||||
public function DeleteAllContacts(string $sEmail, bool $bSyncDb = true) : bool
|
||||
{
|
||||
if ($bSyncDb)
|
||||
{
|
||||
|
|
@ -1046,16 +976,7 @@ class PdoAddressBook
|
|||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sEmail
|
||||
* @param int $iOffset = 0
|
||||
* @param int $iLimit = 20
|
||||
* @param string $sSearch = ''
|
||||
* @param int $iResultCount = 0
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function GetContacts($sEmail, $iOffset = 0, $iLimit = 20, $sSearch = '', &$iResultCount = 0)
|
||||
public function GetContacts(string $sEmail, int $iOffset = 0, int $iLimit = 20, string $sSearch = '', int &$iResultCount = 0) : array
|
||||
{
|
||||
$this->SyncDatabase();
|
||||
|
||||
|
|
@ -1246,13 +1167,11 @@ class PdoAddressBook
|
|||
}
|
||||
|
||||
/**
|
||||
* @param string $sEmail
|
||||
* @param string $mID
|
||||
* @param bool $bIsStrID = false
|
||||
* @param mixed $mID
|
||||
*
|
||||
* @return \RainLoop\Providers\AddressBook\Classes\Contact|null
|
||||
*/
|
||||
public function GetContactByID($sEmail, $mID, $bIsStrID = false)
|
||||
public function GetContactByID(string $sEmail, $mID, bool $bIsStrID = false)
|
||||
{
|
||||
$mID = \trim($mID);
|
||||
|
||||
|
|
@ -1350,15 +1269,9 @@ class PdoAddressBook
|
|||
}
|
||||
|
||||
/**
|
||||
* @param string $sEmail
|
||||
* @param string $sSearch
|
||||
* @param int $iLimit = 20
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function GetSuggestions($sEmail, $sSearch, $iLimit = 20)
|
||||
public function GetSuggestions(string $sEmail, string $sSearch, int $iLimit = 20) : array
|
||||
{
|
||||
$sSearch = \trim($sSearch);
|
||||
if (0 === \strlen($sSearch))
|
||||
|
|
@ -1553,14 +1466,7 @@ class PdoAddressBook
|
|||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sEmail
|
||||
* @param array $aEmails
|
||||
* @param bool $bCreateAuto = true
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function IncFrec($sEmail, $aEmails, $bCreateAuto = true)
|
||||
public function IncFrec(string $sEmail, array $aEmails, bool $bCreateAuto = true) : bool
|
||||
{
|
||||
$self = $this;
|
||||
$aEmailsObjects = \array_map(function ($mItem) {
|
||||
|
|
@ -1569,7 +1475,7 @@ class PdoAddressBook
|
|||
{
|
||||
$oResult = \MailSo\Mime\Email::Parse(\trim($mItem));
|
||||
}
|
||||
catch (\Exception $oException) { unset($oException); }
|
||||
catch (\Throwable $oException) { unset($oException); }
|
||||
return $oResult;
|
||||
}, $aEmails);
|
||||
|
||||
|
|
@ -1721,10 +1627,7 @@ class PdoAddressBook
|
|||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function Test()
|
||||
public function Test() : string
|
||||
{
|
||||
$sResult = '';
|
||||
try
|
||||
|
|
@ -1735,7 +1638,7 @@ class PdoAddressBook
|
|||
$sResult = 'Unknown database error';
|
||||
}
|
||||
}
|
||||
catch (\Exception $oException)
|
||||
catch (\Throwable $oException)
|
||||
{
|
||||
$sResult = $oException->getMessage();
|
||||
if (!empty($sResult) && !\MailSo\Base\Utils::IsAscii($sResult) && !\MailSo\Base\Utils::IsUtf8($sResult))
|
||||
|
|
@ -1752,7 +1655,7 @@ class PdoAddressBook
|
|||
return $sResult;
|
||||
}
|
||||
|
||||
private function getInitialTablesArray($sDbType)
|
||||
private function getInitialTablesArray(string $sDbType)
|
||||
{
|
||||
switch ($sDbType)
|
||||
{
|
||||
|
|
@ -1876,10 +1779,7 @@ SQLITEINITIAL;
|
|||
return $aResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function SyncDatabase()
|
||||
public function SyncDatabase() : bool
|
||||
{
|
||||
static $mCache = null;
|
||||
if (null !== $mCache)
|
||||
|
|
@ -1926,12 +1826,7 @@ SQLITEINITIAL;
|
|||
return $mCache;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $iUserID
|
||||
* @param int $iIdContact
|
||||
* @return array
|
||||
*/
|
||||
private function getContactFreq($iUserID, $iIdContact)
|
||||
private function getContactFreq(int $iUserID, int $iIdContact) : array
|
||||
{
|
||||
$aResult = array();
|
||||
|
||||
|
|
@ -1961,25 +1856,13 @@ SQLITEINITIAL;
|
|||
return $aResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sSearch
|
||||
* @param string $sEscapeSign = '='
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function specialConvertSearchValue($sSearch, $sEscapeSign = '=')
|
||||
private function specialConvertSearchValue(string $sSearch, string $sEscapeSign = '=') : string
|
||||
{
|
||||
return '%'.\str_replace(array($sEscapeSign, '_', '%'),
|
||||
array($sEscapeSign.$sEscapeSign, $sEscapeSign.'_', $sEscapeSign.'%'), $sSearch).'%';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sSearch
|
||||
* @param string $sEscapeSign = '='
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function specialConvertSearchValueLower($sSearch, $sEscapeSign = '=')
|
||||
private function specialConvertSearchValueLower(string $sSearch, string $sEscapeSign = '=') : string
|
||||
{
|
||||
if (!\MailSo\Base\Utils::FunctionExistsAndEnabled('mb_strtolower'))
|
||||
{
|
||||
|
|
@ -1991,22 +1874,14 @@ SQLITEINITIAL;
|
|||
(string) @\mb_strtolower($sSearch, 'UTF-8')).'%';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sSearch
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function specialConvertSearchValueCustomPhone($sSearch)
|
||||
private function specialConvertSearchValueCustomPhone(string $sSearch) : string
|
||||
{
|
||||
$sResult = '%'.\preg_replace('/[^\d]/', '', $sSearch).'%';
|
||||
return '%%' === $sResult ? '' : $sResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
protected function getPdoAccessData()
|
||||
protected function getPdoAccessData() : array
|
||||
{
|
||||
return array($this->sDsnType, $this->sDsn, $this->sUser, $this->sPassword);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,42 +19,24 @@ class ChangePassword extends \RainLoop\Providers\AbstractProvider
|
|||
*/
|
||||
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)
|
||||
public function __construct(\RainLoop\Actions $oActions, ?\RainLoop\Providers\ChangePassword\ChangePasswordInterface $oDriver = null, bool $bCheckWeak = true)
|
||||
{
|
||||
$this->oActions = $oActions;
|
||||
$this->oDriver = $oDriver;
|
||||
$this->bCheckWeak = !!$bCheckWeak;
|
||||
$this->bCheckWeak = $bCheckWeak;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \RainLoop\Account $oAccount
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function PasswordChangePossibility($oAccount)
|
||||
public function PasswordChangePossibility(\RainLoop\Model\Account $oAccount) : bool
|
||||
{
|
||||
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)
|
||||
public function ChangePassword(\RainLoop\Model\Account $oAccount, string $sPrevPassword, string $sNewPassword)
|
||||
{
|
||||
$mResult = false;
|
||||
|
||||
|
||||
if ($this->oDriver instanceof \RainLoop\Providers\ChangePassword\ChangePasswordInterface &&
|
||||
$this->PasswordChangePossibility($oAccount))
|
||||
{
|
||||
|
|
@ -92,10 +74,7 @@ class ChangePassword extends \RainLoop\Providers\AbstractProvider
|
|||
return $mResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function IsActive()
|
||||
public function IsActive() : bool
|
||||
{
|
||||
return $this->oDriver instanceof \RainLoop\Providers\ChangePassword\ChangePasswordInterface;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,19 +4,7 @@ namespace RainLoop\Providers\ChangePassword;
|
|||
|
||||
interface ChangePasswordInterface
|
||||
{
|
||||
/**
|
||||
* @param \RainLoop\Account $oAccount
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function PasswordChangePossibility($oAccount);
|
||||
public function PasswordChangePossibility(\RainLoop\Model\Account $oAccount) : bool;
|
||||
|
||||
/**
|
||||
* @param \RainLoop\Account $oAccount
|
||||
* @param string $sPrevPassword
|
||||
* @param string $sNewPassword
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function ChangePassword(\RainLoop\Account $oAccount, $sPrevPassword, $sNewPassword);
|
||||
public function ChangePassword(\RainLoop\Model\Account $oAccount, string $sPrevPassword, string $sNewPassword) : bool;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,11 +19,6 @@ class Domain extends \RainLoop\Providers\AbstractProvider
|
|||
*/
|
||||
private $bAdmin;
|
||||
|
||||
/**
|
||||
* @param \RainLoop\Providers\Domain\DomainInterface $oDriver
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(\RainLoop\Providers\Domain\DomainInterface $oDriver,
|
||||
\RainLoop\Plugins\Manager $oPlugins)
|
||||
{
|
||||
|
|
@ -32,23 +27,15 @@ class Domain extends \RainLoop\Providers\AbstractProvider
|
|||
$this->bAdmin = $this->oDriver instanceof \RainLoop\Providers\Domain\DomainAdminInterface;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function IsAdmin()
|
||||
public function IsAdmin() : bool
|
||||
{
|
||||
return $this->bAdmin;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sName
|
||||
* @param bool $bFindWithWildCard = false
|
||||
* @param bool $bCheckDisabled = true
|
||||
* @param bool $bCheckAliases = true
|
||||
*
|
||||
* @return \RainLoop\Model\Domain|null
|
||||
*/
|
||||
public function Load($sName, $bFindWithWildCard = false, $bCheckDisabled = true, $bCheckAliases = true)
|
||||
public function Load(string $sName, bool $bFindWithWildCard = false, bool $bCheckDisabled = true, bool $bCheckAliases = true)
|
||||
{
|
||||
$oDomain = $this->oDriver->Load($sName, $bFindWithWildCard, $bCheckDisabled, $bCheckAliases);
|
||||
if ($oDomain instanceof \RainLoop\Model\Domain)
|
||||
|
|
@ -59,23 +46,12 @@ class Domain extends \RainLoop\Providers\AbstractProvider
|
|||
return $oDomain;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \RainLoop\Model\Domain $oDomain
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function Save(\RainLoop\Model\Domain $oDomain)
|
||||
public function Save(\RainLoop\Model\Domain $oDomain) : bool
|
||||
{
|
||||
return $this->bAdmin ? $this->oDriver->Save($oDomain) : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sName
|
||||
* @param string $sAlias
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function SaveAlias($sName, $sAlias)
|
||||
public function SaveAlias(string $sName, string $sAlias) : bool
|
||||
{
|
||||
if ($this->Load($sName, false, false))
|
||||
{
|
||||
|
|
@ -85,36 +61,17 @@ class Domain extends \RainLoop\Providers\AbstractProvider
|
|||
return $this->bAdmin ? $this->oDriver->SaveAlias($sName, $sAlias) : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sName
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function Delete($sName)
|
||||
public function Delete(string $sName) : bool
|
||||
{
|
||||
return $this->bAdmin ? $this->oDriver->Delete($sName) : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sName
|
||||
* @param bool $bDisabled
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function Disable($sName, $bDisabled)
|
||||
public function Disable(string $sName, bool $bDisabled) : bool
|
||||
{
|
||||
return $this->bAdmin ? $this->oDriver->Disable($sName, $bDisabled) : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $iOffset = 0
|
||||
* @param int $iLimit = 20
|
||||
* @param string $sSearch = ''
|
||||
* @param bool $bIncludeAliases = true
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function GetList($iOffset = 0, $iLimit = 20, $sSearch = '', $bIncludeAliases = true)
|
||||
public function GetList(int $iOffset = 0, int $iLimit = 20, string $sSearch = '', bool $bIncludeAliases = true) : array
|
||||
{
|
||||
$sSearch = \trim($sSearch);
|
||||
|
||||
|
|
@ -131,23 +88,15 @@ class Domain extends \RainLoop\Providers\AbstractProvider
|
|||
return $this->bAdmin ? $this->oDriver->GetList($iOffset, $iLimit, $sSearch, $bIncludeAliases) : array();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sSearch = ''
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function Count($sSearch = '')
|
||||
public function Count(string $sSearch = '') : int
|
||||
{
|
||||
return $this->oDriver->Count($sSearch);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \RainLoop\Actions $oActions
|
||||
* @param string $sNameForTest = ''
|
||||
*
|
||||
* @return \RainLoop\Model\Domain | null
|
||||
*/
|
||||
public function LoadOrCreateNewFromAction(\RainLoop\Actions $oActions, $sNameForTest = '')
|
||||
public function LoadOrCreateNewFromAction(\RainLoop\Actions $oActions, string $sNameForTest = '')
|
||||
{
|
||||
$oDomain = null;
|
||||
|
||||
|
|
@ -215,12 +164,9 @@ class Domain extends \RainLoop\Providers\AbstractProvider
|
|||
}
|
||||
|
||||
/**
|
||||
* @param \RainLoop\Actions $oActions
|
||||
* @param string $sNameForTest = ''
|
||||
*
|
||||
* @return \RainLoop\Model\Domain | null
|
||||
*/
|
||||
public function CreateNewAliasFromAction(\RainLoop\Actions $oActions, $sNameForTest = '')
|
||||
public function CreateNewAliasFromAction(\RainLoop\Actions $oActions, string $sNameForTest = '')
|
||||
{
|
||||
$oDomain = null;
|
||||
|
||||
|
|
@ -287,11 +233,8 @@ class Domain extends \RainLoop\Providers\AbstractProvider
|
|||
return $oDomain;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function IsActive()
|
||||
public function IsActive() : bool
|
||||
{
|
||||
return $this->oDriver instanceof \RainLoop\Providers\Domain\DomainInterface;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,410 +1,325 @@
|
|||
<?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);
|
||||
}
|
||||
|
||||
/**
|
||||
* @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
|
||||
* @param bool $bCheckAliases = true
|
||||
*
|
||||
* @return \RainLoop\Model\Domain|null
|
||||
*/
|
||||
public function Load($sName, $bFindWithWildCard = false, $bCheckDisabled = true, $bCheckAliases = 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 = \RainLoop\Utils::CustomParseIniFile($this->sDomainPath.'/'.$sRealFileName.'.ini');
|
||||
// if ($bCheckAliases && !empty($aDomain['alias']))
|
||||
// {
|
||||
// $oDomain = $this->Load($aDomain['alias'], false, false, false);
|
||||
// if ($oDomain && $oDomain instanceof \RainLoop\Model\Domain)
|
||||
// {
|
||||
// $oDomain->SetAliasName($sName);
|
||||
// }
|
||||
//
|
||||
// return $oDomain;
|
||||
// }
|
||||
|
||||
// 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\Model\Domain::NewInstanceFromDomainConfigArray($sName, $aDomain);
|
||||
}
|
||||
else if ($bCheckAliases && \file_exists($this->sDomainPath.'/'.$sRealFileName.'.alias') &&
|
||||
(!$bCheckDisabled || 0 === \strlen($sDisabled) || false === \strpos(','.$sDisabled.',', ','.\MailSo\Base\Utils::IdnToAscii($sName, true).',')))
|
||||
{
|
||||
$sAlias = \trim(\file_get_contents($this->sDomainPath.'/'.$sRealFileName.'.alias'));
|
||||
if (!empty($sAlias))
|
||||
{
|
||||
$oDomain = $this->Load($sAlias, false, false, false);
|
||||
if ($oDomain && $oDomain instanceof \RainLoop\Model\Domain)
|
||||
{
|
||||
$oDomain->SetAliasName($sName);
|
||||
}
|
||||
|
||||
return $oDomain;
|
||||
}
|
||||
}
|
||||
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\Model\Domain $oDomain
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function Save(\RainLoop\Model\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
|
||||
* @param string $sAlias
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function SaveAlias($sName, $sAlias)
|
||||
{
|
||||
$sRealFileName = $this->codeFileName($sName);
|
||||
|
||||
if ($this->oCacher)
|
||||
{
|
||||
$this->oCacher->Delete($this->wildcardDomainsCacheKey());
|
||||
}
|
||||
|
||||
$mResult = \file_put_contents($this->sDomainPath.'/'.$sRealFileName.'.alias', $sAlias);
|
||||
return \is_int($mResult) && 0 < $mResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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), ', '));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sName
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function Delete($sName)
|
||||
{
|
||||
$bResult = true;
|
||||
$sRealFileName = $this->codeFileName($sName);
|
||||
|
||||
if (0 < \strlen($sName))
|
||||
{
|
||||
if (\file_exists($this->sDomainPath.'/'.$sRealFileName.'.ini'))
|
||||
{
|
||||
$bResult = \unlink($this->sDomainPath.'/'.$sRealFileName.'.ini');
|
||||
}
|
||||
else if (\file_exists($this->sDomainPath.'/'.$sRealFileName.'.alias'))
|
||||
{
|
||||
$bResult = \unlink($this->sDomainPath.'/'.$sRealFileName.'.alias');
|
||||
}
|
||||
}
|
||||
|
||||
if ($bResult)
|
||||
{
|
||||
$this->Disable($sName, false);
|
||||
}
|
||||
|
||||
if ($this->oCacher)
|
||||
{
|
||||
$this->oCacher->Delete($this->wildcardDomainsCacheKey());
|
||||
}
|
||||
|
||||
return $bResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $iOffset = 0
|
||||
* @param int $iLimit = 20
|
||||
* @param int $sSearch = ''
|
||||
* @param bool $bIncludeAliases = true
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function GetList($iOffset = 0, $iLimit = 20, $sSearch = '', $bIncludeAliases = true)
|
||||
{
|
||||
$aResult = array();
|
||||
$aWildCards = array();
|
||||
$aAliases = array();
|
||||
|
||||
// $aList = \glob($this->sDomainPath.'/*.{ini,alias}', GLOB_BRACE);
|
||||
$aList = @\array_diff(\scandir($this->sDomainPath), array('.', '..'));
|
||||
if (\is_array($aList))
|
||||
{
|
||||
foreach ($aList as $sFile)
|
||||
{
|
||||
$sName = $sFile;
|
||||
if ('.ini' === \substr($sName, -4) || '.alias' === \substr($sName, -6))
|
||||
{
|
||||
$bAlias = '.alias' === \substr($sName, -6);
|
||||
|
||||
$sName = \preg_replace('/\.(ini|alias)$/', '', $sName);
|
||||
$sName = $this->codeFileName($sName, true);
|
||||
|
||||
if ($bAlias)
|
||||
{
|
||||
if ($bIncludeAliases)
|
||||
{
|
||||
$aAliases[] = $sName;
|
||||
}
|
||||
}
|
||||
else if (false !== \strpos($sName, '*'))
|
||||
{
|
||||
$aWildCards[] = $sName;
|
||||
}
|
||||
else
|
||||
{
|
||||
$aResult[] = $sName;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
\sort($aResult, SORT_STRING);
|
||||
\sort($aAliases, SORT_STRING);
|
||||
\rsort($aWildCards, SORT_STRING);
|
||||
|
||||
$aResult = \array_merge($aResult, $aAliases, $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] = array(
|
||||
!\in_array($sName, $aDisabledNames),
|
||||
\in_array($sName, $aAliases)
|
||||
);
|
||||
}
|
||||
|
||||
return $aReturn;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sSearch = ''
|
||||
* @param bool $bIncludeAliases = true
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function Count($sSearch = '', $bIncludeAliases = true)
|
||||
{
|
||||
return \count($this->GetList(0, 999, $sSearch, $bIncludeAliases));
|
||||
}
|
||||
}
|
||||
<?php
|
||||
|
||||
namespace RainLoop\Providers\Domain;
|
||||
|
||||
class DefaultDomain implements \RainLoop\Providers\Domain\DomainAdminInterface
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $sDomainPath;
|
||||
|
||||
/**
|
||||
* @var \MailSo\Cache\CacheClient
|
||||
*/
|
||||
protected $oCacher;
|
||||
|
||||
public function __construct(string $sDomainPath, ?\MailSo\Cache\CacheClient $oCacher = null)
|
||||
{
|
||||
$this->sDomainPath = \rtrim(\trim($sDomainPath), '\\/');
|
||||
$this->oCacher = $oCacher;
|
||||
}
|
||||
|
||||
public function codeFileName(string $sName, bool $bBack = false) : string
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
private function wildcardDomainsCacheKey() : string
|
||||
{
|
||||
return '/WildCard/DomainCache/'.\md5(APP_VERSION.APP_PRIVATE_DATA_NAME).'/';
|
||||
}
|
||||
|
||||
private function getWildcardDomainsLine() : string
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \RainLoop\Model\Domain|null
|
||||
*/
|
||||
public function Load(string $sName, bool $bFindWithWildCard = false, bool $bCheckDisabled = true, bool $bCheckAliases = 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 = \RainLoop\Utils::CustomParseIniFile($this->sDomainPath.'/'.$sRealFileName.'.ini');
|
||||
// if ($bCheckAliases && !empty($aDomain['alias']))
|
||||
// {
|
||||
// $oDomain = $this->Load($aDomain['alias'], false, false, false);
|
||||
// if ($oDomain && $oDomain instanceof \RainLoop\Model\Domain)
|
||||
// {
|
||||
// $oDomain->SetAliasName($sName);
|
||||
// }
|
||||
//
|
||||
// return $oDomain;
|
||||
// }
|
||||
$mResult = \RainLoop\Model\Domain::NewInstanceFromDomainConfigArray($sName, $aDomain);
|
||||
}
|
||||
else if ($bCheckAliases && \file_exists($this->sDomainPath.'/'.$sRealFileName.'.alias') &&
|
||||
(!$bCheckDisabled || 0 === \strlen($sDisabled) || false === \strpos(','.$sDisabled.',', ','.\MailSo\Base\Utils::IdnToAscii($sName, true).',')))
|
||||
{
|
||||
$sAlias = \trim(\file_get_contents($this->sDomainPath.'/'.$sRealFileName.'.alias'));
|
||||
if (!empty($sAlias))
|
||||
{
|
||||
$oDomain = $this->Load($sAlias, false, false, false);
|
||||
if ($oDomain && $oDomain instanceof \RainLoop\Model\Domain)
|
||||
{
|
||||
$oDomain->SetAliasName($sName);
|
||||
}
|
||||
|
||||
return $oDomain;
|
||||
}
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
public function Save(\RainLoop\Model\Domain $oDomain) : bool
|
||||
{
|
||||
$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;
|
||||
}
|
||||
|
||||
public function SaveAlias(string $sName, string $sAlias) : bool
|
||||
{
|
||||
$sRealFileName = $this->codeFileName($sName);
|
||||
|
||||
if ($this->oCacher)
|
||||
{
|
||||
$this->oCacher->Delete($this->wildcardDomainsCacheKey());
|
||||
}
|
||||
|
||||
$mResult = \file_put_contents($this->sDomainPath.'/'.$sRealFileName.'.alias', $sAlias);
|
||||
return \is_int($mResult) && 0 < $mResult;
|
||||
}
|
||||
|
||||
public function Disable(string $sName, bool $bDisable) : bool
|
||||
{
|
||||
$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), ', '));
|
||||
}
|
||||
|
||||
public function Delete(string $sName) : bool
|
||||
{
|
||||
$bResult = true;
|
||||
$sRealFileName = $this->codeFileName($sName);
|
||||
|
||||
if (0 < \strlen($sName))
|
||||
{
|
||||
if (\file_exists($this->sDomainPath.'/'.$sRealFileName.'.ini'))
|
||||
{
|
||||
$bResult = \unlink($this->sDomainPath.'/'.$sRealFileName.'.ini');
|
||||
}
|
||||
else if (\file_exists($this->sDomainPath.'/'.$sRealFileName.'.alias'))
|
||||
{
|
||||
$bResult = \unlink($this->sDomainPath.'/'.$sRealFileName.'.alias');
|
||||
}
|
||||
}
|
||||
|
||||
if ($bResult)
|
||||
{
|
||||
$this->Disable($sName, false);
|
||||
}
|
||||
|
||||
if ($this->oCacher)
|
||||
{
|
||||
$this->oCacher->Delete($this->wildcardDomainsCacheKey());
|
||||
}
|
||||
|
||||
return $bResult;
|
||||
}
|
||||
|
||||
public function GetList(int $iOffset = 0, int $iLimit = 20, string $sSearch = '', bool $bIncludeAliases = true) : array
|
||||
{
|
||||
$aResult = array();
|
||||
$aWildCards = array();
|
||||
$aAliases = array();
|
||||
|
||||
// $aList = \glob($this->sDomainPath.'/*.{ini,alias}', GLOB_BRACE);
|
||||
$aList = @\array_diff(\scandir($this->sDomainPath), array('.', '..'));
|
||||
if (\is_array($aList))
|
||||
{
|
||||
foreach ($aList as $sFile)
|
||||
{
|
||||
$sName = $sFile;
|
||||
if ('.ini' === \substr($sName, -4) || '.alias' === \substr($sName, -6))
|
||||
{
|
||||
$bAlias = '.alias' === \substr($sName, -6);
|
||||
|
||||
$sName = \preg_replace('/\.(ini|alias)$/', '', $sName);
|
||||
$sName = $this->codeFileName($sName, true);
|
||||
|
||||
if ($bAlias)
|
||||
{
|
||||
if ($bIncludeAliases)
|
||||
{
|
||||
$aAliases[] = $sName;
|
||||
}
|
||||
}
|
||||
else if (false !== \strpos($sName, '*'))
|
||||
{
|
||||
$aWildCards[] = $sName;
|
||||
}
|
||||
else
|
||||
{
|
||||
$aResult[] = $sName;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
\sort($aResult, SORT_STRING);
|
||||
\sort($aAliases, SORT_STRING);
|
||||
\rsort($aWildCards, SORT_STRING);
|
||||
|
||||
$aResult = \array_merge($aResult, $aAliases, $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] = array(
|
||||
!\in_array($sName, $aDisabledNames),
|
||||
\in_array($sName, $aAliases)
|
||||
);
|
||||
}
|
||||
|
||||
return $aReturn;
|
||||
}
|
||||
|
||||
public function Count(string $sSearch = '', bool $bIncludeAliases = true) : int
|
||||
{
|
||||
return \count($this->GetList(0, 999, $sSearch, $bIncludeAliases));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,52 +5,18 @@ namespace RainLoop\Providers\Domain;
|
|||
interface DomainAdminInterface extends DomainInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* @param string $sName
|
||||
* @param bool $bDisable
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function Disable($sName, $bDisable);
|
||||
public function Disable(string $sName, bool $bDisable) : bool;
|
||||
|
||||
/**
|
||||
* @param string $sName
|
||||
* @param bool $bFindWithWildCard = false
|
||||
* @param bool $bCheckDisabled = true
|
||||
*
|
||||
* @return \RainLoop\Model\Domain|null
|
||||
*/
|
||||
public function Load($sName, $bFindWithWildCard = false, $bCheckDisabled = true);
|
||||
public function Load(string $sName, bool $bFindWithWildCard = false, bool $bCheckDisabled = true);
|
||||
|
||||
/**
|
||||
* @param \RainLoop\Model\Domain $oDomain
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function Save(\RainLoop\Model\Domain $oDomain);
|
||||
public function Save(\RainLoop\Model\Domain $oDomain) : bool;
|
||||
|
||||
/**
|
||||
* @param string $sName
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function Delete($sName);
|
||||
public function Delete(string $sName) : bool;
|
||||
|
||||
/**
|
||||
* @param int $iOffset = 0
|
||||
* @param int $iLimit = 20
|
||||
* @param int $sSearch = ''
|
||||
* @param bool $bIncludeAliases = true
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function GetList($iOffset = 0, $iLimit = 20, $sSearch = '', $bIncludeAliases = true);
|
||||
public function GetList(int $iOffset = 0, int $iLimit = 20, string $sSearch = '', bool $bIncludeAliases = true) : array;
|
||||
|
||||
/**
|
||||
* @param string $sSearch = ''
|
||||
* @param bool $bIncludeAliases = true
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function Count($sSearch = '', $bIncludeAliases = true);
|
||||
}
|
||||
public function Count(string $sSearch = '', bool $bIncludeAliases = true) : int;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,128 +9,72 @@ class Files extends \RainLoop\Providers\AbstractProvider
|
|||
*/
|
||||
private $oDriver;
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(\RainLoop\Providers\Files\IFiles $oDriver)
|
||||
{
|
||||
$this->oDriver = $oDriver;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \RainLoop\Model\Account $oAccount
|
||||
* @param string $sKey
|
||||
* @param resource $rSource
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function PutFile($oAccount, $sKey, $rSource)
|
||||
public function PutFile(\RainLoop\Model\Account $oAccount, string $sKey, resource $rSource) : bool
|
||||
{
|
||||
return $this->oDriver->PutFile($oAccount, $sKey, $rSource);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \RainLoop\Model\Account $oAccount
|
||||
* @param string $sKey
|
||||
* @param string $sSource
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function MoveUploadedFile($oAccount, $sKey, $sSource)
|
||||
public function MoveUploadedFile(\RainLoop\Model\Account $oAccount, string $sKey, string $sSource) : bool
|
||||
{
|
||||
return $this->oDriver->MoveUploadedFile($oAccount, $sKey, $sSource);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \RainLoop\Model\Account $oAccount
|
||||
* @param string $sKey
|
||||
* @param string $sOpenMode = 'rb'
|
||||
*
|
||||
* @return resource|bool
|
||||
*/
|
||||
public function GetFile($oAccount, $sKey, $sOpenMode = 'rb')
|
||||
public function GetFile(\RainLoop\Model\Account $oAccount, string $sKey, string $sOpenMode = 'rb')
|
||||
{
|
||||
return $this->oDriver->GetFile($oAccount, $sKey, $sOpenMode);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \RainLoop\Model\Account $oAccount
|
||||
* @param string $sKey
|
||||
*
|
||||
* @return string | bool
|
||||
*/
|
||||
public function GetFileName($oAccount, $sKey)
|
||||
public function GetFileName(\RainLoop\Model\Account $oAccount, string $sKey)
|
||||
{
|
||||
return $this->oDriver->GetFileName($oAccount, $sKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \RainLoop\Model\Account $oAccount
|
||||
* @param string $sKey
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function Clear($oAccount, $sKey)
|
||||
public function Clear(\RainLoop\Model\Account $oAccount, string $sKey) : bool
|
||||
{
|
||||
return $this->oDriver->Clear($oAccount, $sKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \RainLoop\Model\Account $oAccount
|
||||
* @param string $sKey
|
||||
*
|
||||
* @return int|bool
|
||||
*/
|
||||
public function FileSize($oAccount, $sKey)
|
||||
public function FileSize(\RainLoop\Model\Account $oAccount, string $sKey)
|
||||
{
|
||||
return $this->oDriver->FileSize($oAccount, $sKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \RainLoop\Model\Account $oAccount
|
||||
* @param string $sKey
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function FileExists($oAccount, $sKey)
|
||||
public function FileExists(\RainLoop\Model\Account $oAccount, string $sKey) : bool
|
||||
{
|
||||
return $this->oDriver->FileExists($oAccount, $sKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $iTimeToClearInHours = 24
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function GC($iTimeToClearInHours = 24)
|
||||
public function GC(int $iTimeToClearInHours = 24) : bool
|
||||
{
|
||||
return $this->oDriver ? $this->oDriver->GC($iTimeToClearInHours) : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function CloseAllOpenedFiles()
|
||||
public function CloseAllOpenedFiles() : bool
|
||||
{
|
||||
return $this->oDriver && \method_exists($this->oDriver, 'CloseAllOpenedFiles') ?
|
||||
$this->oDriver->CloseAllOpenedFiles() : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \RainLoop\Model\Account $oAccount
|
||||
* @param string $sKey
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function GenerateLocalFullFileName($oAccount, $sKey)
|
||||
public function GenerateLocalFullFileName(\RainLoop\Model\Account $oAccount, string $sKey) : string
|
||||
{
|
||||
return $this->oDriver ? $this->oDriver->GenerateLocalFullFileName($oAccount, $sKey) : '';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function IsActive()
|
||||
public function IsActive() : bool
|
||||
{
|
||||
return $this->oDriver instanceof \RainLoop\Providers\Files\IFiles;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,36 +14,18 @@ class FileStorage implements \RainLoop\Providers\Files\IFiles
|
|||
*/
|
||||
private $sDataPath;
|
||||
|
||||
/**
|
||||
* @param string $sStoragePath
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($sStoragePath)
|
||||
public function __construct(string $sStoragePath)
|
||||
{
|
||||
$this->aResources = array();
|
||||
$this->sDataPath = \rtrim(\trim($sStoragePath), '\\/');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \RainLoop\Model\Account $oAccount
|
||||
* @param string $sKey
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function GenerateLocalFullFileName($oAccount, $sKey)
|
||||
public function GenerateLocalFullFileName(\RainLoop\Model\Account $oAccount, string $sKey) : string
|
||||
{
|
||||
return $this->generateFullFileName($oAccount, $sKey, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \RainLoop\Model\Account $oAccount
|
||||
* @param string $sKey
|
||||
* @param resource $rSource
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function PutFile($oAccount, $sKey, $rSource)
|
||||
public function PutFile(\RainLoop\Model\Account $oAccount, string $sKey, resource $rSource) : bool
|
||||
{
|
||||
$bResult = false;
|
||||
if ($rSource)
|
||||
|
|
@ -58,27 +40,16 @@ class FileStorage implements \RainLoop\Providers\Files\IFiles
|
|||
return $bResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \RainLoop\Model\Account $oAccount
|
||||
* @param string $sKey
|
||||
* @param string $sSource
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function MoveUploadedFile($oAccount, $sKey, $sSource)
|
||||
public function MoveUploadedFile(\RainLoop\Model\Account $oAccount, string $sKey, string $sSource) : bool
|
||||
{
|
||||
return @\move_uploaded_file($sSource,
|
||||
$this->generateFullFileName($oAccount, $sKey, true));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \RainLoop\Model\Account $oAccount
|
||||
* @param string $sKey
|
||||
* @param string $sOpenMode = 'rb'
|
||||
*
|
||||
* @return resource|bool
|
||||
*/
|
||||
public function GetFile($oAccount, $sKey, $sOpenMode = 'rb')
|
||||
public function GetFile(\RainLoop\Model\Account $oAccount, string $sKey, string $sOpenMode = 'rb')
|
||||
{
|
||||
$mResult = false;
|
||||
$bCreate = !!\preg_match('/[wac]/', $sOpenMode);
|
||||
|
|
@ -98,12 +69,9 @@ class FileStorage implements \RainLoop\Providers\Files\IFiles
|
|||
}
|
||||
|
||||
/**
|
||||
* @param \RainLoop\Model\Account $oAccount
|
||||
* @param string $sKey
|
||||
*
|
||||
* @return string|bool
|
||||
*/
|
||||
public function GetFileName($oAccount, $sKey)
|
||||
public function GetFileName(\RainLoop\Model\Account $oAccount, string $sKey)
|
||||
{
|
||||
$mResult = false;
|
||||
$sFileName = $this->generateFullFileName($oAccount, $sKey);
|
||||
|
|
@ -115,13 +83,7 @@ class FileStorage implements \RainLoop\Providers\Files\IFiles
|
|||
return $mResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \RainLoop\Model\Account $oAccount
|
||||
* @param string $sKey
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function Clear($oAccount, $sKey)
|
||||
public function Clear(\RainLoop\Model\Account $oAccount, string $sKey) : bool
|
||||
{
|
||||
$mResult = true;
|
||||
$sFileName = $this->generateFullFileName($oAccount, $sKey);
|
||||
|
|
@ -139,12 +101,9 @@ class FileStorage implements \RainLoop\Providers\Files\IFiles
|
|||
}
|
||||
|
||||
/**
|
||||
* @param \RainLoop\Model\Account $oAccount
|
||||
* @param string $sKey
|
||||
*
|
||||
* @return int|bool
|
||||
*/
|
||||
public function FileSize($oAccount, $sKey)
|
||||
public function FileSize(\RainLoop\Model\Account $oAccount, string $sKey)
|
||||
{
|
||||
$mResult = false;
|
||||
$sFileName = $this->generateFullFileName($oAccount, $sKey);
|
||||
|
|
@ -156,23 +115,12 @@ class FileStorage implements \RainLoop\Providers\Files\IFiles
|
|||
return $mResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \RainLoop\Model\Account $oAccount
|
||||
* @param string $sKey
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function FileExists($oAccount, $sKey)
|
||||
public function FileExists(\RainLoop\Model\Account $oAccount, string $sKey) : bool
|
||||
{
|
||||
return @\file_exists($this->generateFullFileName($oAccount, $sKey));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $iTimeToClearInHours = 24
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function GC($iTimeToClearInHours = 24)
|
||||
public function GC(int $iTimeToClearInHours = 24) : bool
|
||||
{
|
||||
if (0 < $iTimeToClearInHours)
|
||||
{
|
||||
|
|
@ -183,10 +131,7 @@ class FileStorage implements \RainLoop\Providers\Files\IFiles
|
|||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function CloseAllOpenedFiles()
|
||||
public function CloseAllOpenedFiles() : bool
|
||||
{
|
||||
if (\is_array($this->aResources) && 0 < \count($this->aResources))
|
||||
{
|
||||
|
|
@ -202,14 +147,7 @@ class FileStorage implements \RainLoop\Providers\Files\IFiles
|
|||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \RainLoop\Model\Account $oAccount
|
||||
* @param string $sKey
|
||||
* @param bool $bMkDir = false
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function generateFullFileName($oAccount, $sKey, $bMkDir = false)
|
||||
private function generateFullFileName(\RainLoop\Model\Account $oAccount, string $sKey, bool $bMkDir = false) : string
|
||||
{
|
||||
$sEmail = $sSubEmail = '';
|
||||
if ($oAccount instanceof \RainLoop\Model\Account)
|
||||
|
|
|
|||
|
|
@ -4,77 +4,30 @@ namespace RainLoop\Providers\Files;
|
|||
|
||||
interface IFiles
|
||||
{
|
||||
/**
|
||||
* @param \RainLoop\Model\Account $oAccount
|
||||
* @param string $sKey
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function GenerateLocalFullFileName($oAccount, $sKey);
|
||||
public function GenerateLocalFullFileName(\RainLoop\Model\Account $oAccount, string $sKey) : string;
|
||||
|
||||
public function PutFile(\RainLoop\Model\Account $oAccount, string $sKey, resource $rSource) : bool;
|
||||
|
||||
public function MoveUploadedFile(\RainLoop\Model\Account $oAccount, string $sKey, string $sSource) : bool;
|
||||
|
||||
/**
|
||||
* @param \RainLoop\Model\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\Model\Account $oAccount
|
||||
* @param string $sKey
|
||||
* @param string $sOpenMode = 'rb'
|
||||
*
|
||||
* @return resource|bool
|
||||
*/
|
||||
public function GetFile($oAccount, $sKey, $sOpenMode = 'rb');
|
||||
public function GetFile(\RainLoop\Model\Account $oAccount, string $sKey, string $sOpenMode = 'rb');
|
||||
|
||||
/**
|
||||
* @param \RainLoop\Model\Account $oAccount
|
||||
* @param string $sKey
|
||||
*
|
||||
* @return string|bool
|
||||
*/
|
||||
public function GetFileName($oAccount, $sKey);
|
||||
public function GetFileName(\RainLoop\Model\Account $oAccount, string $sKey);
|
||||
|
||||
public function Clear(\RainLoop\Model\Account $oAccount, string $sKey) : bool;
|
||||
|
||||
/**
|
||||
* @param \RainLoop\Model\Account $oAccount
|
||||
* @param string $sKey
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function Clear($oAccount, $sKey);
|
||||
|
||||
/**
|
||||
* @param \RainLoop\Model\Account $oAccount
|
||||
* @param string $sKey
|
||||
*
|
||||
* @return int | bool
|
||||
*/
|
||||
public function FileSize($oAccount, $sKey);
|
||||
public function FileSize(\RainLoop\Model\Account $oAccount, string $sKey);
|
||||
|
||||
/**
|
||||
* @param \RainLoop\Model\Account $oAccount
|
||||
* @param string $sKey
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function FileExists($oAccount, $sKey);
|
||||
public function FileExists(\RainLoop\Model\Account $oAccount, string $sKey) : bool;
|
||||
|
||||
/**
|
||||
* @param int $iTimeToClearInHours = 24
|
||||
|
||||
* @return bool
|
||||
*/
|
||||
public function GC($iTimeToClearInHours = 24);
|
||||
public function GC(int $iTimeToClearInHours = 24) : bool;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,13 +17,7 @@ class Filters extends \RainLoop\Providers\AbstractProvider
|
|||
$this->oDriver = $oDriver instanceof \RainLoop\Providers\Filters\FiltersInterface ? $oDriver : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \RainLoop\Account $oAccount
|
||||
* @param bool $bAllowRaw = false
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function Load($oAccount, $bAllowRaw = false)
|
||||
public function Load(\RainLoop\Model\Account $oAccount, bool $bAllowRaw = false) : array
|
||||
{
|
||||
try
|
||||
{
|
||||
|
|
@ -33,7 +27,7 @@ class Filters extends \RainLoop\Providers\AbstractProvider
|
|||
{
|
||||
throw new \RainLoop\Exceptions\ClientException(\RainLoop\Notifications::ConnectionError, $oException);
|
||||
}
|
||||
catch (\Exception $oException)
|
||||
catch (\Throwable $oException)
|
||||
{
|
||||
throw new \RainLoop\Exceptions\ClientException(\RainLoop\Notifications::CantGetFilters, $oException);
|
||||
}
|
||||
|
|
@ -41,15 +35,7 @@ class Filters extends \RainLoop\Providers\AbstractProvider
|
|||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \RainLoop\Account $oAccount
|
||||
* @param array $aFilters
|
||||
* @param string $sRaw = ''
|
||||
* @param bool $bRawIsActive = false
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function Save($oAccount, $aFilters, $sRaw = '', $bRawIsActive = false)
|
||||
public function Save(\RainLoop\Model\Account $oAccount, array $aFilters, string $sRaw = '', bool $bRawIsActive = false) : bool
|
||||
{
|
||||
try
|
||||
{
|
||||
|
|
@ -66,7 +52,7 @@ class Filters extends \RainLoop\Providers\AbstractProvider
|
|||
\RainLoop\Notifications::ClientViewError, $oException,
|
||||
\implode("\r\n", $oException->GetResponses()));
|
||||
}
|
||||
catch (\Exception $oException)
|
||||
catch (\Throwable $oException)
|
||||
{
|
||||
throw new \RainLoop\Exceptions\ClientException(\RainLoop\Notifications::CantSaveFilters, $oException);
|
||||
}
|
||||
|
|
@ -74,11 +60,8 @@ class Filters extends \RainLoop\Providers\AbstractProvider
|
|||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function IsActive()
|
||||
public function IsActive() : bool
|
||||
{
|
||||
return $this->oDriver instanceof \RainLoop\Providers\Filters\FiltersInterface;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -101,122 +101,77 @@ class Filter
|
|||
$this->bStop = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function ID()
|
||||
public function ID() : string
|
||||
{
|
||||
return $this->sID;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function Enabled()
|
||||
public function Enabled() : bool
|
||||
{
|
||||
return $this->bEnabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function Name()
|
||||
public function Name() : string
|
||||
{
|
||||
return $this->sName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function Conditions()
|
||||
public function Conditions() : array
|
||||
{
|
||||
return $this->aConditions;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function ConditionsType()
|
||||
public function ConditionsType() : string
|
||||
{
|
||||
return $this->sConditionsType;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function ActionType()
|
||||
public function ActionType() : string
|
||||
{
|
||||
return $this->sActionType;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function ActionValue()
|
||||
public function ActionValue() : string
|
||||
{
|
||||
return $this->sActionValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function ActionValueSecond()
|
||||
public function ActionValueSecond() : string
|
||||
{
|
||||
return $this->sActionValueSecond;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function ActionValueThird()
|
||||
public function ActionValueThird() : string
|
||||
{
|
||||
return $this->sActionValueThird;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function ActionValueFourth()
|
||||
public function ActionValueFourth() : string
|
||||
{
|
||||
return $this->sActionValueFourth;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function MarkAsRead()
|
||||
public function MarkAsRead() : bool
|
||||
{
|
||||
return $this->bMarkAsRead;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function Stop()
|
||||
public function Stop() : bool
|
||||
{
|
||||
return $this->bStop;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function Keep()
|
||||
public function Keep() : bool
|
||||
{
|
||||
return $this->bKeep;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function serializeToJson()
|
||||
public function serializeToJson() : string
|
||||
{
|
||||
return \json_encode($this->ToSimpleJSON());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sFilterJson
|
||||
*/
|
||||
public function unserializeFromJson($sFilterJson)
|
||||
public function unserializeFromJson(string $sFilterJson)
|
||||
{
|
||||
$aFilterJson = \json_decode(\trim($sFilterJson), true);
|
||||
if (\is_array($aFilterJson))
|
||||
|
|
@ -227,12 +182,7 @@ class Filter
|
|||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $aFilter
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function FromJSON($aFilter)
|
||||
public function FromJSON(array $aFilter) : array
|
||||
{
|
||||
if (\is_array($aFilter))
|
||||
{
|
||||
|
|
@ -265,12 +215,7 @@ class Filter
|
|||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $bAjax = false
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function ToSimpleJSON($bAjax = false)
|
||||
public function ToSimpleJSON(bool $bAjax = false) : array
|
||||
{
|
||||
$aConditions = array();
|
||||
foreach ($this->Conditions() as $oItem)
|
||||
|
|
|
|||
|
|
@ -37,44 +37,27 @@ class FilterCondition
|
|||
$this->sValueSecond = '';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function Field()
|
||||
public function Field() : string
|
||||
{
|
||||
return $this->sField;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function Type()
|
||||
public function Type() : string
|
||||
{
|
||||
return $this->sType;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function Value()
|
||||
public function Value() : string
|
||||
{
|
||||
return $this->sValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function ValueSecond()
|
||||
public function ValueSecond() : string
|
||||
{
|
||||
return $this->sValueSecond;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $aData
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function FromJSON($aData)
|
||||
public function FromJSON(array $aData) : array
|
||||
{
|
||||
if (\is_array($aData))
|
||||
{
|
||||
|
|
@ -93,12 +76,7 @@ class FilterCondition
|
|||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $bAjax = false
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function ToSimpleJSON($bAjax = false)
|
||||
public function ToSimpleJSON(bool $bAjax = false) : array
|
||||
{
|
||||
return array(
|
||||
'Field' => $this->Field(),
|
||||
|
|
@ -108,10 +86,7 @@ class FilterCondition
|
|||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public static function CollectionFromJSON($aCollection)
|
||||
public static function CollectionFromJSON($aCollection) : array
|
||||
{
|
||||
$aResult = array();
|
||||
if (\is_array($aCollection) && 0 < \count($aCollection))
|
||||
|
|
|
|||
|
|
@ -4,19 +4,7 @@ namespace RainLoop\Providers\Filters;
|
|||
|
||||
interface FiltersInterface
|
||||
{
|
||||
/**
|
||||
* @param \RainLoop\Account $oAccount
|
||||
* @param bool $bAllowRaw = false
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function Load($oAccount, $bAllowRaw = false);
|
||||
public function Load(\RainLoop\Model\Account $oAccount, bool $bAllowRaw = false) : array;
|
||||
|
||||
/**
|
||||
* @param \RainLoop\Account $oAccount
|
||||
* @param array $aFilters
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function Save($oAccount, $aFilters);
|
||||
public function Save(\RainLoop\Model\Account $oAccount, array $aFilters) : bool;
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -1,390 +1,66 @@
|
|||
<?php
|
||||
|
||||
namespace RainLoop\Providers;
|
||||
|
||||
class Prem
|
||||
{
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($oConfig, $oLogger, $oCacher)
|
||||
{
|
||||
$this->oConfig = $oConfig;
|
||||
$this->oLogger = $oLogger;
|
||||
$this->oCacher = $oCacher;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function Type()
|
||||
{
|
||||
static $bResult = null;
|
||||
if (null === $bResult)
|
||||
{
|
||||
$bResult = $this->Parser($this->Fetcher(false, true));
|
||||
}
|
||||
|
||||
return $bResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function IsActive()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sInput
|
||||
* @param int $iExpired = 0
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function Parser($sInput, &$iExpired = 0)
|
||||
{
|
||||
$aMatch = array();
|
||||
if (\preg_match('/^EXPIRED:([\d]+)$/', $sInput, $aMatch))
|
||||
{
|
||||
$iExpired = (int) $aMatch[1];
|
||||
return \time() < $iExpired;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $aAppData
|
||||
*/
|
||||
public function PopulateAppData(&$aAppData)
|
||||
{
|
||||
if (\is_array($aAppData))
|
||||
{
|
||||
$aAppData['Community'] = false;
|
||||
|
||||
$oConfig = $this->oConfig;
|
||||
if ($oConfig && $this->Type())
|
||||
{
|
||||
$aAppData['PremType'] = true;
|
||||
$aAppData['LoginLogo'] = $oConfig->Get('branding', 'login_logo', '');
|
||||
$aAppData['LoginBackground'] = $oConfig->Get('branding', 'login_background', '');
|
||||
$aAppData['LoginCss'] = $oConfig->Get('branding', 'login_css', '');
|
||||
$aAppData['LoginDescription'] = $oConfig->Get('branding', 'login_desc', '');
|
||||
$aAppData['UserLogo'] = $oConfig->Get('branding', 'user_logo', '');
|
||||
$aAppData['UserLogoTitle'] = $oConfig->Get('branding', 'user_logo_title', '');
|
||||
$aAppData['UserLogoMessage'] = $oConfig->Get('branding', 'user_logo_message', '');
|
||||
$aAppData['UserIframeMessage'] = $oConfig->Get('branding', 'user_iframe_message', '');
|
||||
$aAppData['UserCss'] = $oConfig->Get('branding', 'user_css', '');
|
||||
$aAppData['WelcomePageUrl'] = $oConfig->Get('branding', 'welcome_page_url', '');
|
||||
$aAppData['WelcomePageDisplay'] = \strtolower($oConfig->Get('branding', 'welcome_page_display', 'none'));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function PremSection(&$oActions, &$oConfig)
|
||||
{
|
||||
if ($oActions && $oActions->HasOneOfActionParams(array(
|
||||
'LoginLogo', 'LoginBackground', 'LoginDescription', 'LoginCss',
|
||||
'UserLogo', 'UserLogoTitle', 'UserLogoMessage', 'UserIframeMessage', 'UserCss',
|
||||
'WelcomePageUrl', 'WelcomePageDisplay'
|
||||
)) && $this->Type())
|
||||
{
|
||||
$oActions->setConfigFromParams($oConfig, 'LoginLogo', 'branding', 'login_logo', 'string');
|
||||
$oActions->setConfigFromParams($oConfig, 'LoginBackground', 'branding', 'login_background', 'string');
|
||||
$oActions->setConfigFromParams($oConfig, 'LoginDescription', 'branding', 'login_desc', 'string');
|
||||
$oActions->setConfigFromParams($oConfig, 'LoginCss', 'branding', 'login_css', 'string');
|
||||
|
||||
$oActions->setConfigFromParams($oConfig, 'UserLogo', 'branding', 'user_logo', 'string');
|
||||
$oActions->setConfigFromParams($oConfig, 'UserLogoTitle', 'branding', 'user_logo_title', 'string');
|
||||
$oActions->setConfigFromParams($oConfig, 'UserLogoMessage', 'branding', 'user_logo_message', 'string');
|
||||
$oActions->setConfigFromParams($oConfig, 'UserIframeMessage', 'branding', 'user_iframe_message', 'string');
|
||||
$oActions->setConfigFromParams($oConfig, 'UserCss', 'branding', 'user_css', 'string');
|
||||
|
||||
$oActions->setConfigFromParams($oConfig, 'WelcomePageUrl', 'branding', 'welcome_page_url', 'string');
|
||||
$oActions->setConfigFromParams($oConfig, 'WelcomePageDisplay', 'branding', 'welcome_page_display', 'string');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function Activate($sDomain, $sKey, &$iCode)
|
||||
{
|
||||
$iCode = 0;
|
||||
$sContentType = '';
|
||||
|
||||
$oHttp = \MailSo\Base\Http::SingletonInstance();
|
||||
|
||||
$sResult = $oHttp->GetUrlAsString(APP_API_PATH.'activate/'.\urlencode($sDomain).'/'.\urlencode($sKey),
|
||||
'RainLoop/'.APP_VERSION, $sContentType, $iCode, $this->oLogger, 10,
|
||||
$this->oConfig->Get('labs', 'curl_proxy', ''), $this->oConfig->Get('labs', 'curl_proxy_auth', ''),
|
||||
array(), false
|
||||
);
|
||||
|
||||
if (200 !== $iCode)
|
||||
{
|
||||
$sResult = '';
|
||||
}
|
||||
|
||||
return $sResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function Fetcher($sForce = false, $bLongCache = false, $iFastCacheTimeInMin = 10, $iLongCacheTimeInDays = 3)
|
||||
{
|
||||
$sDomain = \trim(APP_SITE);
|
||||
|
||||
$oConfig = $this->oConfig;
|
||||
$oLogger = $this->oLogger;
|
||||
$oCacher = $this->oCacher;
|
||||
|
||||
$oHttp = \MailSo\Base\Http::SingletonInstance();
|
||||
|
||||
if (0 === \strlen($sDomain) || $oHttp->CheckLocalhost($sDomain) || !$oCacher || !$oConfig || !$oCacher->Verify(true))
|
||||
{
|
||||
return 'NO';
|
||||
}
|
||||
|
||||
$sDomainKeyValue = \RainLoop\KeyPathHelper::LicensingDomainKeyValue($sDomain);
|
||||
$sDomainLongKeyValue = \RainLoop\KeyPathHelper::LicensingDomainKeyOtherValue($sDomain);
|
||||
|
||||
$sValue = '';
|
||||
if (!$sForce)
|
||||
{
|
||||
if ($bLongCache)
|
||||
{
|
||||
$bLock = $oCacher->GetLock($sDomainLongKeyValue);
|
||||
$iTime = $bLock ? 0 : $oCacher->GetTimer($sDomainLongKeyValue);
|
||||
|
||||
if ($bLock || (0 < $iTime && \time() < $iTime + (60 * 60 * 24) * $iLongCacheTimeInDays))
|
||||
{
|
||||
$sValue = $oCacher->Get($sDomainLongKeyValue);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$iTime = $oCacher->GetTimer($sDomainKeyValue);
|
||||
if (0 < $iTime && \time() < $iTime + 60 * $iFastCacheTimeInMin)
|
||||
{
|
||||
$sValue = $oCacher->Get($sDomainKeyValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (0 === \strlen($sValue))
|
||||
{
|
||||
if ($bLongCache)
|
||||
{
|
||||
if (!$oCacher->SetTimer($sDomainLongKeyValue))
|
||||
{
|
||||
return 'NO';
|
||||
}
|
||||
|
||||
$oCacher->SetLock($sDomainLongKeyValue);
|
||||
}
|
||||
|
||||
$iCode = 0;
|
||||
$sContentType = '';
|
||||
|
||||
$sValue = $oHttp->GetUrlAsString(APP_API_PATH.'status/'.\urlencode($sDomain),
|
||||
'RainLoop/'.APP_VERSION, $sContentType, $iCode, $oLogger, 5,
|
||||
$oConfig->Get('labs', 'curl_proxy', ''), $oConfig->Get('labs', 'curl_proxy_auth', ''),
|
||||
array(), false
|
||||
);
|
||||
|
||||
if ($oLogger)
|
||||
{
|
||||
$oLogger->Write($sValue);
|
||||
}
|
||||
|
||||
if (404 === $iCode)
|
||||
{
|
||||
$sValue = 'NO';
|
||||
}
|
||||
else if (200 !== $iCode)
|
||||
{
|
||||
$sValue = '';
|
||||
}
|
||||
|
||||
$oCacher->SetTimer($sDomainKeyValue);
|
||||
|
||||
$oCacher->Set($sDomainKeyValue, $sValue);
|
||||
$oCacher->Set($sDomainLongKeyValue, $sValue);
|
||||
|
||||
if ($bLongCache)
|
||||
{
|
||||
$oCacher->RemoveLock($sDomainLongKeyValue);
|
||||
}
|
||||
}
|
||||
|
||||
return $sValue;
|
||||
}
|
||||
|
||||
public function ClearOldVersion()
|
||||
{
|
||||
$sVPath = APP_INDEX_ROOT_PATH.'rainloop/v/';
|
||||
|
||||
if ($this->oLogger)
|
||||
{
|
||||
$this->oLogger->Write('Versions GC: Begin');
|
||||
}
|
||||
|
||||
$aDirs = @\array_map('basename', @\array_filter(@\glob($sVPath.'*'), 'is_dir'));
|
||||
|
||||
if ($this->oLogger)
|
||||
{
|
||||
$this->oLogger->Write('Versions GC: Count:'.(\is_array($aDirs) ? \count($aDirs) : 0));
|
||||
}
|
||||
|
||||
if (\is_array($aDirs) && 5 < \count($aDirs))
|
||||
{
|
||||
\uasort($aDirs, 'version_compare');
|
||||
|
||||
foreach ($aDirs as $sName)
|
||||
{
|
||||
if (APP_DEV_VERSION !== $sName && APP_VERSION !== $sName)
|
||||
{
|
||||
if ($this->oLogger)
|
||||
{
|
||||
$this->oLogger->Write('Versions GC: Begin to remove "'.$sVPath.$sName.'" version');
|
||||
}
|
||||
|
||||
if (@\unlink($sVPath.$sName.'/index.php'))
|
||||
{
|
||||
@\MailSo\Base\Utils::RecRmDir($sVPath.$sName);
|
||||
}
|
||||
else
|
||||
{
|
||||
if ($this->oLogger)
|
||||
{
|
||||
$this->oLogger->Write('Versions GC (Error): index file cant be removed from"'.$sVPath.$sName.'"',
|
||||
\MailSo\Log\Enumerations\Type::ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->oLogger)
|
||||
{
|
||||
$this->oLogger->Write('Versions GC: End to remove "'.$sVPath.$sName.'" version');
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->oLogger)
|
||||
{
|
||||
$this->oLogger->Write('Versions GC: End');
|
||||
}
|
||||
}
|
||||
|
||||
public function UpdateCore($oActions, $sFile)
|
||||
{
|
||||
$bResult = false;
|
||||
|
||||
$sNewVersion = '';
|
||||
$sTmp = $oActions->downloadRemotePackageByUrl($sFile);
|
||||
if (!empty($sTmp))
|
||||
{
|
||||
include_once APP_VERSION_ROOT_PATH.'app/libraries/pclzip/pclzip.lib.php';
|
||||
|
||||
$oArchive = new \PclZip($sTmp);
|
||||
$sTmpFolder = APP_PRIVATE_DATA.\md5($sTmp);
|
||||
|
||||
\mkdir($sTmpFolder);
|
||||
if (\is_dir($sTmpFolder))
|
||||
{
|
||||
$bResult = 0 !== $oArchive->extract(PCLZIP_OPT_PATH, $sTmpFolder);
|
||||
if (!$bResult)
|
||||
{
|
||||
if ($this->oLogger)
|
||||
{
|
||||
$this->oLogger->Write('Cannot extract package files: '.$oArchive->errorInfo(), \MailSo\Log\Enumerations\Type::ERROR, 'INSTALLER');
|
||||
}
|
||||
}
|
||||
|
||||
if ($bResult && \file_exists($sTmpFolder.'/index.php') &&
|
||||
\is_writable(APP_INDEX_ROOT_PATH.'rainloop/') &&
|
||||
\is_writable(APP_INDEX_ROOT_PATH.'index.php') &&
|
||||
\is_dir($sTmpFolder.'/rainloop/'))
|
||||
{
|
||||
$aMatch = array();
|
||||
$sIndexFile = \file_get_contents($sTmpFolder.'/index.php');
|
||||
if (\preg_match('/\'APP_VERSION\', \'([^\']+)\'/', $sIndexFile, $aMatch) && !empty($aMatch[1]))
|
||||
{
|
||||
$sNewVersion = \trim($aMatch[1]);
|
||||
}
|
||||
|
||||
if (empty($sNewVersion))
|
||||
{
|
||||
if ($this->oLogger)
|
||||
{
|
||||
$this->oLogger->Write('Unknown version', \MailSo\Log\Enumerations\Type::ERROR, 'INSTALLER');
|
||||
}
|
||||
}
|
||||
else if (!\is_dir(APP_INDEX_ROOT_PATH.'rainloop/v/'.$sNewVersion))
|
||||
{
|
||||
\MailSo\Base\Utils::CopyDir($sTmpFolder.'/rainloop/', APP_INDEX_ROOT_PATH.'rainloop/');
|
||||
|
||||
if (\is_dir(APP_INDEX_ROOT_PATH.'rainloop/v/'.$sNewVersion) &&
|
||||
\is_file(APP_INDEX_ROOT_PATH.'rainloop/v/'.$sNewVersion.'/index.php'))
|
||||
{
|
||||
$bResult = \copy($sTmpFolder.'/index.php', APP_INDEX_ROOT_PATH.'index.php');
|
||||
|
||||
if ($bResult)
|
||||
{
|
||||
if (\MailSo\Base\Utils::FunctionExistsAndEnabled('opcache_invalidate'))
|
||||
{
|
||||
@\opcache_invalidate(APP_INDEX_ROOT_PATH.'index.php', true);
|
||||
}
|
||||
|
||||
if (\MailSo\Base\Utils::FunctionExistsAndEnabled('apc_delete_file'))
|
||||
{
|
||||
@\apc_delete_file(APP_INDEX_ROOT_PATH.'index.php');
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ($this->oLogger)
|
||||
{
|
||||
$this->oLogger->Write('Cannot copy new package files', \MailSo\Log\Enumerations\Type::ERROR, 'INSTALLER');
|
||||
$this->oLogger->Write($sTmpFolder.'/rainloop/ -> '.APP_INDEX_ROOT_PATH.'rainloop/', \MailSo\Log\Enumerations\Type::ERROR, 'INSTALLER');
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (!empty($sNewVersion))
|
||||
{
|
||||
if ($this->oLogger)
|
||||
{
|
||||
$this->oLogger->Write('"'.$sNewVersion.'" version already installed', \MailSo\Log\Enumerations\Type::ERROR, 'INSTALLER');
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ($bResult)
|
||||
{
|
||||
if ($this->oLogger)
|
||||
{
|
||||
$this->oLogger->Write('Cannot validate package files', \MailSo\Log\Enumerations\Type::ERROR, 'INSTALLER');
|
||||
}
|
||||
}
|
||||
|
||||
\MailSo\Base\Utils::RecRmDir($sTmpFolder);
|
||||
}
|
||||
else
|
||||
{
|
||||
if ($this->oLogger)
|
||||
{
|
||||
$this->oLogger->Write('Cannot create tmp folder: '.$sTmpFolder, \MailSo\Log\Enumerations\Type::ERROR, 'INSTALLER');
|
||||
}
|
||||
}
|
||||
|
||||
@\unlink($sTmp);
|
||||
}
|
||||
|
||||
return $bResult;
|
||||
}
|
||||
}
|
||||
<?php
|
||||
|
||||
namespace RainLoop\Providers;
|
||||
|
||||
class Prem
|
||||
{
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($oConfig, $oLogger, $oCacher)
|
||||
{
|
||||
$this->oConfig = $oConfig;
|
||||
$this->oLogger = $oLogger;
|
||||
$this->oCacher = $oCacher;
|
||||
}
|
||||
|
||||
public function PopulateAppData(array &$aAppData)
|
||||
{
|
||||
if (\is_array($aAppData))
|
||||
{
|
||||
$aAppData['Community'] = false;
|
||||
|
||||
$oConfig = $this->oConfig;
|
||||
if ($oConfig)
|
||||
{
|
||||
$aAppData['PremType'] = true;
|
||||
$aAppData['LoginLogo'] = $oConfig->Get('branding', 'login_logo', '');
|
||||
$aAppData['LoginBackground'] = $oConfig->Get('branding', 'login_background', '');
|
||||
$aAppData['LoginCss'] = $oConfig->Get('branding', 'login_css', '');
|
||||
$aAppData['LoginDescription'] = $oConfig->Get('branding', 'login_desc', '');
|
||||
$aAppData['UserLogo'] = $oConfig->Get('branding', 'user_logo', '');
|
||||
$aAppData['UserLogoTitle'] = $oConfig->Get('branding', 'user_logo_title', '');
|
||||
$aAppData['UserLogoMessage'] = $oConfig->Get('branding', 'user_logo_message', '');
|
||||
$aAppData['UserIframeMessage'] = $oConfig->Get('branding', 'user_iframe_message', '');
|
||||
$aAppData['UserCss'] = $oConfig->Get('branding', 'user_css', '');
|
||||
$aAppData['WelcomePageUrl'] = $oConfig->Get('branding', 'welcome_page_url', '');
|
||||
$aAppData['WelcomePageDisplay'] = \strtolower($oConfig->Get('branding', 'welcome_page_display', 'none'));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function PremSection(&$oActions, &$oConfig)
|
||||
{
|
||||
if ($oActions && $oActions->HasOneOfActionParams(array(
|
||||
'LoginLogo', 'LoginBackground', 'LoginDescription', 'LoginCss',
|
||||
'UserLogo', 'UserLogoTitle', 'UserLogoMessage', 'UserIframeMessage', 'UserCss',
|
||||
'WelcomePageUrl', 'WelcomePageDisplay'
|
||||
)))
|
||||
{
|
||||
$oActions->setConfigFromParams($oConfig, 'LoginLogo', 'branding', 'login_logo', 'string');
|
||||
$oActions->setConfigFromParams($oConfig, 'LoginBackground', 'branding', 'login_background', 'string');
|
||||
$oActions->setConfigFromParams($oConfig, 'LoginDescription', 'branding', 'login_desc', 'string');
|
||||
$oActions->setConfigFromParams($oConfig, 'LoginCss', 'branding', 'login_css', 'string');
|
||||
|
||||
$oActions->setConfigFromParams($oConfig, 'UserLogo', 'branding', 'user_logo', 'string');
|
||||
$oActions->setConfigFromParams($oConfig, 'UserLogoTitle', 'branding', 'user_logo_title', 'string');
|
||||
$oActions->setConfigFromParams($oConfig, 'UserLogoMessage', 'branding', 'user_logo_message', 'string');
|
||||
$oActions->setConfigFromParams($oConfig, 'UserIframeMessage', 'branding', 'user_iframe_message', 'string');
|
||||
$oActions->setConfigFromParams($oConfig, 'UserCss', 'branding', 'user_css', 'string');
|
||||
|
||||
$oActions->setConfigFromParams($oConfig, 'WelcomePageUrl', 'branding', 'welcome_page_url', 'string');
|
||||
$oActions->setConfigFromParams($oConfig, 'WelcomePageDisplay', 'branding', 'welcome_page_display', 'string');
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,18 +34,13 @@ class Settings extends \RainLoop\Providers\AbstractProvider
|
|||
/**
|
||||
* @param \RainLoop\Model\Account $oAccount
|
||||
* @param \RainLoop\Settings $oSettings
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function Save(\RainLoop\Model\Account $oAccount, \RainLoop\Settings $oSettings)
|
||||
public function Save(\RainLoop\Model\Account $oAccount, \RainLoop\Settings $oSettings) : bool
|
||||
{
|
||||
return $this->oDriver->Save($oAccount, $oSettings->DataAsArray());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function IsActive()
|
||||
public function IsActive() : bool
|
||||
{
|
||||
return $this->oDriver instanceof \RainLoop\Providers\Settings\ISettings;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,20 +12,12 @@ class DefaultSettings implements \RainLoop\Providers\Settings\ISettings
|
|||
*/
|
||||
private $oStorageProvider;
|
||||
|
||||
/**
|
||||
* @param \RainLoop\Providers\Storage $oStorageProvider
|
||||
*/
|
||||
public function __construct(\RainLoop\Providers\Storage $oStorageProvider)
|
||||
{
|
||||
$this->oStorageProvider = $oStorageProvider;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \RainLoop\Model\Account $oAccount
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function Load($oAccount)
|
||||
public function Load(\RainLoop\Model\Account $oAccount) : array
|
||||
{
|
||||
$sValue = $this->oStorageProvider->Get($oAccount,
|
||||
\RainLoop\Providers\Storage\Enumerations\StorageType::CONFIG,
|
||||
|
|
@ -47,13 +39,7 @@ class DefaultSettings implements \RainLoop\Providers\Settings\ISettings
|
|||
return $aSettings;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \RainLoop\Model\Account $oAccount
|
||||
* @param array $aSettings
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function Save($oAccount, array $aSettings)
|
||||
public function Save(\RainLoop\Model\Account $oAccount, array $aSettings) : bool
|
||||
{
|
||||
return $this->oStorageProvider->Put($oAccount,
|
||||
\RainLoop\Providers\Storage\Enumerations\StorageType::CONFIG,
|
||||
|
|
@ -63,12 +49,7 @@ class DefaultSettings implements \RainLoop\Providers\Settings\ISettings
|
|||
\json_encode($aSettings));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \RainLoop\Model\Account $oAccount
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function Delete($oAccount)
|
||||
public function Delete(\RainLoop\Model\Account $oAccount) : bool
|
||||
{
|
||||
return $this->oStorageProvider->Clear($oAccount,
|
||||
\RainLoop\Providers\Storage\Enumerations\StorageType::CONFIG,
|
||||
|
|
@ -76,4 +57,4 @@ class DefaultSettings implements \RainLoop\Providers\Settings\ISettings
|
|||
\RainLoop\Providers\Settings\DefaultSettings::FILE_NAME_LOCAL :
|
||||
\RainLoop\Providers\Settings\DefaultSettings::FILE_NAME);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,25 +4,9 @@ namespace RainLoop\Providers\Settings;
|
|||
|
||||
interface ISettings
|
||||
{
|
||||
/**
|
||||
* @param \RainLoop\Model\Account $oAccount
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function Load($oAccount);
|
||||
public function Load(\RainLoop\Model\Account $oAccount) : array;
|
||||
|
||||
/**
|
||||
* @param \RainLoop\Model\Account $oAccount
|
||||
* @param array $aSettings
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function Save($oAccount, array $aSettings);
|
||||
public function Save(\RainLoop\Model\Account $oAccount, array $aSettings) : bool;
|
||||
|
||||
/**
|
||||
* @param \RainLoop\Model\Account $oAccount
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function Delete($oAccount);
|
||||
}
|
||||
public function Delete(\RainLoop\Model\Account $oAccount) : bool;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,11 +19,8 @@ class Storage extends \RainLoop\Providers\AbstractProvider
|
|||
|
||||
/**
|
||||
* @param \RainLoop\Model\Account|string|null $mAccount
|
||||
* @param int $iStorageType
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function verifyAccount($mAccount, $iStorageType)
|
||||
private function verifyAccount($mAccount, int $iStorageType) : bool
|
||||
{
|
||||
if (\RainLoop\Providers\Storage\Enumerations\StorageType::NOBODY !== $iStorageType &&
|
||||
!($mAccount instanceof \RainLoop\Model\Account || \is_string($mAccount)))
|
||||
|
|
@ -36,13 +33,9 @@ class Storage extends \RainLoop\Providers\AbstractProvider
|
|||
|
||||
/**
|
||||
* @param \RainLoop\Model\Account|string|null $oAccount
|
||||
* @param int $iStorageType
|
||||
* @param string $sKey
|
||||
* @param string $sValue
|
||||
*
|
||||
* @return bool
|
||||
* @param mixed $sValue
|
||||
*/
|
||||
public function Put($oAccount, $iStorageType, $sKey, $sValue)
|
||||
public function Put($oAccount, int $iStorageType, string $sKey, $sValue) : bool
|
||||
{
|
||||
if (!$this->verifyAccount($oAccount, $iStorageType))
|
||||
{
|
||||
|
|
@ -54,13 +47,11 @@ class Storage extends \RainLoop\Providers\AbstractProvider
|
|||
|
||||
/**
|
||||
* @param \RainLoop\Model\Account|string|null $oAccount
|
||||
* @param int $iStorageType
|
||||
* @param string $sKey
|
||||
* @param mixed $mDefault = false
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function Get($oAccount, $iStorageType, $sKey, $mDefault = false)
|
||||
public function Get($oAccount, int $iStorageType, string $sKey, $mDefault = false)
|
||||
{
|
||||
if (!$this->verifyAccount($oAccount, $iStorageType))
|
||||
{
|
||||
|
|
@ -72,12 +63,8 @@ class Storage extends \RainLoop\Providers\AbstractProvider
|
|||
|
||||
/**
|
||||
* @param \RainLoop\Model\Account|string|null $oAccount
|
||||
* @param int $iStorageType
|
||||
* @param string $sKey
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function Clear($oAccount, $iStorageType, $sKey)
|
||||
public function Clear($oAccount, int $iStorageType, string $sKey) : bool
|
||||
{
|
||||
if (!$this->verifyAccount($oAccount, $iStorageType))
|
||||
{
|
||||
|
|
@ -89,26 +76,18 @@ class Storage extends \RainLoop\Providers\AbstractProvider
|
|||
|
||||
/**
|
||||
* @param \RainLoop\Model\Account|string $oAccount
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function DeleteStorage($oAccount)
|
||||
public function DeleteStorage($oAccount) : bool
|
||||
{
|
||||
return $this->oDriver->DeleteStorage($oAccount);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function IsActive()
|
||||
public function IsActive() : bool
|
||||
{
|
||||
return $this->oDriver instanceof \RainLoop\Providers\Storage\IStorage;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function IsLocal()
|
||||
public function IsLocal() : bool
|
||||
{
|
||||
return $this->oDriver instanceof \RainLoop\Providers\Storage\IStorage &&
|
||||
$this->oDriver->IsLocal();
|
||||
|
|
|
|||
|
|
@ -20,12 +20,9 @@ class FileStorage implements \RainLoop\Providers\Storage\IStorage
|
|||
protected $oLogger;
|
||||
|
||||
/**
|
||||
* @param string $sStoragePath
|
||||
* @param bool $bLocal = false
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($sStoragePath, $bLocal = false)
|
||||
public function __construct(string $sStoragePath, bool $bLocal = false)
|
||||
{
|
||||
$this->sDataPath = \rtrim(\trim($sStoragePath), '\\/');
|
||||
$this->bLocal = !!$bLocal;
|
||||
|
|
@ -34,13 +31,9 @@ class FileStorage implements \RainLoop\Providers\Storage\IStorage
|
|||
|
||||
/**
|
||||
* @param \RainLoop\Model\Account|string|null $oAccount
|
||||
* @param int $iStorageType
|
||||
* @param string $sKey
|
||||
* @param string $sValue
|
||||
*
|
||||
* @return bool
|
||||
* @param mixed $sValue
|
||||
*/
|
||||
public function Put($oAccount, $iStorageType, $sKey, $sValue)
|
||||
public function Put($oAccount, int $iStorageType, string $sKey, $sValue) : bool
|
||||
{
|
||||
return false !== @\file_put_contents(
|
||||
$this->generateFileName($oAccount, $iStorageType, $sKey, true), $sValue);
|
||||
|
|
@ -48,13 +41,11 @@ class FileStorage implements \RainLoop\Providers\Storage\IStorage
|
|||
|
||||
/**
|
||||
* @param \RainLoop\Model\Account|string|null $oAccount
|
||||
* @param int $iStorageType
|
||||
* @param string $sKey
|
||||
* @param mixed $mDefault = false
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function Get($oAccount, $iStorageType, $sKey, $mDefault = false)
|
||||
public function Get($oAccount, int $iStorageType, string $sKey, $mDefault = false)
|
||||
{
|
||||
$mValue = false;
|
||||
$sFileName = $this->generateFileName($oAccount, $iStorageType, $sKey);
|
||||
|
|
@ -68,12 +59,8 @@ class FileStorage implements \RainLoop\Providers\Storage\IStorage
|
|||
|
||||
/**
|
||||
* @param \RainLoop\Model\Account|string|null $oAccount
|
||||
* @param int $iStorageType
|
||||
* @param string $sKey
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function Clear($oAccount, $iStorageType, $sKey)
|
||||
public function Clear($oAccount, int $iStorageType, string $sKey) : bool
|
||||
{
|
||||
$mResult = true;
|
||||
$sFileName = $this->generateFileName($oAccount, $iStorageType, $sKey);
|
||||
|
|
@ -87,10 +74,8 @@ class FileStorage implements \RainLoop\Providers\Storage\IStorage
|
|||
|
||||
/**
|
||||
* @param \RainLoop\Model\Account|string $oAccount
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function DeleteStorage($oAccount)
|
||||
public function DeleteStorage($oAccount) : bool
|
||||
{
|
||||
$sPath = $this->generateFileName($oAccount,
|
||||
\RainLoop\Providers\Storage\Enumerations\StorageType::USER, 'xxx', false, true);
|
||||
|
|
@ -111,24 +96,15 @@ class FileStorage implements \RainLoop\Providers\Storage\IStorage
|
|||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function IsLocal()
|
||||
public function IsLocal() : bool
|
||||
{
|
||||
return $this->bLocal;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \RainLoop\Model\Account|string|null $mAccount
|
||||
* @param int $iStorageType
|
||||
* @param string $sKey
|
||||
* @param bool $bMkDir = false
|
||||
* @param bool $bForDeleteAction = false
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function generateFileName($mAccount, $iStorageType, $sKey, $bMkDir = false, $bForDeleteAction = false)
|
||||
public function generateFileName($mAccount, int $iStorageType, string $sKey, bool $bMkDir = false, bool $bForDeleteAction = false) : string
|
||||
{
|
||||
if (null === $mAccount)
|
||||
{
|
||||
|
|
@ -196,8 +172,8 @@ class FileStorage implements \RainLoop\Providers\Storage\IStorage
|
|||
/**
|
||||
* @param \MailSo\Log\Logger $oLogger
|
||||
*/
|
||||
public function SetLogger($oLogger)
|
||||
public function SetLogger(?\MailSo\Log\Logger $oLogger)
|
||||
{
|
||||
$this->oLogger = $oLogger instanceof \MailSo\Log\Logger ? $oLogger : null;
|
||||
$this->oLogger = $oLogger;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,35 +6,22 @@ interface IStorage
|
|||
{
|
||||
/**
|
||||
* @param \RainLoop\Model\Account|null $oAccount
|
||||
* @param int $iStorageType
|
||||
* @param string $sKey
|
||||
* @param string $sValue
|
||||
*
|
||||
* @return bool
|
||||
* @param mixed $sValue
|
||||
*/
|
||||
public function Put($oAccount, $iStorageType, $sKey, $sValue);
|
||||
public function Put($oAccount, int $iStorageType, int $sKey, $sValue) : bool;
|
||||
|
||||
/**
|
||||
* @param \RainLoop\Model\Account|null $oAccount
|
||||
* @param int $iStorageType
|
||||
* @param string $sKey
|
||||
* @param mixed $mDefault = false
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function Get($oAccount, $iStorageType, $sKey, $mDefault = false);
|
||||
public function Get($oAccount, int $iStorageType, string $sKey, $mDefault = false);
|
||||
|
||||
/**
|
||||
* @param \RainLoop\Model\Account|null $oAccount
|
||||
* @param int $iStorageType
|
||||
* @param string $sKey
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function Clear($oAccount, $iStorageType, $sKey);
|
||||
public function Clear($oAccount, int $iStorageType, string $sKey) : bool;
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function IsLocal();
|
||||
public function IsLocal() : bool;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,26 +6,20 @@ class TemproryApcStorage extends \RainLoop\Providers\Storage\FileStorage
|
|||
{
|
||||
/**
|
||||
* @param \RainLoop\Model\Account|string|null $oAccount
|
||||
* @param int $iStorageType
|
||||
* @param string $sKey
|
||||
* @param string $sValue
|
||||
*
|
||||
* @return bool
|
||||
* @param mixed $sValue
|
||||
*/
|
||||
public function Put($oAccount, $iStorageType, $sKey, $sValue)
|
||||
public function Put($oAccount, int $iStorageType, string $sKey, $sValue) : bool
|
||||
{
|
||||
return !!@\apc_store($this->generateFileName($oAccount, $iStorageType, $sKey, true), $sValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \RainLoop\Model\Account|string|null $oAccount
|
||||
* @param int $iStorageType
|
||||
* @param string $sKey
|
||||
* @param mixed $mDefault = false
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function Get($oAccount, $iStorageType, $sKey, $mDefault = false)
|
||||
public function Get($oAccount, int $iStorageType, string $sKey, $mDefault = false)
|
||||
{
|
||||
$bValue = false;
|
||||
$mValue = @\apc_fetch($this->generateFileName($oAccount, $iStorageType, $sKey), $bValue);
|
||||
|
|
@ -39,12 +33,8 @@ class TemproryApcStorage extends \RainLoop\Providers\Storage\FileStorage
|
|||
|
||||
/**
|
||||
* @param \RainLoop\Model\Account|string|null $oAccount
|
||||
* @param int $iStorageType
|
||||
* @param string $sKey
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function Clear($oAccount, $iStorageType, $sKey)
|
||||
public function Clear($oAccount, int $iStorageType, string $sKey) : bool
|
||||
{
|
||||
@\apc_delete($this->generateFileName($oAccount, $iStorageType, $sKey));
|
||||
|
||||
|
|
@ -53,24 +43,16 @@ class TemproryApcStorage extends \RainLoop\Providers\Storage\FileStorage
|
|||
|
||||
/**
|
||||
* @param \RainLoop\Model\Account|string $oAccount
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function DeleteStorage($oAccount)
|
||||
public function DeleteStorage($oAccount) : bool
|
||||
{
|
||||
return !!$oAccount;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \RainLoop\Model\Account|string|null $mAccount
|
||||
* @param int $iStorageType
|
||||
* @param string $sKey
|
||||
* @param bool $bMkDir = false
|
||||
* @param bool $bForDeleteAction = false
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function generateFileName($mAccount, $iStorageType, $sKey, $bMkDir = false, $bForDeleteAction = false)
|
||||
public function generateFileName($mAccount, int $iStorageType, string $sKey, bool $bMkDir = false, bool $bForDeleteAction = false) : string
|
||||
{
|
||||
$sFileName = parent::generateFileName($mAccount, $iStorageType, $sKey, false, false);
|
||||
return $sFileName.'/'.\RainLoop\Utils::GetConnectionToken().'/';
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ class Suggestions extends \RainLoop\Providers\AbstractProvider
|
|||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($aDriver = null)
|
||||
public function __construct(?array $aDriver = null)
|
||||
{
|
||||
if (\is_array($aDriver))
|
||||
{
|
||||
|
|
@ -26,14 +26,7 @@ class Suggestions extends \RainLoop\Providers\AbstractProvider
|
|||
$this->aDrivers = \is_array($aDriver) && 0 < \count($aDriver) ? $aDriver : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \RainLoop\Model\Account $oAccount
|
||||
* @param string $sQuery
|
||||
* @param int $iLimit = 20
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function Process($oAccount, $sQuery, $iLimit = 20)
|
||||
public function Process(\RainLoop\Model\Account $oAccount, string $sQuery, int $iLimit = 20) : array
|
||||
{
|
||||
$aSuggestions = array();
|
||||
if ($oAccount instanceof \RainLoop\Model\Account &&
|
||||
|
|
@ -63,11 +56,8 @@ class Suggestions extends \RainLoop\Providers\AbstractProvider
|
|||
return $aResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function IsActive()
|
||||
public function IsActive() : bool
|
||||
{
|
||||
return \is_array($this->aDrivers) && 0 < \count($this->aDrivers);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,11 +5,7 @@ namespace RainLoop\Providers\Suggestions;
|
|||
interface ISuggestions
|
||||
{
|
||||
/**
|
||||
* @param \RainLoop\Model\Account $oAccount
|
||||
* @param string $sQuery
|
||||
* @param int $iLimit = 20
|
||||
*
|
||||
* @return array [['email@1', 'name_1'], ['email@2', 'name_2']]
|
||||
*/
|
||||
public function Process($oAccount, $sQuery, $iLimit = 20);
|
||||
}
|
||||
public function Process(\RainLoop\Model\Account $oAccount, string $sQuery, int $iLimit = 20);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,116 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace RainLoop\Providers\Suggestions;
|
||||
|
||||
class OwnCloudSuggestions implements \RainLoop\Providers\Suggestions\ISuggestions
|
||||
{
|
||||
/**
|
||||
* @var \MailSo\Log\Logger
|
||||
*/
|
||||
protected $oLogger;
|
||||
|
||||
/**
|
||||
* @param \RainLoop\Model\Account $oAccount
|
||||
* @param string $sQuery
|
||||
* @param int $iLimit = 20
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function Process($oAccount, $sQuery, $iLimit = 20)
|
||||
{
|
||||
$iInputLimit = $iLimit;
|
||||
$aResult = array();
|
||||
$sQuery = \trim($sQuery);
|
||||
|
||||
try
|
||||
{
|
||||
if ('' === $sQuery || !$oAccount || !\RainLoop\Utils::IsOwnCloudLoggedIn())
|
||||
{
|
||||
return $aResult;
|
||||
}
|
||||
|
||||
$aParams = array('FN', 'NICKNAME', 'TITLE', 'EMAIL');
|
||||
if (\class_exists('OC') && isset(\OC::$server) && \method_exists(\OC::$server, 'getContactsManager'))
|
||||
{
|
||||
$cm = \OC::$server->getContactsManager();
|
||||
if (!$cm && !$cm->isEnabled())
|
||||
{
|
||||
return $aResult;
|
||||
}
|
||||
|
||||
$aSearchResult = $cm->search($sQuery, $aParams);
|
||||
}
|
||||
else if (\class_exists('OCP\Contacts') && \OCP\Contacts::isEnabled())
|
||||
{
|
||||
$aSearchResult = \OCP\Contacts::search($sQuery, $aParams);
|
||||
}
|
||||
else
|
||||
{
|
||||
return $aResult;
|
||||
}
|
||||
|
||||
//$this->oLogger->WriteDump($aSearchResult);
|
||||
|
||||
$aHashes = array();
|
||||
if (\is_array($aSearchResult) && 0 < \count($aSearchResult))
|
||||
{
|
||||
foreach ($aSearchResult as $aContact)
|
||||
{
|
||||
if (0 >= $iLimit)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
$sUid = empty($aContact['UID']) ? '' : $aContact['UID'];
|
||||
if (!empty($sUid))
|
||||
{
|
||||
$mEmails = isset($aContact['EMAIL']) ? $aContact['EMAIL'] : '';
|
||||
|
||||
$sFullName = isset($aContact['FN']) ? \trim($aContact['FN']) : '';
|
||||
if (empty($sFullName))
|
||||
{
|
||||
$sFullName = isset($aContact['NICKNAME']) ? \trim($aContact['NICKNAME']) : '';
|
||||
}
|
||||
|
||||
if (!\is_array($mEmails))
|
||||
{
|
||||
$mEmails = array($mEmails);
|
||||
}
|
||||
|
||||
foreach ($mEmails as $sEmail)
|
||||
{
|
||||
$sHash = '"'.$sFullName.'" <'.$sEmail.'>';
|
||||
if (!isset($aHashes[$sHash]))
|
||||
{
|
||||
$aHashes[$sHash] = true;
|
||||
$aResult[] = array($sEmail, $sFullName);
|
||||
$iLimit--;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$aResult = \array_slice($aResult, 0, $iInputLimit);
|
||||
}
|
||||
|
||||
unset($aSearchResult, $aHashes);
|
||||
}
|
||||
catch (\Exception $oException)
|
||||
{
|
||||
if ($this->oLogger)
|
||||
{
|
||||
$this->oLogger->WriteException($oException);
|
||||
}
|
||||
}
|
||||
|
||||
return $aResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \MailSo\Log\Logger $oLogger
|
||||
*/
|
||||
public function SetLogger($oLogger)
|
||||
{
|
||||
$this->oLogger = $oLogger instanceof \MailSo\Log\Logger ? $oLogger : null;
|
||||
}
|
||||
}
|
||||
|
|
@ -8,10 +8,8 @@ class TestSuggestions implements \RainLoop\Providers\Suggestions\ISuggestions
|
|||
* @param \RainLoop\Model\Account $oAccount
|
||||
* @param string $sQuery
|
||||
* @param int $iLimit = 20
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function Process($oAccount, $sQuery, $iLimit = 20)
|
||||
public function Process(\RainLoop\Model\Account $oAccount, string $sQuery, int $iLimit = 20) : array
|
||||
{
|
||||
return array(
|
||||
array($oAccount->Email(), ''),
|
||||
|
|
|
|||
|
|
@ -9,41 +9,23 @@ class TwoFactorAuth extends \RainLoop\Providers\AbstractProvider
|
|||
*/
|
||||
private $oDriver;
|
||||
|
||||
/**
|
||||
* @param \RainLoop\Providers\TwoFactorAuth\TwoFactorAuthInterface|null $oDriver = null
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($oDriver = null)
|
||||
public function __construct(?\RainLoop\Providers\TwoFactorAuth\TwoFactorAuthInterface $oDriver = null)
|
||||
{
|
||||
$this->oDriver = $oDriver;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function IsActive()
|
||||
public function IsActive() : bool
|
||||
{
|
||||
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 = '')
|
||||
public function GetQRCodeGoogleUrl(string $sName, string $sSecret, string $sTitle = '') : string
|
||||
{
|
||||
$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()
|
||||
public function CreateSecret() : string
|
||||
{
|
||||
$sResult = '';
|
||||
if ($this->IsActive())
|
||||
|
|
@ -53,14 +35,8 @@ class TwoFactorAuth extends \RainLoop\Providers\AbstractProvider
|
|||
|
||||
return $sResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sSecret
|
||||
* @param string $sCode
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function VerifyCode($sSecret, $sCode)
|
||||
|
||||
public function VerifyCode(string $sSecret, string $sCode) : bool
|
||||
{
|
||||
$bResult = false;
|
||||
if ($this->IsActive())
|
||||
|
|
|
|||
|
|
@ -4,20 +4,12 @@ namespace RainLoop\Providers\TwoFactorAuth;
|
|||
|
||||
abstract class AbstractTwoFactorAuth
|
||||
{
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function Label()
|
||||
public function Label() : string
|
||||
{
|
||||
return 'Two Factor Authenticator Code';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sSecret
|
||||
* @param string $sCode
|
||||
* @return bool
|
||||
*/
|
||||
public function VerifyCode($sSecret, $sCode)
|
||||
|
||||
public function VerifyCode(string $sSecret, string $sCode) : bool
|
||||
{
|
||||
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, 8);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function CreateSecret()
|
||||
{
|
||||
include_once APP_VERSION_ROOT_PATH.'app/libraries/PHPGangsta/GoogleAuthenticator.php';
|
||||
|
||||
$oGoogleAuthenticator = new \PHPGangsta_GoogleAuthenticator();
|
||||
return $oGoogleAuthenticator->createSecret();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,101 @@
|
|||
<?php
|
||||
|
||||
namespace RainLoop\Providers\TwoFactorAuth;
|
||||
|
||||
class TotpTwoFactorAuth
|
||||
extends \RainLoop\Providers\TwoFactorAuth\AbstractTwoFactorAuth
|
||||
implements \RainLoop\Providers\TwoFactorAuth\TwoFactorAuthInterface
|
||||
{
|
||||
public function VerifyCode(string $sSecret, string $sCode) : bool
|
||||
{
|
||||
$key = static::Base32Decode($sSecret);
|
||||
$algo = 'SHA1'; // Google Authenticator doesn't support SHA256
|
||||
$digits = 6; // Google Authenticator doesn't support 8
|
||||
$modulo = \pow(10, $digits);
|
||||
$timeSlice = \floor(\time() / 30);
|
||||
$discrepancy = 1;
|
||||
for ($i = -$discrepancy; $i <= $discrepancy; ++$i) {
|
||||
// Pack time into binary string
|
||||
$counter = \str_pad(\pack('N*', $timeSlice + $i), 8, "\x00", STR_PAD_LEFT);
|
||||
// Hash it with users secret key
|
||||
$hm = \hash_hmac($algo, $counter, $key, true);
|
||||
// Unpak 4 bytes of the result, use last nipple of result as index/offset
|
||||
$value = \unpack('N', \substr($hm, (\ord(\substr($hm, -1)) & 0x0F), 4));
|
||||
// Only 32 bits
|
||||
$value = $value[1] & 0x7FFFFFFF;
|
||||
$value = \str_pad($value % $modulo, $digits, '0', STR_PAD_LEFT);
|
||||
if (\hash_equals($value, $sCode)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function CreateSecret() : string
|
||||
{
|
||||
$CHARS = \array_keys(static::$map);
|
||||
$length = 16;
|
||||
$secret = '';
|
||||
while (0 < $length--) {
|
||||
$secret .= $CHARS[\random_int(0,31)];
|
||||
}
|
||||
return $secret;
|
||||
}
|
||||
|
||||
protected static $map = array(
|
||||
'A' => 0, // ord 65
|
||||
'B' => 1,
|
||||
'C' => 2,
|
||||
'D' => 3,
|
||||
'E' => 4,
|
||||
'F' => 5,
|
||||
'G' => 6,
|
||||
'H' => 7,
|
||||
'I' => 8,
|
||||
'J' => 9,
|
||||
'K' => 10,
|
||||
'L' => 11,
|
||||
'M' => 12,
|
||||
'N' => 13,
|
||||
'O' => 14,
|
||||
'P' => 15,
|
||||
'Q' => 16,
|
||||
'R' => 17,
|
||||
'S' => 18,
|
||||
'T' => 19,
|
||||
'U' => 20,
|
||||
'V' => 21,
|
||||
'W' => 22,
|
||||
'X' => 23,
|
||||
'Y' => 24,
|
||||
'Z' => 25, // ord 90
|
||||
'2' => 26, // ord 50
|
||||
'3' => 27,
|
||||
'4' => 28,
|
||||
'5' => 29,
|
||||
'6' => 30,
|
||||
'7' => 31 // ord 55
|
||||
);
|
||||
|
||||
protected static function Base32Decode(string $data)
|
||||
{
|
||||
$data = \strtoupper(\rtrim($data, "=\x20\t\n\r\0\x0B"));
|
||||
$dataSize = \strlen($data);
|
||||
$buf = 0;
|
||||
$bufSize = 0;
|
||||
$res = '';
|
||||
for ($i = 0; $i < $dataSize; ++$i) {
|
||||
$c = $data[$i];
|
||||
if (isset(static::$map[$c])) {
|
||||
$buf = ($buf << 5) | static::$map[$c];
|
||||
$bufSize += 5;
|
||||
if ($bufSize > 7) {
|
||||
$bufSize -= 8;
|
||||
$res .= \chr(($buf & (0xff << $bufSize)) >> $bufSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -4,11 +4,5 @@ namespace RainLoop\Providers\TwoFactorAuth;
|
|||
|
||||
interface TwoFactorAuthInterface
|
||||
{
|
||||
/**
|
||||
* @param string $sSecret
|
||||
* @param string $sCode
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function VerifyCode($sSecret, $sCode);
|
||||
public function VerifyCode(string $sSecret, string $sCode) : bool;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,342 +1,315 @@
|
|||
<?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);
|
||||
}
|
||||
|
||||
$sXssProtectionOptionsHeader = \trim($this->oActions->Config()->Get('security', 'x_xss_protection_header', ''));
|
||||
if (0 < \strlen($sXssProtectionOptionsHeader))
|
||||
{
|
||||
@\header('X-XSS-Protection: '.$sXssProtectionOptionsHeader, 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(0);
|
||||
}
|
||||
|
||||
$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;
|
||||
}
|
||||
|
||||
$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))
|
||||
{
|
||||
$sAdminPanelKey = \strtolower($this->oActions->Config()->Get('security', 'admin_panel_key', 'admin'));
|
||||
$bAdmin = !empty($aPaths[0]) && \strtolower($aPaths[0]) === $sAdminPanelKey;
|
||||
}
|
||||
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->oServiceActions->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' !== \strtolower($aPaths[0]))
|
||||
{
|
||||
$bIndex = false;
|
||||
$sMethodName = 'Service'.\preg_replace('/@.+$/', '', $aPaths[0]);
|
||||
$sMethodExtra = 0 < \strpos($aPaths[0], '@') ? \preg_replace('/^[^@]+@/', '', $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), $sMethodExtra);
|
||||
}
|
||||
else if (!$this->oActions->Plugins()->RunAdditionalPart($aPaths[0], $aPaths))
|
||||
{
|
||||
$bIndex = true;
|
||||
}
|
||||
}
|
||||
|
||||
$bMobile = false;
|
||||
$bMobileDevice = false;
|
||||
|
||||
if ($this->oActions->Config()->Get('labs', 'allow_mobile_version', false))
|
||||
{
|
||||
$bUseMobileVersionForTablets = $this->oActions->Config()->Get('labs', 'use_mobile_version_for_tablets', false);
|
||||
|
||||
$oMobileDetect = new \Detection\MobileDetect();
|
||||
$bMobileDevice = $oMobileDetect->isMobile() &&
|
||||
($bUseMobileVersionForTablets ? true : !$oMobileDetect->isTablet());
|
||||
|
||||
if ($bIndex)
|
||||
{
|
||||
$sMobileType = (string) \RainLoop\Utils::GetCookie(\RainLoop\Actions::RL_MOBILE_TYPE, '');
|
||||
switch ($sMobileType) {
|
||||
default:
|
||||
$sMobileType = '';
|
||||
$bMobile = $bMobileDevice;
|
||||
break;
|
||||
case 'mobile':
|
||||
$bMobile = true;
|
||||
break;
|
||||
case 'desktop':
|
||||
$bMobile = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($bIndex)
|
||||
{
|
||||
@\header('Content-Security-Policy:');
|
||||
@\header_remove('Content-Security-Policy');
|
||||
|
||||
@header('Content-Type: text/html; charset=utf-8');
|
||||
$this->oHttp->ServerNoCache();
|
||||
|
||||
if (!@\is_dir(APP_DATA_FOLDER_PATH) || !@\is_writable(APP_DATA_FOLDER_PATH))
|
||||
{
|
||||
echo $this->oServiceActions->ErrorTemplates(
|
||||
'Permission denied!',
|
||||
'RainLoop Webmail cannot access to the data folder "'.APP_DATA_FOLDER_PATH.'"'
|
||||
);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
$aTemplateParameters = $this->indexTemplateParameters($bAdmin, $bMobile, $bMobileDevice);
|
||||
|
||||
$sCacheFileName = '';
|
||||
if ($this->oActions->Config()->Get('labs', 'cache_system_data', true) && !empty($aTemplateParameters['{{BaseHash}}']))
|
||||
{
|
||||
$sCacheFileName = 'TMPL:'.$aTemplateParameters['{{BaseHash}}'];
|
||||
$sResult = $this->oActions->Cacher()->Get($sCacheFileName);
|
||||
}
|
||||
|
||||
if (0 === \strlen($sResult))
|
||||
{
|
||||
// $aTemplateParameters['{{BaseTemplates}}'] = $this->oServiceActions->compileTemplates($bAdmin, false);
|
||||
$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 .= '[time:'.\substr(\microtime(true) - APP_START, 0, 6);
|
||||
|
||||
// $sResult .= '][version:'.APP_VERSION;
|
||||
if ($this->oActions->IsOpen())
|
||||
{
|
||||
$sResult .= '][AGPLv3';
|
||||
}
|
||||
|
||||
$sResult .= '][cached:'.($bCached ? 'true' : 'false');
|
||||
// $sResult .= '][hash:'.$aTemplateParameters['{{BaseHash}}'];
|
||||
// $sResult .= '][session:'.\md5(\RainLoop\Utils::GetShortToken());
|
||||
|
||||
if ($bMobile)
|
||||
{
|
||||
$sResult .= '][mobile:true';
|
||||
}
|
||||
|
||||
if (\RainLoop\Utils::IsOwnCloud())
|
||||
{
|
||||
$sResult .= '][cloud:true';
|
||||
}
|
||||
|
||||
$sResult .= ']-->';
|
||||
}
|
||||
else
|
||||
{
|
||||
@\header('X-XSS-Protection: 1; mode=block');
|
||||
}
|
||||
|
||||
// Output result
|
||||
echo $sResult;
|
||||
unset($sResult);
|
||||
|
||||
$this->oActions->BootEnd();
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sPath
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function staticPath($sPath)
|
||||
{
|
||||
return $this->oActions->StaticPath($sPath);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $bAdmin = false
|
||||
* @param bool $bMobile = false
|
||||
* @param bool $bMobileDevice = false
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function indexTemplateParameters($bAdmin = false, $bMobile = false, $bMobileDevice = false)
|
||||
{
|
||||
$sLanguage = 'en';
|
||||
$sTheme = 'Default';
|
||||
|
||||
list($sLanguage, $sTheme) = $this->oActions->GetLanguageAndTheme($bAdmin, $bMobile);
|
||||
|
||||
$bAppJsDebug = !!$this->oActions->Config()->Get('labs', 'use_app_debug_js', false);
|
||||
$bAppCssDebug = !!$this->oActions->Config()->Get('labs', 'use_app_debug_css', false);
|
||||
|
||||
$sFaviconUrl = (string) $this->oActions->Config()->Get('webmail', 'favicon_url', '');
|
||||
|
||||
$sFaviconPngLink = $sFaviconUrl ? $sFaviconUrl : $this->staticPath('apple-touch-icon.png');
|
||||
$sAppleTouchLink = $sFaviconUrl ? '' : $this->staticPath('apple-touch-icon.png');
|
||||
|
||||
$sContentSecurityPolicy = $this->oActions->Config()->Get('security', 'content_security_policy', '');
|
||||
$sSentryDsn = $this->oActions->Config()->Get('logs', 'sentry_dsn', '');
|
||||
|
||||
$aTemplateParameters = array(
|
||||
'{{BaseAppHeadScriptLink}}' => $sSentryDsn ?
|
||||
'<script type="text/javascript" data-cfasync="false" src="https://browser.sentry-cdn.com/5.4.3/bundle.min.js" crossorigin="anonymous"></script>' : '',
|
||||
'{{BaseAppBodyScript}}' => $sSentryDsn ?
|
||||
'<script type="text/javascript" data-cfasync="false">window && window.Sentry && window.Sentry.init({dsn:\''.$sSentryDsn.'\',ignoreErrors:[\'Document not active\']});</script>' : '',
|
||||
'{{BaseAppFaviconPngLinkTag}}' => $sFaviconPngLink ? '<link type="image/png" rel="shortcut icon" href="'.$sFaviconPngLink.'" />' : '',
|
||||
'{{BaseAppFaviconTouchLinkTag}}' => $sAppleTouchLink ? '<link type="image/png" rel="apple-touch-icon" href="'.$sAppleTouchLink.'" />' : '',
|
||||
'{{BaseAppMainCssLink}}' => $this->staticPath('css/app'.($bAppCssDebug ? '' : '.min').'.css'),
|
||||
'{{BaseAppThemeCssLink}}' => $this->oActions->ThemeLink($sTheme, $bAdmin),
|
||||
'{{BaseAppPolyfillsScriptLink}}' => $this->staticPath('js/'.($bAppJsDebug ? '' : 'min/').'polyfills'.($bAppJsDebug ? '' : '.min').'.js'),
|
||||
'{{BaseAppBootScriptLink}}' => $this->staticPath('js/'.($bAppJsDebug ? '' : 'min/').'boot'.($bAppJsDebug ? '' : '.min').'.js'),
|
||||
'{{BaseViewport}}' => $bMobile ? 'width=device-width,initial-scale=1,user-scalable=no' : 'width=950,maximum-scale=2',
|
||||
'{{BaseContentSecurityPolicy}}' => $sContentSecurityPolicy ?
|
||||
'<meta http-equiv="Content-Security-Policy" content="'.$sContentSecurityPolicy.'" />' : '',
|
||||
'{{BaseDir}}' => false && \in_array($sLanguage, array('ar', 'he', 'ur')) ? 'rtl' : 'ltr',
|
||||
'{{BaseAppManifestLink}}' => $this->staticPath('manifest.json')
|
||||
);
|
||||
|
||||
$aTemplateParameters['{{RainloopBootData}}'] = \json_encode(array(
|
||||
'admin' => $bAdmin,
|
||||
'language' => $sLanguage,
|
||||
'theme' => $sTheme,
|
||||
'mobile' => $bMobile,
|
||||
'mobileDevice' => $bMobileDevice
|
||||
));
|
||||
|
||||
$aTemplateParameters['{{BaseHash}}'] = \md5(
|
||||
\implode('~', array(
|
||||
$bAdmin ? '1' : '0',
|
||||
\md5($this->oActions->Config()->Get('cache', 'index', '')),
|
||||
$this->oActions->Plugins()->Hash(),
|
||||
\RainLoop\Utils::WebVersionPath(),
|
||||
APP_VERSION,
|
||||
)).
|
||||
\implode('~', $aTemplateParameters)
|
||||
);
|
||||
|
||||
return $aTemplateParameters;
|
||||
}
|
||||
}
|
||||
<?php
|
||||
|
||||
namespace RainLoop;
|
||||
|
||||
class Service
|
||||
{
|
||||
/**
|
||||
* @var \MailSo\Base\Http
|
||||
*/
|
||||
private $oHttp;
|
||||
|
||||
/**
|
||||
* @var \RainLoop\Actions
|
||||
*/
|
||||
private $oActions;
|
||||
|
||||
/**
|
||||
* @var \RainLoop\ServiceActions
|
||||
*/
|
||||
private $oServiceActions;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
$sXssProtectionOptionsHeader = \trim($this->oActions->Config()->Get('security', 'x_xss_protection_header', ''));
|
||||
if (0 < \strlen($sXssProtectionOptionsHeader))
|
||||
{
|
||||
@\header('X-XSS-Protection: '.$sXssProtectionOptionsHeader, 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(0);
|
||||
}
|
||||
|
||||
$this->localHandle();
|
||||
}
|
||||
|
||||
public function RunResult() : bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @staticvar bool $bOne
|
||||
*/
|
||||
public static function Handle() : bool
|
||||
{
|
||||
static $bOne = null;
|
||||
if (null === $bOne)
|
||||
{
|
||||
$oService = null;
|
||||
if (\class_exists('MailSo\Version'))
|
||||
{
|
||||
$oService = new self();
|
||||
}
|
||||
|
||||
$bOne = $oService->RunResult();
|
||||
}
|
||||
|
||||
return $bOne;
|
||||
}
|
||||
|
||||
private function localHandle() : self
|
||||
{
|
||||
if (!\class_exists('MailSo\Version'))
|
||||
{
|
||||
return $this;
|
||||
}
|
||||
|
||||
$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))
|
||||
{
|
||||
$sAdminPanelKey = \strtolower($this->oActions->Config()->Get('security', 'admin_panel_key', 'admin'));
|
||||
$bAdmin = !empty($aPaths[0]) && \strtolower($aPaths[0]) === $sAdminPanelKey;
|
||||
}
|
||||
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->oServiceActions->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' !== \strtolower($aPaths[0]))
|
||||
{
|
||||
$bIndex = false;
|
||||
$sMethodName = 'Service'.\preg_replace('/@.+$/', '', $aPaths[0]);
|
||||
$sMethodExtra = 0 < \strpos($aPaths[0], '@') ? \preg_replace('/^[^@]+@/', '', $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), $sMethodExtra);
|
||||
}
|
||||
else if (!$this->oActions->Plugins()->RunAdditionalPart($aPaths[0], $aPaths))
|
||||
{
|
||||
$bIndex = true;
|
||||
}
|
||||
}
|
||||
|
||||
$bMobile = false;
|
||||
$bMobileDevice = false;
|
||||
|
||||
if ($this->oActions->Config()->Get('labs', 'allow_mobile_version', false))
|
||||
{
|
||||
$bUseMobileVersionForTablets = $this->oActions->Config()->Get('labs', 'use_mobile_version_for_tablets', false);
|
||||
|
||||
$oMobileDetect = new \Detection\MobileDetect();
|
||||
$bMobileDevice = $oMobileDetect->isMobile() &&
|
||||
($bUseMobileVersionForTablets ? true : !$oMobileDetect->isTablet());
|
||||
|
||||
if ($bIndex)
|
||||
{
|
||||
$sMobileType = (string) \RainLoop\Utils::GetCookie(\RainLoop\Actions::RL_MOBILE_TYPE, '');
|
||||
switch ($sMobileType) {
|
||||
default:
|
||||
$sMobileType = '';
|
||||
$bMobile = $bMobileDevice;
|
||||
break;
|
||||
case 'mobile':
|
||||
$bMobile = true;
|
||||
break;
|
||||
case 'desktop':
|
||||
$bMobile = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($bIndex)
|
||||
{
|
||||
@\header('Content-Security-Policy:');
|
||||
@\header_remove('Content-Security-Policy');
|
||||
|
||||
@header('Content-Type: text/html; charset=utf-8');
|
||||
$this->oHttp->ServerNoCache();
|
||||
|
||||
if (!@\is_dir(APP_DATA_FOLDER_PATH) || !@\is_writable(APP_DATA_FOLDER_PATH))
|
||||
{
|
||||
echo $this->oServiceActions->ErrorTemplates(
|
||||
'Permission denied!',
|
||||
'RainLoop Webmail cannot access to the data folder "'.APP_DATA_FOLDER_PATH.'"'
|
||||
);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
$aTemplateParameters = $this->indexTemplateParameters($bAdmin, $bMobile, $bMobileDevice);
|
||||
|
||||
$sCacheFileName = '';
|
||||
if ($this->oActions->Config()->Get('labs', 'cache_system_data', true) && !empty($aTemplateParameters['{{BaseHash}}']))
|
||||
{
|
||||
$sCacheFileName = 'TMPL:'.$aTemplateParameters['{{BaseHash}}'];
|
||||
$sResult = $this->oActions->Cacher()->Get($sCacheFileName);
|
||||
}
|
||||
|
||||
if (0 === \strlen($sResult))
|
||||
{
|
||||
// $aTemplateParameters['{{BaseTemplates}}'] = $this->oServiceActions->compileTemplates($bAdmin, false);
|
||||
$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 .= '[time:'.\substr(\microtime(true) - APP_START, 0, 6);
|
||||
|
||||
// $sResult .= '][version:'.APP_VERSION;
|
||||
if ($this->oActions->IsOpen())
|
||||
{
|
||||
$sResult .= '][AGPLv3';
|
||||
}
|
||||
|
||||
$sResult .= '][cached:'.($bCached ? 'true' : 'false');
|
||||
// $sResult .= '][hash:'.$aTemplateParameters['{{BaseHash}}'];
|
||||
// $sResult .= '][session:'.\md5(\RainLoop\Utils::GetShortToken());
|
||||
|
||||
if ($bMobile)
|
||||
{
|
||||
$sResult .= '][mobile:true';
|
||||
}
|
||||
|
||||
$sResult .= ']-->';
|
||||
}
|
||||
else
|
||||
{
|
||||
@\header('X-XSS-Protection: 1; mode=block');
|
||||
}
|
||||
|
||||
// Output result
|
||||
echo $sResult;
|
||||
unset($sResult);
|
||||
|
||||
$this->oActions->BootEnd();
|
||||
return $this;
|
||||
}
|
||||
|
||||
private function staticPath(string $sPath) : string
|
||||
{
|
||||
return $this->oActions->StaticPath($sPath);
|
||||
}
|
||||
|
||||
private function indexTemplateParameters(bool $bAdmin = false, bool $bMobile = false, bool $bMobileDevice = false) : array
|
||||
{
|
||||
$sLanguage = 'en';
|
||||
$sTheme = 'Default';
|
||||
|
||||
list($sLanguage, $sTheme) = $this->oActions->GetLanguageAndTheme($bAdmin, $bMobile);
|
||||
|
||||
$bAppJsDebug = !!$this->oActions->Config()->Get('labs', 'use_app_debug_js', false);
|
||||
$bAppCssDebug = !!$this->oActions->Config()->Get('labs', 'use_app_debug_css', false);
|
||||
|
||||
$sFaviconUrl = (string) $this->oActions->Config()->Get('webmail', 'favicon_url', '');
|
||||
|
||||
$sFaviconPngLink = $sFaviconUrl ? $sFaviconUrl : $this->staticPath('apple-touch-icon.png');
|
||||
$sAppleTouchLink = $sFaviconUrl ? '' : $this->staticPath('apple-touch-icon.png');
|
||||
|
||||
$sContentSecurityPolicy = $this->oActions->Config()->Get('security', 'content_security_policy', '');
|
||||
$sSentryDsn = $this->oActions->Config()->Get('logs', 'sentry_dsn', '');
|
||||
|
||||
$aTemplateParameters = array(
|
||||
'{{BaseAppHeadScriptLink}}' => $sSentryDsn ?
|
||||
'<script type="text/javascript" data-cfasync="false" src="https://browser.sentry-cdn.com/5.4.3/bundle.min.js" crossorigin="anonymous"></script>' : '',
|
||||
'{{BaseAppBodyScript}}' => $sSentryDsn ?
|
||||
'<script type="text/javascript" data-cfasync="false">window && window.Sentry && window.Sentry.init({dsn:\''.$sSentryDsn.'\',ignoreErrors:[\'Document not active\']});</script>' : '',
|
||||
'{{BaseAppFaviconPngLinkTag}}' => $sFaviconPngLink ? '<link type="image/png" rel="shortcut icon" href="'.$sFaviconPngLink.'" />' : '',
|
||||
'{{BaseAppFaviconTouchLinkTag}}' => $sAppleTouchLink ? '<link type="image/png" rel="apple-touch-icon" href="'.$sAppleTouchLink.'" />' : '',
|
||||
'{{BaseAppMainCssLink}}' => $this->staticPath('css/app'.($bAppCssDebug ? '' : '.min').'.css'),
|
||||
'{{BaseAppThemeCssLink}}' => $this->oActions->ThemeLink($sTheme, $bAdmin),
|
||||
'{{BaseAppPolyfillsScriptLink}}' => $this->staticPath('js/'.($bAppJsDebug ? '' : 'min/').'polyfills'.($bAppJsDebug ? '' : '.min').'.js'),
|
||||
'{{BaseAppBootScriptLink}}' => $this->staticPath('js/'.($bAppJsDebug ? '' : 'min/').'boot'.($bAppJsDebug ? '' : '.min').'.js'),
|
||||
'{{BaseViewport}}' => $bMobile ? 'width=device-width,initial-scale=1,user-scalable=no' : 'width=950,maximum-scale=2',
|
||||
'{{BaseContentSecurityPolicy}}' => $sContentSecurityPolicy ?
|
||||
'<meta http-equiv="Content-Security-Policy" content="'.$sContentSecurityPolicy.'" />' : '',
|
||||
'{{BaseDir}}' => false && \in_array($sLanguage, array('ar', 'he', 'ur')) ? 'rtl' : 'ltr',
|
||||
'{{BaseAppManifestLink}}' => $this->staticPath('manifest.json')
|
||||
);
|
||||
|
||||
$aTemplateParameters['{{RainloopBootData}}'] = \json_encode(array(
|
||||
'admin' => $bAdmin,
|
||||
'language' => $sLanguage,
|
||||
'theme' => $sTheme,
|
||||
'mobile' => $bMobile,
|
||||
'mobileDevice' => $bMobileDevice
|
||||
));
|
||||
|
||||
$aTemplateParameters['{{BaseHash}}'] = \md5(
|
||||
\implode('~', array(
|
||||
$bAdmin ? '1' : '0',
|
||||
\md5($this->oActions->Config()->Get('cache', 'index', '')),
|
||||
$this->oActions->Plugins()->Hash(),
|
||||
\RainLoop\Utils::WebVersionPath(),
|
||||
APP_VERSION,
|
||||
)).
|
||||
\implode('~', $aTemplateParameters)
|
||||
);
|
||||
|
||||
return $aTemplateParameters;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -17,18 +17,13 @@ class Settings
|
|||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($bLocal = false)
|
||||
public function __construct(bool $bLocal = false)
|
||||
{
|
||||
$this->aData = array();
|
||||
$this->bLocal = !!$bLocal;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $aData
|
||||
*
|
||||
* @return \RainLoop\Settings
|
||||
*/
|
||||
public function InitData($aData)
|
||||
public function InitData(array $aData) : self
|
||||
{
|
||||
if (\is_array($aData))
|
||||
{
|
||||
|
|
@ -38,41 +33,33 @@ class Settings
|
|||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function DataAsArray()
|
||||
public function DataAsArray() : array
|
||||
{
|
||||
return $this->aData;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function IsLocal()
|
||||
public function IsLocal() : bool
|
||||
{
|
||||
return $this->bLocal;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sName
|
||||
* @param mixed $mDefValue = null
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function GetConf($sName, $mDefValue = null)
|
||||
public function GetConf(string $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)
|
||||
public function SetConf(string $sName, $mValue)
|
||||
{
|
||||
$this->aData[$sName] = $mValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,815 +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;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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) && !empty($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);
|
||||
$sEncodedData = $oSettings->GetConf('TwitterAccessToken', '');
|
||||
|
||||
if (!empty($sEncodedData))
|
||||
{
|
||||
$aData = \RainLoop\Utils::DecodeKeyValues($sEncodedData);
|
||||
if (is_array($aData) && isset($aData['id']))
|
||||
{
|
||||
$this->oActions->StorageProvider()->Clear(null,
|
||||
\RainLoop\Providers\Storage\Enumerations\StorageType::NOBODY,
|
||||
$this->TwitterUserLoginStorageKey($oTwitter, $aData['id'])
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
$oSettings->SetConf('TwitterAccessToken', '');
|
||||
$oSettings->SetConf('TwitterSocialName', '');
|
||||
|
||||
return $this->oActions->SettingsProvider()->Save($oAccount, $oSettings);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function popupServiceResult($sTypeStr, $sLoginUrl, $bLogin, $iErrorCode)
|
||||
{
|
||||
$sResult = '';
|
||||
$bAppCssDebug = !!$this->oActions->Config()->Get('labs', 'use_app_debug_css', false);
|
||||
|
||||
$sIcon = $sTypeStr;
|
||||
if ('facebook' === $sIcon)
|
||||
{
|
||||
$sIcon = $sIcon.'-alt';
|
||||
}
|
||||
|
||||
if ($sLoginUrl)
|
||||
{
|
||||
$this->oHttp->ServerNoCache();
|
||||
@\header('Content-Type: text/html; charset=utf-8');
|
||||
|
||||
$sResult = \strtr(\file_get_contents(APP_VERSION_ROOT_PATH.'app/templates/Social.html'), array(
|
||||
'{{RefreshMeta}}' => '<meta http-equiv="refresh" content="0; URL='.$sLoginUrl.'" />',
|
||||
'{{Stylesheet}}' => $this->oActions->StaticPath('css/social'.($bAppCssDebug ? '' : '.min').'.css'),
|
||||
'{{Icon}}' => $sIcon,
|
||||
'{{Script}}' => ''
|
||||
));
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->oHttp->ServerNoCache();
|
||||
@\header('Content-Type: text/html; charset=utf-8');
|
||||
|
||||
$sCallBackType = $bLogin ? '_login' : '';
|
||||
$sConnectionFunc = 'rl_'.\md5(\RainLoop\Utils::GetConnectionToken()).'_'.$sTypeStr.$sCallBackType.'_service';
|
||||
|
||||
$sResult = \strtr(\file_get_contents(APP_VERSION_ROOT_PATH.'app/templates/Social.html'), array(
|
||||
'{{RefreshMeta}}' => '',
|
||||
'{{Stylesheet}}' => $this->oActions->StaticPath('css/social'.($bAppCssDebug ? '' : '.min').'.css'),
|
||||
'{{Icon}}' => $sIcon,
|
||||
'{{Script}}' => '<script data-cfasync="false">opener && opener.'.$sConnectionFunc.' && opener.'.
|
||||
$sConnectionFunc.'('.$iErrorCode.'); self && self.close && self.close();</script>'
|
||||
));
|
||||
}
|
||||
|
||||
return $sResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function GoogleRefreshToken($sAccessToken, $sRefreshToken)
|
||||
{
|
||||
$oGoogle = $this->GoogleConnector();
|
||||
if ($oGoogle)
|
||||
{
|
||||
$aRefreshTokenResponse = $oGoogle->getAccessToken('https://accounts.google.com/o/oauth2/token', 'refresh_token', array(
|
||||
'refresh_token' => $sRefreshToken
|
||||
));
|
||||
|
||||
return !empty($aRefreshTokenResponse['result']['access_token']) ? $aRefreshTokenResponse['result']['access_token'] : '';
|
||||
}
|
||||
|
||||
return $sAccessToken;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function GooglePopupService($bGmail = false)
|
||||
{
|
||||
$sLoginUrl = '';
|
||||
$oAccount = null;
|
||||
|
||||
$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, 3);
|
||||
|
||||
if (!$bGmail)
|
||||
{
|
||||
$bGmail = !empty($aParts[0]) ? '1' === (string) $aParts[0] : false;
|
||||
}
|
||||
|
||||
$sCheckToken = !empty($aParts[1]) ? $aParts[1] : '';
|
||||
$sCheckAuth = !empty($aParts[2]) ? $aParts[2] : '';
|
||||
}
|
||||
|
||||
$sRedirectUrl = $this->oHttp->GetFullUrl().'?SocialGoogle';
|
||||
if (!$this->oHttp->HasQuery('code'))
|
||||
{
|
||||
$aParams = array(
|
||||
'scope' => \trim(\implode(' ', array(
|
||||
'https://www.googleapis.com/auth/userinfo.email',
|
||||
'https://www.googleapis.com/auth/userinfo.profile',
|
||||
$bGmail ? 'https://mail.google.com/' : ''
|
||||
))),
|
||||
'state' => ($bGmail ? '1' : '0').'|'.\RainLoop\Utils::GetConnectionToken().'|'.$this->oActions->GetSpecAuthToken(),
|
||||
'response_type' => 'code'
|
||||
);
|
||||
|
||||
if ($bGmail)
|
||||
{
|
||||
$aParams['access_type'] = 'offline';
|
||||
// $aParams['prompt'] = 'consent';
|
||||
}
|
||||
|
||||
$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;
|
||||
}
|
||||
|
||||
$aAuthorizationCodeResponse = $oGoogle->getAccessToken('https://accounts.google.com/o/oauth2/token', 'authorization_code', array(
|
||||
'code' => $this->oHttp->GetQuery('code'),
|
||||
'redirect_uri' => $sRedirectUrl
|
||||
));
|
||||
|
||||
$sAccessToken = !empty($aAuthorizationCodeResponse['result']['access_token']) ? $aAuthorizationCodeResponse['result']['access_token'] : '';
|
||||
$sRefreshToken = !empty($aAuthorizationCodeResponse['result']['refresh_token']) ? $aAuthorizationCodeResponse['result']['refresh_token'] : '';
|
||||
|
||||
if (!empty($sAccessToken))
|
||||
{
|
||||
$oGoogle->setAccessToken($sAccessToken);
|
||||
$aUserInfoResponse = $oGoogle->fetch('https://www.googleapis.com/oauth2/v2/userinfo');
|
||||
|
||||
if (!empty($aUserInfoResponse['result']['id']))
|
||||
{
|
||||
if ($bLogin)
|
||||
{
|
||||
$aUserData = null;
|
||||
if ($bGmail)
|
||||
{
|
||||
if (!empty($aUserInfoResponse['result']['email']))
|
||||
{
|
||||
$aUserData = array(
|
||||
'Email' => $aUserInfoResponse['result']['email'],
|
||||
'Password' => \RainLoop\Model\Account::GenerateTokensPassword($sAccessToken, $sRefreshToken)
|
||||
);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$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']))
|
||||
{
|
||||
$iErrorCode = $this->loginProcess($oAccount, $aUserData['Email'], $aUserData['Password']);
|
||||
}
|
||||
else
|
||||
{
|
||||
$iErrorCode = \RainLoop\Notifications::SocialGoogleLoginAccessDisable;
|
||||
}
|
||||
}
|
||||
|
||||
if ($oAccount && !$bGmail)
|
||||
{
|
||||
$aUserData = array(
|
||||
'ID' => $aUserInfoResponse['result']['id'],
|
||||
'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('GoogleAccessToken', \RainLoop\Utils::EncodeKeyValues(array(
|
||||
'id' => $aUserInfoResponse['result']['id']
|
||||
)));
|
||||
|
||||
$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);
|
||||
}
|
||||
|
||||
return $this->popupServiceResult('google', $sLoginUrl, $bLogin, $iErrorCode);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function FacebookPopupService()
|
||||
{
|
||||
$sLoginUrl = '';
|
||||
$sSocialName = '';
|
||||
|
||||
$mData = false;
|
||||
$sUserData = '';
|
||||
$aUserData = false;
|
||||
$oAccount = null;
|
||||
|
||||
$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();
|
||||
|
||||
$sRedirectUrl = '';
|
||||
$oFacebook = $this->FacebookConnector($oAccount, $sRedirectUrl);
|
||||
if ($oFacebook)
|
||||
{
|
||||
try
|
||||
{
|
||||
$oRedirectLoginHelper = $oFacebook->getRedirectLoginHelper();
|
||||
$oAccessToken = $oRedirectLoginHelper->getAccessToken();
|
||||
|
||||
if (!$oAccessToken && !$this->oHttp->HasQuery('state'))
|
||||
{
|
||||
$sLoginUrl = $oFacebook->getRedirectLoginHelper()->getLoginUrl($sRedirectUrl.'&display=popup');
|
||||
}
|
||||
else if ($oAccessToken)
|
||||
{
|
||||
$oResponse = $oFacebook->get('/me?fields=id,name', (string) $oAccessToken);
|
||||
$oGraphUser = $oResponse->getGraphUser();
|
||||
|
||||
$mData = $oGraphUser->getId();
|
||||
$sSocialName = $oGraphUser->getName();
|
||||
|
||||
if ($oAccount)
|
||||
{
|
||||
if ($mData && 0 < \strlen($mData))
|
||||
{
|
||||
$aUserData = array(
|
||||
'id' => $mData,
|
||||
'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']))
|
||||
{
|
||||
$iErrorCode = $this->loginProcess($oAccount, $aUserData['Email'], $aUserData['Password']);
|
||||
}
|
||||
else
|
||||
{
|
||||
$iErrorCode = \RainLoop\Notifications::SocialFacebookLoginAccessDisable;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (\Exception $oException)
|
||||
{
|
||||
$this->oActions->Logger()->WriteException($oException, \MailSo\Log\Enumerations\Type::ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
return $this->popupServiceResult('facebook', $sLoginUrl, $bLogin, $iErrorCode);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function TwitterPopupService()
|
||||
{
|
||||
$sLoginUrl = '';
|
||||
|
||||
$sSocialName = '';
|
||||
$oAccount = null;
|
||||
|
||||
$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']))
|
||||
{
|
||||
$aAccessToken = $oTwitter->extract_params($oTwitter->response['response']);
|
||||
if ($aAccessToken && isset($aAccessToken['oauth_token']) && !empty($aAccessToken['user_id']))
|
||||
{
|
||||
$aAccessToken['id'] = $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(
|
||||
'id' => $aAccessToken['id'],
|
||||
'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['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']))
|
||||
{
|
||||
$iErrorCode = $this->loginProcess($oAccount, $aUserData['Email'], $aUserData['Password']);
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
return $this->popupServiceResult('twitter', $sLoginUrl, $bLogin, $iErrorCode);
|
||||
}
|
||||
|
||||
/**
|
||||
* @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\Model\Account|null $oAccount = null
|
||||
* @param string $sRedirectUrl = ''
|
||||
*
|
||||
* @return \RainLoop\Common\RainLoopFacebookRedirectLoginHelper|null
|
||||
*/
|
||||
public function FacebookConnector($oAccount = null, &$sRedirectUrl = '')
|
||||
{
|
||||
$oFacebook = false;
|
||||
$oConfig = $this->oActions->Config();
|
||||
$sAppID = \trim($oConfig->Get('social', 'fb_app_id', ''));
|
||||
$sAppSecret = \trim($oConfig->Get('social', 'fb_app_secret', ''));
|
||||
|
||||
if (\version_compare(PHP_VERSION, '5.4.0', '>=') &&
|
||||
$oConfig->Get('social', 'fb_enable', false) && '' !== $sAppID &&
|
||||
'' !== \trim($oConfig->Get('social', 'fb_app_secret', '')) &&
|
||||
\class_exists('Facebook\Facebook')
|
||||
)
|
||||
{
|
||||
$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 \Facebook\Facebook(array(
|
||||
'app_id' => $sAppID, // Replace {app-id} with your app id
|
||||
'app_secret' => $sAppSecret,
|
||||
'persistent_data_handler' => new \RainLoop\Common\FacebookRainLoopPersistentDataHandler(
|
||||
$oAccount, \RainLoop\Utils::GetConnectionToken(), $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->getApp()->getId()), $sFacebookUserId, APP_SALT));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function TwitterUserLoginStorageKey($oTwitter, $sTwitterUserId)
|
||||
{
|
||||
return \implode('_', array('twitter_2', \md5($oTwitter->config['consumer_secret']), $sTwitterUserId, APP_SALT));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \RainLoop\Model\Account|null $oAccount
|
||||
* @param string $sEmail
|
||||
* @param string $sPassword
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
private function loginProcess(&$oAccount, $sEmail, $sPassword)
|
||||
{
|
||||
$iErrorCode = \RainLoop\Notifications::UnknownError;
|
||||
|
||||
try
|
||||
{
|
||||
$oAccount = $this->oActions->LoginProcess($sEmail, $sPassword, '', '', false, true);
|
||||
if ($oAccount instanceof \RainLoop\Model\Account)
|
||||
{
|
||||
$this->oActions->AuthToken($oAccount);
|
||||
$iErrorCode = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
$oAccount = null;
|
||||
$iErrorCode = \RainLoop\Notifications::AuthError;
|
||||
}
|
||||
}
|
||||
catch (\RainLoop\Exceptions\ClientException $oException)
|
||||
{
|
||||
$iErrorCode = $oException->getCode();
|
||||
}
|
||||
catch (\Exception $oException)
|
||||
{
|
||||
unset($oException);
|
||||
$iErrorCode = \RainLoop\Notifications::UnknownError;
|
||||
}
|
||||
|
||||
return $iErrorCode;
|
||||
}
|
||||
}
|
||||
|
|
@ -18,20 +18,11 @@ class Utils
|
|||
|
||||
static $RsaKey = null;
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
private function __construct()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sFileName
|
||||
* @param string $sSignature
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
static public function PgpVerifyFile($sFileName, $sSignature)
|
||||
static public function PgpVerifyFile(string $sFileName, string $sSignature) : bool
|
||||
{
|
||||
$sKeyFile = APP_VERSION_ROOT_PATH.'app/resources/RainLoop.asc';
|
||||
if (\file_exists($sKeyFile) && \file_exists($sFileName) && !empty($sSignature))
|
||||
|
|
@ -43,10 +34,7 @@ class Utils
|
|||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
static public function RsaPrivateKey()
|
||||
static public function RsaPrivateKey() : string
|
||||
{
|
||||
if (!empty(\RainLoop\Utils::$RsaKey))
|
||||
{
|
||||
|
|
@ -60,12 +48,9 @@ class Utils
|
|||
}
|
||||
|
||||
/**
|
||||
* @param string $sString
|
||||
* @param string $sKey = ''
|
||||
*
|
||||
* @return string|false
|
||||
*/
|
||||
static public function EncryptStringRSA($sString, $sKey = '')
|
||||
static public function EncryptStringRSA(string $sString, string $sKey = '')
|
||||
{
|
||||
$sResult = '';
|
||||
$sKey = \md5($sKey);
|
||||
|
|
@ -103,12 +88,9 @@ class Utils
|
|||
}
|
||||
|
||||
/**
|
||||
* @param string $sString
|
||||
* @param string $sKey = ''
|
||||
*
|
||||
* @return string|false
|
||||
*/
|
||||
static public function DecryptStringRSA($sString, $sKey = '')
|
||||
static public function DecryptStringRSA(string $sString, string $sKey = '')
|
||||
{
|
||||
$sResult = '';
|
||||
$sKey = \md5($sKey);
|
||||
|
|
@ -140,35 +122,17 @@ class Utils
|
|||
return $sResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sString
|
||||
* @param string $sKey
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
static public function EncryptString($sString, $sKey)
|
||||
static public function EncryptString(string $sString, string $sKey) : string
|
||||
{
|
||||
return \MailSo\Base\Crypt::XxteaEncrypt($sString, $sKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sEncriptedString
|
||||
* @param string $sKey
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
static public function DecryptString($sEncriptedString, $sKey)
|
||||
static public function DecryptString(string $sEncriptedString, string $sKey) : string
|
||||
{
|
||||
return \MailSo\Base\Crypt::XxteaDecrypt($sEncriptedString, $sKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sString
|
||||
* @param string $sKey
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
static public function EncryptStringQ($sString, $sKey)
|
||||
static public function EncryptStringQ(string $sString, string $sKey) : string
|
||||
{
|
||||
// if (\MailSo\Base\Utils::FunctionExistsAndEnabled('openssl_pkey_get_private'))
|
||||
// {
|
||||
|
|
@ -180,13 +144,7 @@ class Utils
|
|||
$sKey.'Q'.\RainLoop\Utils::GetShortToken());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sEncriptedString
|
||||
* @param string $sKey
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
static public function DecryptStringQ($sEncriptedString, $sKey)
|
||||
static public function DecryptStringQ(string $sEncriptedString, string $sKey) : string
|
||||
{
|
||||
// if (\MailSo\Base\Utils::FunctionExistsAndEnabled('openssl_pkey_get_private'))
|
||||
// {
|
||||
|
|
@ -198,25 +156,13 @@ class Utils
|
|||
$sKey.'Q'.\RainLoop\Utils::GetShortToken());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $aValues
|
||||
* @param string $sCustomKey = ''
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
static public function EncodeKeyValues(array $aValues, $sCustomKey = '')
|
||||
static public function EncodeKeyValues(array $aValues, string $sCustomKey = '') : string
|
||||
{
|
||||
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 = '')
|
||||
static public function DecodeKeyValues(string $sEncodedValues, string $sCustomKey = '') : array
|
||||
{
|
||||
$aResult = @\unserialize(
|
||||
\RainLoop\Utils::DecryptString(
|
||||
|
|
@ -225,26 +171,14 @@ class Utils
|
|||
return \is_array($aResult) ? $aResult : array();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $aValues
|
||||
* @param string $sCustomKey = ''
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
static public function EncodeKeyValuesQ(array $aValues, $sCustomKey = '')
|
||||
static public function EncodeKeyValuesQ(array $aValues, string $sCustomKey = '') : string
|
||||
{
|
||||
return \MailSo\Base\Utils::UrlSafeBase64Encode(
|
||||
\RainLoop\Utils::EncryptStringQ(
|
||||
@\serialize($aValues), \md5(APP_SALT.$sCustomKey)));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sEncodedValues
|
||||
* @param string $sCustomKey = ''
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
static public function DecodeKeyValuesQ($sEncodedValues, $sCustomKey = '')
|
||||
static public function DecodeKeyValuesQ(string $sEncodedValues, string $sCustomKey = '') : array
|
||||
{
|
||||
$aResult = @\unserialize(
|
||||
\RainLoop\Utils::DecryptStringQ(
|
||||
|
|
@ -253,10 +187,7 @@ class Utils
|
|||
return \is_array($aResult) ? $aResult : array();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
static public function GetConnectionToken()
|
||||
static public function GetConnectionToken() : string
|
||||
{
|
||||
$sKey = 'rltoken';
|
||||
|
||||
|
|
@ -270,18 +201,12 @@ class Utils
|
|||
return \md5('Connection'.APP_SALT.$sToken.'Token'.APP_SALT);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
static public function Fingerprint()
|
||||
static public function Fingerprint() : string
|
||||
{
|
||||
return \md5(empty($_SERVER['HTTP_USER_AGENT']) ? 'RainLoopFingerprint' : $_SERVER['HTTP_USER_AGENT']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
static public function GetShortToken()
|
||||
static public function GetShortToken() : string
|
||||
{
|
||||
$sKey = 'rlsession';
|
||||
|
||||
|
|
@ -309,20 +234,12 @@ class Utils
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
static public function GetCsrfToken()
|
||||
static public function GetCsrfToken() : string
|
||||
{
|
||||
return \md5('Csrf'.APP_SALT.self::GetConnectionToken().'Token'.APP_SALT);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sPath
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function PathMD5($sPath)
|
||||
public static function PathMD5(string $sPath) : string
|
||||
{
|
||||
$sResult = '';
|
||||
if (@\is_dir($sPath))
|
||||
|
|
@ -340,12 +257,9 @@ class Utils
|
|||
}
|
||||
|
||||
/**
|
||||
* @param string $sFileName
|
||||
* @param array $aResultLang
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function ReadAndAddLang($sFileName, &$aResultLang)
|
||||
public static function ReadAndAddLang(string $sFileName, array &$aResultLang)
|
||||
{
|
||||
if (\file_exists($sFileName))
|
||||
{
|
||||
|
|
@ -392,12 +306,7 @@ class Utils
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sDir
|
||||
* @param string $sType = ''
|
||||
* @return array
|
||||
*/
|
||||
public static function FolderFiles($sDir, $sType = '')
|
||||
public static function FolderFiles(string $sDir, string $sType = '') : array
|
||||
{
|
||||
$aResult = array();
|
||||
if (@\is_dir($sDir))
|
||||
|
|
@ -422,12 +331,7 @@ class Utils
|
|||
return $aResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sHtml
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function ClearHtmlOutput($sHtml)
|
||||
public static function ClearHtmlOutput(string $sHtml) : string
|
||||
{
|
||||
// return $sHtml;
|
||||
return \trim(\str_replace('> <', '><',
|
||||
|
|
@ -439,11 +343,7 @@ class Utils
|
|||
))))));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sKey
|
||||
* @return bool
|
||||
*/
|
||||
public static function FastCheck($sKey)
|
||||
public static function FastCheck(string $sKey) : bool
|
||||
{
|
||||
$bResult = false;
|
||||
|
||||
|
|
@ -457,12 +357,7 @@ class Utils
|
|||
return $bResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $aList
|
||||
* @param string $sDirName
|
||||
* @param string $sNameSuffix = ''
|
||||
*/
|
||||
public static function CompileTemplates(&$aList, $sDirName, $sNameSuffix = '')
|
||||
public static function CompileTemplates(array &$aList, string $sDirName, string $sNameSuffix = '')
|
||||
{
|
||||
if (\file_exists($sDirName))
|
||||
{
|
||||
|
|
@ -477,11 +372,10 @@ class Utils
|
|||
}
|
||||
|
||||
/**
|
||||
* @param string $sName
|
||||
* @param mixed $mDefault = null
|
||||
* @return mixed
|
||||
*/
|
||||
public static function GetCookie($sName, $mDefault = null)
|
||||
public static function GetCookie(string $sName, $mDefault = null)
|
||||
{
|
||||
if (null === \RainLoop\Utils::$Cookies)
|
||||
{
|
||||
|
|
@ -491,7 +385,7 @@ class Utils
|
|||
return isset(\RainLoop\Utils::$Cookies[$sName]) ? \RainLoop\Utils::$Cookies[$sName] : $mDefault;
|
||||
}
|
||||
|
||||
public static function SetCookie($sName, $sValue = '', $iExpire = 0, $sPath = null, $sDomain = null, $bSecure = null, $bHttpOnly = true)
|
||||
public static function SetCookie(string $sName, string $sValue = '', int $iExpire = 0, ?string $sPath = null, ?string $sDomain = null, ?bool $bSecure = null, bool $bHttpOnly = true)
|
||||
{
|
||||
if (null === \RainLoop\Utils::$Cookies)
|
||||
{
|
||||
|
|
@ -513,7 +407,7 @@ class Utils
|
|||
@\setcookie($sName, $sValue, $iExpire, $sPath, $sDomain, $bSecure, $bHttpOnly);
|
||||
}
|
||||
|
||||
public static function ClearCookie($sName)
|
||||
public static function ClearCookie(string $sName)
|
||||
{
|
||||
if (null === \RainLoop\Utils::$Cookies)
|
||||
{
|
||||
|
|
@ -527,81 +421,27 @@ class Utils
|
|||
@\setcookie($sName, '', \time() - 3600 * 24 * 30, $sPath);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public static function IsOwnCloud()
|
||||
{
|
||||
return isset($_ENV['RAINLOOP_OWNCLOUD']) && $_ENV['RAINLOOP_OWNCLOUD'] &&
|
||||
\class_exists('OC');
|
||||
}
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public static function IsOwnCloudLoggedIn()
|
||||
{
|
||||
return self::IsOwnCloud() && \class_exists('OCP\User') && \OCP\User::isLoggedIn();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sV
|
||||
* @param bool $bEncode = false
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function UrlEncode($sV, $bEncode = false)
|
||||
public static function UrlEncode(string $sV, bool $bEncode = false) : string
|
||||
{
|
||||
return $bEncode ? \urlencode($sV) : $sV;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public static function WebPath()
|
||||
public static function WebPath() : string
|
||||
{
|
||||
$sAppPath = '';
|
||||
if (\RainLoop\Utils::IsOwnCloud())
|
||||
{
|
||||
if (\class_exists('OC_App'))
|
||||
{
|
||||
$sAppPath = \rtrim(\trim(\OC_App::getAppWebPath('rainloop')), '\\/').'/app/';
|
||||
}
|
||||
|
||||
if (empty($sAppPath))
|
||||
{
|
||||
$sUrl = \MailSo\Base\Http::SingletonInstance()->GetUrl();
|
||||
if ($sUrl && \preg_match('/\/index\.php\/apps\/rainloop/', $sUrl))
|
||||
{
|
||||
$sAppPath = \preg_replace('/\/index\.php\/apps\/rainloop.+$/',
|
||||
'/apps/rainloop/app/', $sUrl);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $sAppPath;
|
||||
}
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public static function WebVersionPath()
|
||||
public static function WebVersionPath() : string
|
||||
{
|
||||
return self::WebPath().'rainloop/v/'.APP_VERSION.'/';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public static function WebStaticPath()
|
||||
public static function WebStaticPath() : string
|
||||
{
|
||||
return self::WebVersionPath().'static/';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $aSuggestions
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function RemoveSuggestionDuplicates($aSuggestions)
|
||||
public static function RemoveSuggestionDuplicates(array $aSuggestions) : array
|
||||
{
|
||||
$aResult = array();
|
||||
|
||||
|
|
@ -622,13 +462,7 @@ class Utils
|
|||
return $aResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sFileName
|
||||
* @param bool $bProcessSections = false
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function CustomParseIniFile($sFileName, $bProcessSections = false)
|
||||
public static function CustomParseIniFile(string $sFileName, bool $bProcessSections = false) : array
|
||||
{
|
||||
// if (\MailSo\Base\Utils::FunctionExistsAndEnabled('parse_ini_file'))
|
||||
// {
|
||||
|
|
@ -639,7 +473,7 @@ class Utils
|
|||
return \is_string($sData) ? @\parse_ini_string($sData, !!$bProcessSections) : null;
|
||||
}
|
||||
|
||||
public static function CustomBaseConvert($sNumberInput, $sFromBaseInput = '0123456789', $sToBaseInput = '0123456789')
|
||||
public static function CustomBaseConvert(string $sNumberInput, string $sFromBaseInput = '0123456789', string $sToBaseInput = '0123456789')
|
||||
{
|
||||
if ($sFromBaseInput === $sToBaseInput)
|
||||
{
|
||||
|
|
@ -687,4 +521,4 @@ class Utils
|
|||
|
||||
return $mRetVal;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue