Small fixes

This commit is contained in:
RainLoop Team 2014-11-06 21:52:07 +04:00
parent ada2094d56
commit 0587d66d45
20 changed files with 294 additions and 2867 deletions

View file

@ -41,6 +41,7 @@
'Prefetch': 'PREFETCH',
'Gravatar': 'GRAVATAR',
'Themes': 'THEMES',
'UserBackground': 'USER_BACKGROUND',
'Filters': 'FILTERS',
'AdditionalAccounts': 'ADDITIONAL_ACCOUNTS',
'AdditionalIdentities': 'ADDITIONAL_IDENTITIES'

View file

@ -874,7 +874,8 @@
Globals.sAnimationType = Enums.InterfaceAnimation.Full;
oData.capaThemes = ko.observable(false);
oData.capaThemes = ko.observable(true);
oData.capaUserBackground = ko.observable(false);
oData.allowLanguagesOnSettings = ko.observable(true);
oData.allowLanguagesOnLogin = ko.observable(true);

View file

@ -26,8 +26,9 @@
this.language = Data.language;
this.theme = Data.theme;
this.allowLanguagesOnSettings = Data.allowLanguagesOnSettings;
this.capaThemes = Data.capaThemes;
this.capaUserBackground = Data.capaUserBackground;
this.allowLanguagesOnSettings = Data.allowLanguagesOnSettings;
this.capaGravatar = Data.capaGravatar;
this.capaAdditionalAccounts = Data.capaAdditionalAccounts;
this.capaAdditionalIdentities = Data.capaAdditionalIdentities;
@ -119,6 +120,12 @@
});
});
self.capaUserBackground.subscribe(function (bValue) {
Remote.saveAdminConfig(null, {
'CapaUserBackground': bValue ? '1' : '0'
});
});
self.allowLanguagesOnSettings.subscribe(function (bValue) {
Remote.saveAdminConfig(null, {
'AllowLanguagesOnSettings': bValue ? '1' : '0'

View file

@ -49,6 +49,7 @@
this.weakPassword(!!Settings.settingsGet('WeakPassword'));
this.capaThemes(Settings.capa(Enums.Capa.Themes));
this.capaUserBackground(Settings.capa(Enums.Capa.UserBackground));
this.allowLanguagesOnLogin(!!Settings.settingsGet('AllowLanguagesOnLogin'));
this.allowLanguagesOnSettings(!!Settings.settingsGet('AllowLanguagesOnSettings'));
this.useLocalProxyForExternalImages(!!Settings.settingsGet('UseLocalProxyForExternalImages'));

View file

@ -99,6 +99,6 @@ class FolderInformation
*/
public function IsFlagSupported($sFlag)
{
return in_array('\\*', $this->PermanentFlags) || in_array($sFlag, $this->PermanentFlags);
return \in_array('\\*', $this->PermanentFlags) || \in_array($sFlag, $this->PermanentFlags);
}
}

View file

@ -192,23 +192,27 @@ class MailClient
* @param string $sFolderName
* @param string $sMessageFlag
* @param bool $bSetAction = true
* @param bool $sSkipUnsupportedFlag = false
*
* @throws \MailSo\Base\Exceptions\InvalidArgumentException
* @throws \MailSo\Net\Exceptions\Exception
* @throws \MailSo\Imap\Exceptions\Exception
* @throws \MailSo\Mail\Exceptions\Exception
*/
public function MessageSetFlagToAll($sFolderName, $sMessageFlag, $bSetAction = true)
public function MessageSetFlagToAll($sFolderName, $sMessageFlag, $bSetAction = true, $sSkipUnsupportedFlag = false)
{
$this->oImapClient->FolderSelect($sFolderName);
$oFolderInfo = $this->oImapClient->FolderCurrentInformation();
if (!$oFolderInfo || !$oFolderInfo->IsFlagSupported($sMessageFlag))
{
throw new \MailSo\Mail\Exceptions\RuntimeException('Message flag is not supported.');
if (!$sSkipUnsupportedFlag)
{
throw new \MailSo\Mail\Exceptions\RuntimeException('Message flag "'.$sMessageFlag.'" is not supported.');
}
}
if (0 < $oFolderInfo->Exists)
if ($oFolderInfo && 0 < $oFolderInfo->Exists)
{
$sStoreAction = $bSetAction
? \MailSo\Imap\Enumerations\StoreAction::ADD_FLAGS_SILENT
@ -241,7 +245,7 @@ class MailClient
{
if (!$sSkipUnsupportedFlag)
{
throw new \MailSo\Mail\Exceptions\RuntimeException('Message flag is not supported.');
throw new \MailSo\Mail\Exceptions\RuntimeException('Message flag "'.$sMessageFlag.'" is not supported.');
}
}
else
@ -269,7 +273,7 @@ class MailClient
public function MessageSetFlagged($sFolderName, $aIndexRange, $bIndexIsUid, $bSetAction = true)
{
$this->MessageSetFlag($sFolderName, $aIndexRange, $bIndexIsUid,
\MailSo\Imap\Enumerations\MessageFlag::FLAGGED, $bSetAction);
\MailSo\Imap\Enumerations\MessageFlag::FLAGGED, $bSetAction, true);
}
/**
@ -282,7 +286,7 @@ class MailClient
*/
public function MessageSetSeenToAll($sFolderName, $bSetAction = true)
{
$this->MessageSetFlagToAll($sFolderName, \MailSo\Imap\Enumerations\MessageFlag::SEEN, $bSetAction);
$this->MessageSetFlagToAll($sFolderName, \MailSo\Imap\Enumerations\MessageFlag::SEEN, $bSetAction, true);
}
/**
@ -298,7 +302,7 @@ class MailClient
public function MessageSetSeen($sFolderName, $aIndexRange, $bIndexIsUid, $bSetAction = true)
{
$this->MessageSetFlag($sFolderName, $aIndexRange, $bIndexIsUid,
\MailSo\Imap\Enumerations\MessageFlag::SEEN, $bSetAction);
\MailSo\Imap\Enumerations\MessageFlag::SEEN, $bSetAction, true);
}
/**
@ -321,7 +325,7 @@ class MailClient
throw new \MailSo\Base\Exceptions\InvalidArgumentException();
}
$this->oImapClient->FolderExamine($sFolderName);
$this->oImapClient->FolderSelect($sFolderName);
$oBodyStructure = null;
$oMessage = false;
@ -421,7 +425,7 @@ class MailClient
throw new \MailSo\Base\Exceptions\InvalidArgumentException();
}
$this->oImapClient->FolderExamine($sFolderName);
$this->oImapClient->FolderSelect($sFolderName);
$sFileName = '';
$sContentType = '';
@ -720,7 +724,7 @@ class MailClient
if (0 < \strlen($sPrevUidNext) && (string) $sPrevUidNext !== (string) $sCurrentUidNext)
{
$this->oImapClient->FolderExamine($sFolderName);
$this->oImapClient->FolderSelect($sFolderName);
$aFetchResponse = $this->oImapClient->Fetch(array(
\MailSo\Imap\Enumerations\FetchType::INDEX,
@ -796,7 +800,7 @@ class MailClient
$bSelect = false;
if ($this->IsGmail())
{
$this->oImapClient->FolderExamine($sFolderName);
$this->oImapClient->FolderSelect($sFolderName);
$bSelect = true;
}
@ -804,7 +808,7 @@ class MailClient
{
if (!$bSelect)
{
$this->oImapClient->FolderExamine($sFolderName);
$this->oImapClient->FolderSelect($sFolderName);
}
$aFetchResponse = $this->oImapClient->Fetch(array(
@ -1800,7 +1804,7 @@ class MailClient
throw new \MailSo\Base\Exceptions\InvalidArgumentException();
}
$this->oImapClient->FolderExamine($sFolderName);
$this->oImapClient->FolderSelect($sFolderName);
$oMessageCollection = MessageCollection::NewInstance();
$oMessageCollection->FolderName = $sFolderName;

View file

@ -2277,9 +2277,11 @@ class Actions
$bMainCache = false;
$bFilesCache = false;
$bVersionsCache = false;
$iOneDay1 = 60 * 60 * 23;
$iOneDay2 = 60 * 60 * 25;
$iOneDay3 = 60 * 60 * 30;
$sTimers = $this->StorageProvider()->Get(null,
\RainLoop\Providers\Storage\Enumerations\StorageType::NOBODY, 'Cache/Timers', '');
@ -2288,6 +2290,7 @@ class Actions
$iMainCacheTime = !empty($aTimers[0]) && \is_numeric($aTimers[0]) ? (int) $aTimers[0] : 0;
$iFilesCacheTime = !empty($aTimers[1]) && \is_numeric($aTimers[1]) ? (int) $aTimers[1] : 0;
$iVersionsCacheTime = !empty($aTimers[2]) && \is_numeric($aTimers[2]) ? (int) $aTimers[2] : 0;
if (0 === $iMainCacheTime || $iMainCacheTime + $iOneDay1 < \time())
{
@ -2301,13 +2304,19 @@ class Actions
$iFilesCacheTime = \time();
}
if ($bMainCache || $bFilesCache)
if (0 === $iVersionsCacheTime || $iVersionsCacheTime + $iOneDay3 < \time())
{
$bVersionsCache = true;
$iVersionsCacheTime = \time();
}
if ($bMainCache || $bFilesCache || $bVersionsCache)
{
if (!$this->StorageProvider()->Put(null,
\RainLoop\Providers\Storage\Enumerations\StorageType::NOBODY, 'Cache/Timers',
\implode(',', array($iMainCacheTime, $iFilesCacheTime))))
\implode(',', array($iMainCacheTime, $iFilesCacheTime, $iVersionsCacheTime))))
{
$bMainCache = $bFilesCache = false;
$bMainCache = $bFilesCache = $bVersionsCache = false;
}
}
@ -2317,13 +2326,16 @@ class Actions
$this->Cacher()->GC(48);
$this->Logger()->Write('Cacher GC: End');
}
if ($bFilesCache)
else if ($bFilesCache)
{
$this->Logger()->Write('Files GC: Begin');
$this->FilesProvider()->GC(48);
$this->Logger()->Write('Files GC: End');
}
else if ($bVersionsCache)
{
$this->removeOldVersion();
}
$this->Plugins()->RunHook('service.app-delay-start-end');
@ -2420,6 +2432,9 @@ class Actions
case \RainLoop\Enumerations\Capa::THEMES:
$this->setConfigFromParams($oConfig, $sParamName, 'webmail', 'allow_themes', 'bool');
break;
case \RainLoop\Enumerations\Capa::USER_BACKGROUND:
$this->setConfigFromParams($oConfig, $sParamName, 'webmail', 'allow_user_background', 'bool');
break;
case \RainLoop\Enumerations\Capa::OPEN_PGP:
$this->setConfigFromParams($oConfig, $sParamName, 'security', 'openpgp', 'bool');
break;
@ -2510,11 +2525,11 @@ class Actions
$this->setCapaFromParams($oConfig, 'CapaOpenPGP', \RainLoop\Enumerations\Capa::OPEN_PGP);
$this->setCapaFromParams($oConfig, 'CapaGravatar', \RainLoop\Enumerations\Capa::GRAVATAR);
$this->setCapaFromParams($oConfig, 'CapaThemes', \RainLoop\Enumerations\Capa::THEMES);
$this->setCapaFromParams($oConfig, 'CapaUserBackground', \RainLoop\Enumerations\Capa::USER_BACKGROUND);
$this->setConfigFromParams($oConfig, 'DetermineUserLanguage', 'login', 'determine_user_language', 'bool');
$this->setConfigFromParams($oConfig, 'DetermineUserDomain', 'login', 'determine_user_domain', 'bool');
if ($this->HasOneOfActionParams(array('Title', 'LoadingDescription', 'LoginLogo', 'LoginDescription', 'LoginCss', 'LoginPowered')) && $this->PremType())
{
$this->setConfigFromParams($oConfig, 'Title', 'webmail', 'title', 'string');
@ -3311,6 +3326,7 @@ class Actions
$this->IsAdminLoggined();
$bReal = false;
$sNewVersion = '';
$bRainLoopUpdatable = $this->rainLoopUpdatable();
$bRainLoopAccess = $this->rainLoopCoreAccess();
@ -3347,7 +3363,6 @@ class Actions
\is_dir($sTmpFolder.'/rainloop/'))
{
$aMatch = array();
$sNewVersion = '';
$sIndexFile = \file_get_contents($sTmpFolder.'/index.php');
if (\preg_match('/\'APP_VERSION\', \'([^\']+)\'/', $sIndexFile, $aMatch) && !empty($aMatch[1]))
{
@ -3397,6 +3412,40 @@ class Actions
return $this->DefaultResponse(__FUNCTION__, $bResult);
}
public function removeOldVersion()
{
$this->Logger()->Write('Versions GC: Begin');
$iLimitToDelete = 3;
$sVPath = APP_INDEX_ROOT_PATH.'rainloop/v/';
$aDirs = @\array_map('basename', @\array_filter(@\glob($sVPath.'*'), 'is_dir'));
if (\is_array($aDirs) && 5 < \count($aDirs))
{
\uasort($aDirs, 'version_compare');
foreach ($aDirs as $sName)
{
if (APP_DEV_VERSION !== $sName && APP_VERSION !== $sName)
{
$this->Logger()->Write('Versions GC: Begin to remove "'.$sVPath.$sName.'" version');
@\MailSo\Base\Utils::RecRmDir($sVPath.$sName);
$this->Logger()->Write('Versions GC: End to remove "'.$sVPath.$sName.'" version');
$iLimitToDelete--;
if (0 > $iLimitToDelete)
{
break;
}
}
}
}
$this->Logger()->Write('Versions GC: End');
}
/**
* @return array
*/
@ -6208,39 +6257,24 @@ class Actions
public function Upload()
{
$oAccount = $this->getAccountFromToken();
$oConfig = $this->Config();
$sInputName = 'uploader';
$aResponse = array();
$iError = UploadError::UNKNOWN;
$iSizeLimit = ((int) $oConfig->Get('webmail', 'attachment_size_limit', 0)) * 1024 * 1024;
if ($oAccount)
{
$iError = UPLOAD_ERR_OK;
$_FILES = isset($_FILES) ? $_FILES : null;
if (isset($_FILES, $_FILES[$sInputName], $_FILES[$sInputName]['name'], $_FILES[$sInputName]['tmp_name'], $_FILES[$sInputName]['size']))
{
$iError = (isset($_FILES[$sInputName]['error'])) ? (int) $_FILES[$sInputName]['error'] : UPLOAD_ERR_OK;
$aFile = $this->GetActionParam('File', null);
$iError = $this->GetActionParam('Error', \RainLoop\Enumerations\UploadError::UNKNOWN);
if (UPLOAD_ERR_OK === $iError && 0 < $iSizeLimit && $iSizeLimit < (int) $_FILES[$sInputName]['size'])
if ($oAccount && UPLOAD_ERR_OK === $iError && \is_array($aFile))
{
$iError = UploadError::CONFIG_SIZE;
$sSavedName = 'upload-post-'.\md5($aFile['name'].$aFile['tmp_name']);
if (!$this->FilesProvider()->MoveUploadedFile($oAccount, $sSavedName, $aFile['tmp_name']))
{
$iError = \RainLoop\Enumerations\UploadError::ON_SAVING;
}
$sSavedName = 'upload-post-'.md5($_FILES[$sInputName]['name'].$_FILES[$sInputName]['tmp_name']);
if (UPLOAD_ERR_OK === $iError)
else
{
if (!$this->FilesProvider()->MoveUploadedFile($oAccount, $sSavedName, $_FILES[$sInputName]['tmp_name']))
{
$iError = UploadError::ON_SAVING;
}
}
$sUploadName = $_FILES[$sInputName]['name'];
$iSize = $_FILES[$sInputName]['size'];
$sMimeType = $_FILES[$sInputName]['type'];
$sUploadName = $aFile['name'];
$iSize = $aFile['size'];
$sMimeType = $aFile['type'];
$aResponse['Attachment'] = array(
'Name' => $sUploadName,
@ -6249,20 +6283,13 @@ class Actions
'Size' => (int) $iSize
);
}
else if (!isset($_FILES) || !is_array($_FILES) || 0 === count($_FILES))
{
$iError = UPLOAD_ERR_INI_SIZE;
}
else
{
$iError = UploadError::EMPTY_FILES_DATA;
}
}
if (UPLOAD_ERR_OK !== $iError)
{
$iClientError = UploadClientError::NORMAL;
$iClientError = \RainLoop\Enumerations\UploadClientError::NORMAL;
$sError = $this->getUploadErrorMessageByCode($iError, $iClientError);
if (!empty($sError))
{
$aResponse['ErrorCode'] = $iClientError;
@ -6273,6 +6300,136 @@ class Actions
return $this->DefaultResponse(__FUNCTION__, $aResponse);
}
/**
* @return array
*/
public function UploadBackground()
{
$oAccount = $this->getAccountFromToken();
$bResponse = false;
$aFile = $this->GetActionParam('File', null);
$iError = $this->GetActionParam('Error', \RainLoop\Enumerations\UploadError::UNKNOWN);
if ($oAccount && UPLOAD_ERR_OK === $iError && \is_array($aFile))
{
$sSavedName = 'upload-post-'.\md5($aFile['name'].$aFile['tmp_name']);
if (!$this->FilesProvider()->MoveUploadedFile($oAccount, $sSavedName, $aFile['tmp_name']))
{
$iError = \RainLoop\Enumerations\UploadError::ON_SAVING;
}
else
{
$rData = $this->FilesProvider()->GetFile($oAccount, $sSavedName);
if (@\is_resource($rData))
{
$sData = @\stream_get_contents($rData);
if (!empty($sData) && 0 < \strlen($sData))
{
$bResponse = $this->StorageProvider()->Put($oAccount,
\RainLoop\Providers\Storage\Enumerations\StorageType::USER,
\RainLoop\KeyPathHelper::UserBackground($oAccount->Email()),
\base64_encode($sData)
);
}
unset($sData);
}
if (@\is_resource($rData))
{
@\fclose($rData);
}
unset($rData);
}
$this->FilesProvider()->Clear($oAccount, $sSavedName);
}
if (UPLOAD_ERR_OK !== $iError)
{
$iClientError = \RainLoop\Enumerations\UploadClientError::NORMAL;
$sError = $this->getUploadErrorMessageByCode($iError, $iClientError);
if (!empty($sError))
{
return $this->FalseResponse(__FUNCTION__, $iClientError, $sError);
}
}
return $this->DefaultResponse(__FUNCTION__, $bResponse);
}
/**
* @return array
*/
public function UploadContacts()
{
$oAccount = $this->getAccountFromToken();
$mResponse = false;
$aFile = $this->GetActionParam('File', null);
$iError = $this->GetActionParam('Error', \RainLoop\Enumerations\UploadError::UNKNOWN);
if ($oAccount && UPLOAD_ERR_OK === $iError && \is_array($aFile))
{
$sSavedName = 'upload-post-'.\md5($aFile['name'].$aFile['tmp_name']);
if (!$this->FilesProvider()->MoveUploadedFile($oAccount, $sSavedName, $aFile['tmp_name']))
{
$iError = \RainLoop\Enumerations\UploadError::ON_SAVING;
}
else
{
@\ini_set('auto_detect_line_endings', true);
$mData = $this->FilesProvider()->GetFile($oAccount, $sSavedName);
if ($mData)
{
$sFileStart = @\fread($mData, 20);
\rewind($mData);
if (false !== $sFileStart)
{
$sFileStart = \trim($sFileStart);
if (false !== \strpos($sFileStart, 'BEGIN:VCARD'))
{
$mResponse = $this->importContactsFromVcfFile($oAccount, $mData, $sFileStart);
}
else if (false !== \strpos($sFileStart, ',') || false !== \strpos($sFileStart, ';'))
{
$mResponse = $this->importContactsFromCsvFile($oAccount, $mData, $sFileStart);
}
}
}
if (\is_resource($mData))
{
@\fclose($mData);
}
unset($mData);
$this->FilesProvider()->Clear($oAccount, $sSavedName);
@\ini_set('auto_detect_line_endings', false);
}
}
if (UPLOAD_ERR_OK !== $iError)
{
$iClientError = \RainLoop\Enumerations\UploadClientError::NORMAL;
$sError = $this->getUploadErrorMessageByCode($iError, $iClientError);
if (!empty($sError))
{
return $this->FalseResponse(__FUNCTION__, $iClientError, $sError);
}
}
return $this->DefaultResponse(__FUNCTION__, $mResponse);
}
/**
* @param \RainLoop\Account $oAccount
* @param resource $rFile
@ -6365,102 +6522,6 @@ class Actions
return $iCount;
}
/**
* @return array
*/
public function UploadContacts()
{
$oAccount = $this->getAccountFromToken();
$oConfig = $this->Config();
$sInputName = 'uploader';
$mResponse = false;
$iError = UploadError::UNKNOWN;
$iSizeLimit = ((int) $oConfig->Get('webmail', 'attachment_size_limit', 0)) * 1024 * 1024;
if ($oAccount)
{
$oAddressBookProvider = $this->AddressBookProvider($oAccount);
if ($oAddressBookProvider && $oAddressBookProvider->IsActive())
{
$iError = UPLOAD_ERR_OK;
$_FILES = isset($_FILES) ? $_FILES : null;
if (isset($_FILES, $_FILES[$sInputName], $_FILES[$sInputName]['name'], $_FILES[$sInputName]['tmp_name'], $_FILES[$sInputName]['size']))
{
$iError = (isset($_FILES[$sInputName]['error'])) ? (int) $_FILES[$sInputName]['error'] : UPLOAD_ERR_OK;
if (UPLOAD_ERR_OK === $iError && 0 < $iSizeLimit && $iSizeLimit < (int) $_FILES[$sInputName]['size'])
{
$iError = UploadError::CONFIG_SIZE;
}
$sSavedName = 'upload-post-'.md5($_FILES[$sInputName]['name'].$_FILES[$sInputName]['tmp_name']);
if (UPLOAD_ERR_OK === $iError)
{
if (!$this->FilesProvider()->MoveUploadedFile($oAccount, $sSavedName, $_FILES[$sInputName]['tmp_name']))
{
$iError = UploadError::ON_SAVING;
}
@\ini_set('auto_detect_line_endings', true);
$mData = $this->FilesProvider()->GetFile($oAccount, $sSavedName);
if ($mData)
{
$sFileStart = @\fread($mData, 20);
\rewind($mData);
if (false !== $sFileStart)
{
$sFileStart = \trim($sFileStart);
if (false !== \strpos($sFileStart, 'BEGIN:VCARD'))
{
$mResponse = $this->importContactsFromVcfFile($oAccount, $mData, $sFileStart);
}
else if (false !== \strpos($sFileStart, ',') || false !== \strpos($sFileStart, ';'))
{
$mResponse = $this->importContactsFromCsvFile($oAccount, $mData, $sFileStart);
}
}
}
if (\is_resource($mData))
{
@\fclose($mData);
}
unset($mData);
$this->FilesProvider()->Clear($oAccount, $sSavedName);
@\ini_set('auto_detect_line_endings', false);
}
}
else if (!isset($_FILES) || !is_array($_FILES) || 0 === count($_FILES))
{
$iError = UPLOAD_ERR_INI_SIZE;
}
else
{
$iError = UploadError::EMPTY_FILES_DATA;
}
}
}
if (UPLOAD_ERR_OK !== $iError)
{
$iClientError = UploadClientError::NORMAL;
$sError = $this->getUploadErrorMessageByCode($iError, $iClientError);
if (!empty($sError))
{
return $this->FalseResponse(__FUNCTION__, $iClientError, $sError);
}
}
return $this->DefaultResponse(__FUNCTION__, $mResponse);
}
/**
* @return bool
*
@ -6614,6 +6675,11 @@ class Actions
$aResult[] = \RainLoop\Enumerations\Capa::THEMES;
}
if ($oConfig->Get('webmail', 'allow_user_background', false))
{
$aResult[] = \RainLoop\Enumerations\Capa::USER_BACKGROUND;
}
if ($oConfig->Get('security', 'openpgp', false))
{
$aResult[] = \RainLoop\Enumerations\Capa::OPEN_PGP;

View file

@ -63,6 +63,7 @@ class Application extends \RainLoop\Config\AbstractConfig
'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'),
'allow_languages_on_settings' => array(true, 'Allow language selection on settings screen'),

View file

@ -10,6 +10,7 @@ class Capa
const PREFETCH = 'PREFETCH';
const GRAVATAR = 'GRAVATAR';
const THEMES = 'THEMES';
const USER_BACKGROUND = 'USER_BACKGROUND';
const FILTERS = 'FILTERS';
const ADDITIONAL_ACCOUNTS = 'ADDITIONAL_ACCOUNTS';
const ADDITIONAL_IDENTITIES = 'ADDITIONAL_IDENTITIES';

View file

@ -24,6 +24,16 @@ class KeyPathHelper
return 'Webmail/Accounts/'.$sEmail.'/Array';
}
/**
* @param string $sEmail
*
* @return string
*/
static public function UserBackground($sEmail)
{
return '/UserBackground/Base64/'.$sEmail.'/Data/';
}
/**
* @param string $sSsoHash
*

View file

@ -269,14 +269,51 @@ class ServiceActions
*/
private function privateUpload($sAction)
{
$oConfig = $this->Config();
@\ob_start();
$aResponseItem = null;
try
{
$aFile = null;
$sInputName = 'uploader';
$iError = \RainLoop\Enumerations\UploadError::UNKNOWN;
$iSizeLimit = ((int) $oConfig->Get('webmail', 'attachment_size_limit', 0)) * 1024 * 1024;
$iError = UPLOAD_ERR_OK;
$_FILES = isset($_FILES) ? $_FILES : null;
if (isset($_FILES, $_FILES[$sInputName], $_FILES[$sInputName]['name'], $_FILES[$sInputName]['tmp_name'], $_FILES[$sInputName]['size']))
{
$iError = (isset($_FILES[$sInputName]['error'])) ? (int) $_FILES[$sInputName]['error'] : UPLOAD_ERR_OK;
if (UPLOAD_ERR_OK === $iError && 0 < $iSizeLimit && $iSizeLimit < (int) $_FILES[$sInputName]['size'])
{
$iError = \RainLoop\Enumerations\UploadError::CONFIG_SIZE;
}
if (UPLOAD_ERR_OK === $iError)
{
$aFile = $_FILES[$sInputName];
}
}
else if (!isset($_FILES) || !is_array($_FILES) || 0 === count($_FILES))
{
$iError = UPLOAD_ERR_INI_SIZE;
}
else
{
$iError = \RainLoop\Enumerations\UploadError::EMPTY_FILES_DATA;
}
if (\method_exists($this->oActions, $sAction) &&
\is_callable(array($this->oActions, $sAction)))
{
$this->oActions->SetActionParams($this->oHttp->GetQueryAsArray(), $sAction);
$aActionParams = $this->oHttp->GetQueryAsArray();
$aActionParams['File'] = $aFile;
$aActionParams['Error'] = $iError;
$this->oActions->SetActionParams($aActionParams, $sAction);
$aResponseItem = \call_user_func(array($this->oActions, $sAction));
}

View file

@ -65,6 +65,13 @@
value: capaThemes
}
}"></div>
<!-- <div data-bind="component: {
name: 'Checkbox',
params: {
label: 'Allow background selection on settings screen',
value: capaUserBackground
}
}"></div>-->
</div>
</div>
<div class="control-group">

View file

@ -1,183 +0,0 @@
# Magnific Popup Repository
[![Build Status](https://travis-ci.org/dimsemenov/Magnific-Popup.png)](https://travis-ci.org/dimsemenov/Magnific-Popup)
Fast, light and responsive lightbox plugin, for jQuery and Zepto.js.
- [Documentation and getting started guide](http://dimsemenov.com/plugins/magnific-popup/documentation.html).
- [Examples and plugin home page](http://dimsemenov.com/plugins/magnific-popup/).
- More examples in [CodePen collection](http://codepen.io/collection/nLcqo).
Optionally, install via Bower: `bower install magnific-popup`.
## Extensions
- WordPress plugin - [under development](http://dimsemenov.com/plugins/magnific-popup/wordpress.html).
- [Drupal module](https://drupal.org/project/magnific_popup).
- [Ruby gem](https://rubygems.org/gems/magnific-popup-rails), `gem install magnific-popup-rails`.
If you created a popup extension for something, email me and I'll add it to this list.
## Location of stuff
- Generated popup JS and CSS files are in folder [dist/](https://github.com/dimsemenov/Magnific-Popup/tree/master/dist). (Online build tool is on [documentation page](http://dimsemenov.com/plugins/magnific-popup/documentation.html)).
- Source files are in folder [src/](https://github.com/dimsemenov/Magnific-Popup/tree/master/src). They include [Sass CSS file](https://github.com/dimsemenov/Magnific-Popup/blob/master/src/css/main.scss) and js parts (edit them if you wish to submit commit).
- Website (examples & documentation) is in folder [website/](https://github.com/dimsemenov/Magnific-Popup/tree/master/website).
- Documentation page itself is in [website/documentation.md](https://github.com/dimsemenov/Magnific-Popup/blob/master/website/documentation.md) (contributions to it are very welcome).
## Build
To compile Magnific Popup by yourself, first of make sure that you have [Node.js](http://nodejs.org/), [Grunt.js](https://github.com/cowboy/grunt), [Ruby](http://www.ruby-lang.org/) and [Jekyll](https://github.com/mojombo/jekyll/) installed, then:
1) Copy repository
git clone https://github.com/dimsemenov/Magnific-Popup.git
2) Go inside Magnific Popup folder that you fetched and install Node dependencies
cd Magnific-Popup && npm install
3) Now simply run `grunt` to generate JS and CSS in folder `dist` and site in folder `_site/`.
grunt
Optionally:
- Run `grunt watch` to automatically rebuild script when you change files in `src/` or in `website/`.
- If you don't have and don't want to install Jekyll, run `grunt nosite` to just build JS and CSS files related to popup in `dist/`.
## Changelog
### 0.9.8 (Oct 26, 2013)
- Added figure and figcaption elements to image markup (#233, thanks to @pjackson28).
- To avoid "jump" of content background, gap from right side (that "replaces" the scrollbar) is added with help of `margin`, instead of `padding`, (closes #125, thanks to @chodorowicz).
- Function that checks if the clicked element should close popup or not is now public (so it <a href="http://dimsemenov.com/plugins/magnific-popup/documentation.html#how_to_override_some_function_without_modifying_the_source_files">can be overridden with your own logic</a>).
- Working on a new module: the exact copy of native fullscreen Android/iOS gallery, with touch/zoom/pan e.t.c., will publish branch soon (&copy;Blizzard).
### 0.9.7 (Oct 10, 2013)
- CSS: removed outline on buttons (thanks to @OriginalEXE).
- Allow multiple string tokens to be passed in gallery variables like `%curr% of %total%` and `%title%` (#234, thanks to Petr Marek).
- A few small changes to Grunt build, `grunt-contrib-sass` > `grunt-sass`. (thanks to @nschonni).
### 0.9.6 (Sep 29, 2013)
- Fixed bug: options object that you pass to popup gets modified after the initialization (#217, #203).
- Fixed bug: zoom module creates global variable (#226).
- Fixed bug: gallery from AJAX popups stacks content if it's switched before loading has finished.
- Indented and combined SCSS classes (thanks to @nschonni).
- `$.magnificPopup.close()` now doesn't throw an exception if there's no instance (#221, thanks to @mjlescano).
### 0.9.5 (Aug 21, 2013)
- Fixed bug: built-in tab focus in popup works incorrectly (caused by 0.9.3 update).
### 0.9.4 (Aug 7, 2013)
- Fixed bug: error in IE7 when minified version of script is used with some versions of jQuery, #156.
- Fixed bug: DOM exception in Chrome when using gallery mode with some versions of jQuery, #177.
### 0.9.3 (Jul 16, 2013)
- Fixed blurry arrows in FF (#142)
- Added `lazyLoadError` callback.
- Popup now prevents closing if the clicked element is remvoved from DOM.
- `overflow:hidden` is now applied to `html` instead of `body`.
- Increased default z-index to from 500 to 1040.
### 0.9.2 (Jul 5, 2013)
- Fixed bug in new zoom module, that could cause incorrect calculation of image height, when jQuery is used instead of Zepto.
### 0.9.1 (Jul 4, 2013)
- Added zoom module effect for images, go to Magnific Popup [website](http://dimsemenov.com/plugins/magnific-popup/) to view demos. More info in [docs](http://dimsemenov.com/plugins/magnific-popup/documentation.html#zoom_effect).
- `removalDelay` now applies only when browser supports CSS transitions.
- Fix: removed tiny blink when switching between gallery images, or opening images that are already cached.
- Changed the default appearance of gallery arrows (now its white triangle with black border, was vice-versa).
- Added solid background to the image when its loading.
### 0.9.0 (Jul 3, 2013)
- Added `modal` option which disables all default ways to close the popup, learn more in [docs](http://dimsemenov.com/plugins/magnific-popup/documentation.html#modal). Thanks to [Julen Ruiz Aizpuru](https://github.com/julen).
- Added `beforeClose` event.
- Added `imageLoadComplete` event.
- Removed jQuery event alias calls. Thanks to [Albert Casademont](https://github.com/acasademont).
- Cleaned some duplicate styles in CSS. Thanks to [Yann Abgrall](https://github.com/yannabgrall).
### 0.8.9 (Jun 4, 2013)
- Fix: inline element that is created dynamically causes exception in jQuery 1.8.x.
- Fix: incorrect detection of `_hasScrollBar` if body has defined height style.
- Fix: body styles are kept after popup is closed.
- Fix: close icon is aligned incorrectly with iframe type.
- **responseText is deprected**. Argument of callback `parseAjax` - `obj.responseText` is now deprected, but you can still access it via `obj.xhr.responseText`. Instead of it, please use `obj.data` to modify your output.
- Sass: changed variables to be default declarations to support front-loaded settings. i.e. You can override options by adding `_settings.scss` file near `main.scss` with your new options.
- Added: `afterClose` event.
- Added: `ajaxContentLoaded` event.
- Added: [Bower](https://github.com/bower/bower) support.
### 0.8.8 (May 24, 2013)
- Fix: you can now put link inside popup that will open another popup - http://codepen.io/dimsemenov/pen/hwIng
- Fix: incorrect index when opening popup that is already opened from multiple DOM elements.
### 0.8.7 (May 19, 2013)
- Fixed #62 - IE9 HTML5 YouTube player playing audio after pop up closed
### 0.8.6 (May 18, 2013)
- Controls are now removed when there is only one element in gallery.
- Fixed issue that could cause incorrect main event element.
- Public property `items` is now always an array (previously it could be jQuery object collection).
- Added `word-break: break-word` to caption.
### 0.8.5 (May 15, 2013)
- Fix #43 - In IE8 whole window becomes black when YouTube iframe is
closed.
- Fix #51 - In IE9 YouTube HTML5 video keeps playing after iframe is
removed from page.
- Bugfix - box-sizing on IMG in low IE behaves incorrectly.
- Fix #57 - padding on body is not added with overflowY:'scroll'.
- removalDelay option is now ignored in IE.
- Added an option closeOnBgClick.
- Added BeforeChange callback.
- Added AfterChange callback.
### 0.8.4 (May 13, 2013)
- You can now call any public method directly from jQuery DOM element, e.g.: `$('.some-el-with-popup').magnificPopup('methodName', /*, arguments */)`.
- Optimized inline module. Now target element is replaced with placeholder only when it has a defined parent node.
- `inline` type is now set as a default, so you may skip it.
- Now content is just replaced when you call `open()` on popup that is already opened.
### 0.8.3 (May 9, 2013)
- Added: `goTo` public method.
- Custom events that are added to popup are now not lost when navigating through gallery.
- If `delegate` option is used, events are now dispatched on main element instead of children.
### 0.8.2 (May 5, 2013)
- Added !important to mfp-hide class.
- Fix gallery rendering issue in Opera.
- Fix padding to body with overflow:scroll.
## License
Script is MIT licensed and free and will always be kept this way. But has a small restriction from me - please do not create public WordPress plugin based on it(or at least contact me before creating it), because I will make it and it'll be open source too ([want to get notified?](http://dimsemenov.com/subscribe.html)).
Created by [@dimsemenov](http://twitter.com/dimsemenov) & [contributors](https://github.com/dimsemenov/Magnific-Popup/contributors).

View file

@ -1,17 +0,0 @@
{
"name": "magnific-popup",
"version": "0.9.8",
"main": [
"dist/jquery.magnific-popup.js",
"dist/magnific-popup.css"
],
"dependencies": {
"jquery": ">=1.8.0"
},
"ignore": [
"node_modules/",
"components/",
"website/",
"libs/"
]
}

File diff suppressed because it is too large Load diff

File diff suppressed because one or more lines are too long

View file

@ -1,45 +0,0 @@
/* overlay at start */
.mfp-fade.mfp-bg {
opacity: 0;
-webkit-transition: all 0.2s ease-out;
-moz-transition: all 0.2s ease-out;
transition: all 0.2s ease-out;
}
/* overlay animate in */
.mfp-fade.mfp-bg.mfp-ready {
opacity: 0.8;
}
/* overlay animate out */
.mfp-fade.mfp-bg.mfp-removing {
opacity: 0;
}
/* content at start */
.mfp-fade.mfp-wrap .mfp-content {
opacity: 0;
-webkit-transition: all 0.15s ease-out;
-moz-transition: all 0.15s ease-out;
transition: all 0.15s ease-out;
-webkit-transform: translateX(-50px);
-moz-transform: translateX(-50px);
transform: translateX(-50px);
}
/* content animate it */
.mfp-fade.mfp-wrap.mfp-ready .mfp-content {
opacity: 1;
-webkit-transform: translateX(0);
-moz-transform: translateX(0);
transform: translateX(0);
}
/* content animate out */
.mfp-fade.mfp-wrap.mfp-removing .mfp-content {
opacity: 0;
-webkit-transform: translateX(50px);
-moz-transform: translateX(50px);
transform: translateX(50px);
}

View file

@ -1,364 +0,0 @@
/* Magnific Popup CSS */
.mfp-bg {
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 1042;
overflow: hidden;
position: fixed;
background: #0b0b0b;
opacity: 0.8;
filter: alpha(opacity=80); }
.mfp-wrap {
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 1043;
position: fixed;
outline: none !important;
-webkit-backface-visibility: hidden; }
.mfp-container {
text-align: center;
position: absolute;
width: 100%;
height: 100%;
left: 0;
top: 0;
padding: 0 8px;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box; }
.mfp-container:before {
content: '';
display: inline-block;
height: 100%;
vertical-align: middle; }
.mfp-align-top .mfp-container:before {
display: none; }
.mfp-content {
position: relative;
display: inline-block;
vertical-align: middle;
margin: 0 auto;
text-align: left;
z-index: 1045; }
.mfp-inline-holder .mfp-content, .mfp-ajax-holder .mfp-content {
width: 100%;
cursor: auto; }
.mfp-ajax-cur {
cursor: progress; }
.mfp-zoom-out-cur, .mfp-zoom-out-cur .mfp-image-holder .mfp-close {
cursor: -moz-zoom-out;
cursor: -webkit-zoom-out;
cursor: zoom-out; }
.mfp-zoom {
cursor: pointer;
cursor: -webkit-zoom-in;
cursor: -moz-zoom-in;
cursor: zoom-in; }
.mfp-auto-cursor .mfp-content {
cursor: auto; }
.mfp-close, .mfp-arrow, .mfp-preloader, .mfp-counter {
-webkit-user-select: none;
-moz-user-select: none;
user-select: none; }
.mfp-loading.mfp-figure {
display: none; }
.mfp-hide {
display: none !important; }
.mfp-preloader {
color: #cccccc;
position: absolute;
top: 50%;
width: auto;
text-align: center;
margin-top: -0.8em;
left: 8px;
right: 8px;
z-index: 1044; }
.mfp-preloader a {
color: #cccccc; }
.mfp-preloader a:hover {
color: white; }
.mfp-s-ready .mfp-preloader {
display: none; }
.mfp-s-error .mfp-content {
display: none; }
button.mfp-close, button.mfp-arrow {
overflow: visible;
cursor: pointer;
background: transparent;
border: 0;
-webkit-appearance: none;
display: block;
outline: none;
padding: 0;
z-index: 1046;
-webkit-box-shadow: none;
box-shadow: none; }
button::-moz-focus-inner {
padding: 0;
border: 0; }
.mfp-close {
width: 44px;
height: 44px;
line-height: 44px;
position: absolute;
right: 0;
top: 0;
text-decoration: none;
text-align: center;
opacity: 0.65;
padding: 0 0 18px 10px;
color: white;
font-style: normal;
font-size: 28px;
font-family: Arial, Baskerville, monospace; }
.mfp-close:hover, .mfp-close:focus {
opacity: 1; }
.mfp-close:active {
top: 1px; }
.mfp-close-btn-in .mfp-close {
color: #333333; }
.mfp-image-holder .mfp-close, .mfp-iframe-holder .mfp-close {
color: white;
right: -6px;
text-align: right;
padding-right: 6px;
width: 100%; }
.mfp-counter {
position: absolute;
top: 0;
right: 0;
color: #cccccc;
font-size: 12px;
line-height: 18px; }
.mfp-arrow {
position: absolute;
opacity: 0.65;
margin: 0;
top: 50%;
margin-top: -55px;
padding: 0;
width: 90px;
height: 110px;
-webkit-tap-highlight-color: rgba(0, 0, 0, 0); }
.mfp-arrow:active {
margin-top: -54px; }
.mfp-arrow:hover, .mfp-arrow:focus {
opacity: 1; }
.mfp-arrow:before, .mfp-arrow:after, .mfp-arrow .mfp-b, .mfp-arrow .mfp-a {
content: '';
display: block;
width: 0;
height: 0;
position: absolute;
left: 0;
top: 0;
margin-top: 35px;
margin-left: 35px;
border: medium inset transparent; }
.mfp-arrow:after, .mfp-arrow .mfp-a {
border-top-width: 13px;
border-bottom-width: 13px;
top: 8px; }
.mfp-arrow:before, .mfp-arrow .mfp-b {
border-top-width: 21px;
border-bottom-width: 21px; }
.mfp-arrow-left {
left: 0; }
.mfp-arrow-left:after, .mfp-arrow-left .mfp-a {
border-right: 17px solid white;
margin-left: 31px; }
.mfp-arrow-left:before, .mfp-arrow-left .mfp-b {
margin-left: 25px;
border-right: 27px solid #3f3f3f; }
.mfp-arrow-right {
right: 0; }
.mfp-arrow-right:after, .mfp-arrow-right .mfp-a {
border-left: 17px solid white;
margin-left: 39px; }
.mfp-arrow-right:before, .mfp-arrow-right .mfp-b {
border-left: 27px solid #3f3f3f; }
.mfp-iframe-holder {
padding-top: 40px;
padding-bottom: 40px; }
.mfp-iframe-holder .mfp-content {
line-height: 0;
width: 100%;
max-width: 900px; }
.mfp-iframe-holder .mfp-close {
top: -40px; }
.mfp-iframe-scaler {
width: 100%;
height: 0;
overflow: hidden;
padding-top: 56.25%; }
.mfp-iframe-scaler iframe {
position: absolute;
display: block;
top: 0;
left: 0;
width: 100%;
height: 100%;
box-shadow: 0 0 8px rgba(0, 0, 0, 0.6);
background: black; }
/* Main image in popup */
img.mfp-img {
width: auto;
max-width: 100%;
height: auto;
display: block;
line-height: 0;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
padding: 40px 0 40px;
margin: 0 auto; }
/* The shadow behind the image */
.mfp-figure {
line-height: 0; }
.mfp-figure:after {
content: '';
position: absolute;
left: 0;
top: 40px;
bottom: 40px;
display: block;
right: 0;
width: auto;
height: auto;
z-index: -1;
box-shadow: 0 0 8px rgba(0, 0, 0, 0.6);
background: #444444; }
.mfp-figure small {
color: #bdbdbd;
display: block;
font-size: 12px;
line-height: 14px; }
.mfp-bottom-bar {
margin-top: -36px;
position: absolute;
top: 100%;
left: 0;
width: 100%;
cursor: auto; }
.mfp-title {
text-align: left;
line-height: 18px;
color: #f3f3f3;
word-wrap: break-word;
padding-right: 36px; }
.mfp-image-holder .mfp-content {
max-width: 100%; }
.mfp-gallery .mfp-image-holder .mfp-figure {
cursor: pointer; }
@media screen and (max-width: 800px) and (orientation: landscape), screen and (max-height: 300px) {
/**
* Remove all paddings around the image on small screen
*/
.mfp-img-mobile .mfp-image-holder {
padding-left: 0;
padding-right: 0; }
.mfp-img-mobile img.mfp-img {
padding: 0; }
.mfp-img-mobile .mfp-figure {
/* The shadow behind the image */ }
.mfp-img-mobile .mfp-figure:after {
top: 0;
bottom: 0; }
.mfp-img-mobile .mfp-figure small {
display: inline;
margin-left: 5px; }
.mfp-img-mobile .mfp-bottom-bar {
background: rgba(0, 0, 0, 0.6);
bottom: 0;
margin: 0;
top: auto;
padding: 3px 5px;
position: fixed;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box; }
.mfp-img-mobile .mfp-bottom-bar:empty {
padding: 0; }
.mfp-img-mobile .mfp-counter {
right: 5px;
top: 3px; }
.mfp-img-mobile .mfp-close {
top: 0;
right: 0;
width: 35px;
height: 35px;
line-height: 35px;
background: rgba(0, 0, 0, 0.6);
position: fixed;
text-align: center;
padding: 0; } }
@media all and (max-width: 900px) {
.mfp-arrow {
-webkit-transform: scale(0.75);
transform: scale(0.75); }
.mfp-arrow-left {
-webkit-transform-origin: 0;
transform-origin: 0; }
.mfp-arrow-right {
-webkit-transform-origin: 100%;
transform-origin: 100%; }
.mfp-container {
padding-left: 6px;
padding-right: 6px; } }
.mfp-ie7 .mfp-img {
padding: 0; }
.mfp-ie7 .mfp-bottom-bar {
width: 600px;
left: 50%;
margin-left: -300px;
margin-top: 5px;
padding-bottom: 5px; }
.mfp-ie7 .mfp-container {
padding: 0; }
.mfp-ie7 .mfp-content {
padding-top: 44px; }
.mfp-ie7 .mfp-close {
top: 0;
right: 0;
padding-top: 0; }

View file

@ -1,29 +0,0 @@
{
"name": "magnific-popup",
"title": "Magnific Popup",
"description": "Fast, light, mobile-friendly and responsive lightbox and modal dialog plugin. Open inline HTML, ajax loaded content, image, form, iframe (YouTube video, Vimeo, Google Maps), photo gallery. Animation effects added with CSS3 transitions. For jQuery or Zepto.",
"version": "0.9.8",
"homepage": "http://dimsemenov.com/plugins/magnific-popup/",
"demo": "http://dimsemenov.com/plugins/magnific-popup/",
"docs": "http://dimsemenov.com/plugins/magnific-popup/documentation.html",
"author": {
"name": "Dmitry Semenov",
"email": "diiiimaaaa@gmail.com",
"url": "http://dimsemenov.com"
},
"repository": {
"type": "git",
"url": "https://github.com/dimsemenov/Magnific-Popup.git"
},
"bugs": "https://github.com/dimsemenov/Magnific-Popup/issues",
"dependencies": {
"jquery": ">=1.7.2"
},
"keywords": ["lightbox","popup","modal","window","dialog","ui","gallery","slideshow","video","image","ajax","html5","animation","jquery","photo","responsive","mobile"],
"licenses": [
{
"type": "MIT",
"url": "http://www.opensource.org/licenses/mit-license.php"
}
]
}

View file

@ -1,26 +0,0 @@
{
"name": "magnific-popup",
"version": "0.0.0-ignored",
"engines": {
"node": ">= 0.8.0"
},
"scripts": {
"test": "grunt jshint"
},
"devDependencies": {
"grunt-contrib-jshint": "~0.1.1",
"grunt-contrib-concat": "~0.1.2",
"grunt-contrib-uglify": "~0.1.1",
"grunt-contrib-watch": "~0.2.0",
"grunt-contrib-clean": "~0.4.0",
"grunt": "~0.4.0",
"grunt-contrib-cssmin": "~0.4.1",
"grunt-contrib-copy": "~0.4.0",
"grunt-jekyll": "~0.3.9",
"grunt-sass": "~0.6.1"
},
"repository": {
"type": "git",
"url": "https://github.com/nschonni/Magnific-Popup.git"
}
}