oHttp = \MailSo\Base\Http::SingletonInstance(); $this->oActions = Actions::NewInstance(); \set_error_handler(array(&$this, 'LogPhpErrorHandler')); $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); } } /** * @return \RainLoop\Service */ public static function NewInstance() { return new self(); } /** * @param int $iErrNo * @param string $sErrStr * @param string $sErrFile * @param int $iErrLine * * @return bool */ public function LogPhpErrorHandler($iErrNo, $sErrStr, $sErrFile, $iErrLine) { $iType = \MailSo\Log\Enumerations\Type::NOTICE; switch ($iErrNo) { case E_USER_ERROR: $iType = \MailSo\Log\Enumerations\Type::ERROR; break; case E_USER_WARNING: $iType = \MailSo\Log\Enumerations\Type::WARNING; break; } if (!\in_array($sErrStr, array('iconv(): Detected an illegal character in input string'))) { $this->oActions->Logger()->Write($sErrFile.' [line:'.$iErrLine.', code:'.$iErrNo.']', $iType, 'PHP'); $this->oActions->Logger()->Write('Error: '.$sErrStr, $iType, 'PHP'); } return false; } /** * @return \RainLoop\Service */ public function Handle() { if (!\class_exists('MailSo\Version')) { return $this; } $this->oActions->ParseQueryAuthString(); if (defined('APP_INSTALLED_START') && defined('APP_INSTALLED_VERSION') && APP_INSTALLED_START && !APP_INSTALLED_VERSION) { $this->oActions->KeenIO('Install'); } $bCached = false; $sResult = ''; $sPathInfo = \trim(\trim($this->oHttp->GetServer('PATH_INFO', '')), ' /'); if (!empty($sPathInfo)) { if ('dav' !== \substr($sPathInfo, 0, 3)) { $sPathInfo = ''; } } if (empty($sPathInfo)) { $sQuery = \trim(\trim($this->oHttp->GetServer('QUERY_STRING', '')), ' /'); $iPos = \strpos($sQuery, '&'); if (0 < $iPos) { $sQuery = \substr($sQuery, 0, $iPos); } } else { $sQuery = $sPathInfo; } $this->oActions->Plugins()->RunHook('filter.http-query', array(&$sQuery)); $aPaths = \explode('/', $sQuery); $this->oActions->Plugins()->RunHook('filter.http-paths', array(&$aPaths)); $bAdmin = !empty($aPaths[0]) && \in_array(\strtolower($aPaths[0]), array('admin', 'cp')); if ($bAdmin && !$this->oActions->Config()->Get('security', 'allow_admin_panel', true)) { echo $this->oActions->ErrorTemplates('Access Denied.', 'Access to the RainLoop Webmail Admin Panel is not allowed!', true); return $this; } if (0 < \count($aPaths) && !empty($aPaths[0]) && !$bAdmin) { $sMethodName = 'Service'.$aPaths[0]; if (\method_exists($this->oServiceActions, $sMethodName) && \is_callable(array($this->oServiceActions, $sMethodName))) { $this->oServiceActions->SetQuery($sQuery)->SetPaths($aPaths); $sResult = \call_user_func(array($this->oServiceActions, $sMethodName)); } else if (!$this->oActions->Plugins()->RunAdditionalPart($aPaths[0], $aPaths)) { $this->oActions->Logger()->Write('Unknown request', \MailSo\Log\Enumerations\Type::WARNING, 'RESPONSE'); } } else { @header('Content-Type: text/html; charset=utf-8'); $aData = $this->startUpData($bAdmin); $bCacheEnabled = $this->oActions->Config()->Get('labs', 'cache_system_data', true); $sCacheFileName = ''; if ($bCacheEnabled) { $sCacheFileName = 'TMPL:'.$aData['Hash']; $sResult = $this->oActions->Cacher()->Get($sCacheFileName); } if (0 === \strlen($sResult)) { $sJsBoot = \file_get_contents(APP_VERSION_ROOT_PATH.'static/js/boot.js'); $sResult = \strtr(\file_get_contents(APP_VERSION_ROOT_PATH.'app/templates/Index.html'), array( '{{BaseRandHash}}' => \md5(\rand(1000, 9000).\microtime(true)), '{{BaseAppDataScriptLink}}' => ($bAdmin ? APP_INDEX_FILE.'?/AdminAppData/' : APP_INDEX_FILE.'?/AppData/'), '{{BaseAppIndexFile}}' => APP_INDEX_FILE, '{{BaseAppFaviconIcoFile}}' => $aData['FaviconIcoLink'], '{{BaseAppFaviconPngFile}}' => $aData['FaviconPngLink'], '{{BaseAppAppleTouchFile}}' => $aData['AppleTouchLink'], '{{BaseAppMainCssLink}}' => $aData['AppCssLink'], '{{BaseAppBootScriptSource}}' => $sJsBoot, '{{BaseAppLibsScriptLink}}' => $aData['LibJsLink'], '{{BaseAppMainScriptLink}}' => $aData['AppJsLink'], '{{BaseAppLoadingDescription}}' => \htmlspecialchars($aData['LoadingDescription'], ENT_QUOTES|ENT_IGNORE, 'UTF-8'), '{{BaseDir}}' => \in_array($aData['Language'], array('ar', 'he', 'ur')) ? 'rtl' : 'ltr' )); $sResult = \RainLoop\Utils::ClearHtmlOutput($sResult); if (0 < \strlen($sCacheFileName)) { $this->oActions->Cacher()->Set($sCacheFileName, $sResult); } } else { $bCached = true; } $sResult .= ''; } // Output result echo $sResult; unset($sResult); return $this; } /** * @param bool $bAppJsDebug * @param bool $bAdmin * * @return string */ private function generateIndexCacheHash($bAppJsDebug, $bAdmin) { return \md5(APP_WEB_PATH. $this->oActions->Config()->Get('webmail', 'loading_description', 'RainLoop'). $this->oActions->Config()->Get('labs', 'cdn_static_domain', ''). \md5($this->oActions->Config()->Get('cache', 'index', '')). $this->oActions->Plugins()->Hash(). APP_VERSION.($bAppJsDebug ? 'd' : 'm').($bAdmin ? 'a' : 'w')); } /** * @param bool $bAdmin * * @return array */ private function startUpData($bAdmin) { $sLanguage = 'en'; $sTheme = 'Default'; if (!$bAdmin) { list($sLanguage, $sTheme) = $this->oActions->GetLanguageAndTheme(); } $sLanguage = $this->oActions->ValidateLanguage($sLanguage); $sTheme = $this->oActions->ValidateTheme($sTheme); $bAppJsDebug = !!$this->oActions->Config()->Get('labs', 'use_app_debug_js', false); $bAppCssDebug = !!$this->oActions->Config()->Get('labs', 'use_app_debug_css', false); $sCdnStaticDomain = $this->oActions->Config()->Get('labs', 'cdn_static_domain', ''); $sStaticPrefix = APP_WEB_STATIC_PATH; if (0 < \strlen($sCdnStaticDomain)) { $sStaticPrefix = \trim($sCdnStaticDomain, ' /\\').'/'.APP_VERSION.'/static/'; } return array( 'Language' => $sLanguage, 'Theme' => $sTheme, 'Hash' => $this->generateIndexCacheHash($bAppJsDebug, $bAdmin), 'LoadingDescription' => $this->oActions->Config()->Get('webmail', 'loading_description', 'RainLoop'), 'FaviconIcoLink' => $sStaticPrefix.'favicon.ico', 'FaviconPngLink' => $sStaticPrefix.'favicon.png', 'AppleTouchLink' => $sStaticPrefix.'apple-touch-icon.png', 'AppCssLink' => $sStaticPrefix.'css/app'.($bAppCssDebug ? '' : '.min').'.css', 'LibJsLink' => $sStaticPrefix.'js/libs.js', 'AppJsLink' => $sStaticPrefix.'js/'.($bAdmin ? 'admin' : 'app').($bAppJsDebug ? '' : '.min').'.js' ); } }