Index: branches/5.2.x/core/kernel/application.php =================================================================== diff -u -r14092 -r14095 --- branches/5.2.x/core/kernel/application.php (.../application.php) (revision 14092) +++ branches/5.2.x/core/kernel/application.php (.../application.php) (revision 14095) @@ -1,6 +1,6 @@ * See singleton pattern by GOF. -* @package kernel4 */ +class kApplication implements kiCacheable { -defined('FULL_PATH') or die('restricted access!'); - -class kApplication { - /** * Is true, when Init method was called already, prevents double initialization * @@ -134,6 +132,12 @@ */ var $errorHandlers = Array(); + /** + * Maintains list of user-defined exception handlers + * + * @var Array + */ + var $exceptionHandlers = Array(); // performance needs: /** @@ -165,13 +169,6 @@ var $EventManager = null; /** - * Ref to itself, needed because everybody used to write $this->Application, even inside kApplication - * - * @var kApplication - */ - var $Application = null; - - /** * Ref for TemplatesChache * * @var TemplatesCache @@ -228,6 +225,15 @@ var $siteDomain = null; /** + * Prevent kApplication class to be created directly, only via Instance method + * + */ + protected function __construct() + { + + } + + /** * Returns kApplication instance anywhere in the script. * * This method should be used to get single kApplication object instance anywhere in the @@ -248,7 +254,7 @@ * @access public * @return kApplication */ - function &Instance() + public static function &Instance() { static $instance = false; @@ -270,31 +276,39 @@ * @see TemplatesCache * @return bool Was Init actually made now or before */ - function Init() + public function Init() { if($this->InitDone) { return false; } - $this->isAdmin = constOn('ADMIN'); + $this->isAdmin = kUtil::constOn('ADMIN'); - if (!constOn('SKIP_OUT_COMPRESSION')) { + if ( !kUtil::constOn('SKIP_OUT_COMPRESSION') ) { ob_start(); // collect any output from method (other then tags) into buffer } - if (defined('DEBUG_MODE') && $this->isDebugMode() && constOn('DBG_PROFILE_MEMORY')) { + if (defined('DEBUG_MODE') && $this->isDebugMode() && kUtil::constOn('DBG_PROFILE_MEMORY')) { $this->Debugger->appendMemoryUsage('Application before Init:'); } - if (!$this->isDebugMode() && !constOn('DBG_ZEND_PRESENT')) { + + if (!$this->isDebugMode() && !kUtil::constOn('DBG_ZEND_PRESENT')) { error_reporting(0); ini_set('display_errors', 0); } - if (!constOn('DBG_ZEND_PRESENT')) { + + if (!kUtil::constOn('DBG_ZEND_PRESENT')) { $error_handler = set_error_handler( Array (&$this, 'handleError') ); if ($error_handler) { // wrap around previous error handler, if any was set $this->errorHandlers[] = $error_handler; } + + $exception_handler = set_exception_handler( Array (&$this, 'handleException') ); + if ($exception_handler) { + // wrap around previous exception handler, if any was set + $this->exceptionHandlers[] = $exception_handler; + } } $this->Conn = new kDBConnection(SQL_TYPE, Array(&$this, 'handleSQLError') ); @@ -308,14 +322,14 @@ $this->EventManager =& $this->Factory->makeClass('EventManager'); $this->Factory->Storage['EventManager'] =& $this->EventManager; $this->RegisterDefaultBuildEvents(); - $this->SetDefaultConstants(); if (defined('DEBUG_MODE') && $this->isDebugMode()) { $this->Debugger->appendTimestamp('Before UnitConfigReader'); } $this->UnitConfigReader =& $this->recallObject('kUnitConfigReader'); $this->UnitConfigReader->scanModules(MODULES_PATH); + $this->registerModuleConstants(); if (defined('DEBUG_MODE') && $this->isDebugMode()) { @@ -443,18 +457,13 @@ $modules_helper =& $this->recallObject('ModulesHelper'); /* @var $modules_helper kModulesHelper */ + $this->Conn->nextQueryCachable = true; $sql = 'SELECT * FROM ' . TABLE_PREFIX . 'Modules - WHERE Loaded = 1 + WHERE ' . $modules_helper->getWhereClause() . ' ORDER BY LoadOrder'; $this->ModuleInfo = $this->Conn->Query($sql, 'Name'); - $sql = 'SELECT * - FROM '.TABLE_PREFIX.'Modules - WHERE '.$modules_helper->getWhereClause().' - ORDER BY LoadOrder'; - $this->ModuleInfo = $this->Conn->Query($sql, 'Name'); - $this->registerModuleConstants(); } @@ -495,16 +504,19 @@ function VerifyThemeId() { if ($this->isAdmin) { - safeDefine('THEMES_PATH', '/core/admin_templates'); + kUtil::safeDefine('THEMES_PATH', '/core/admin_templates'); + return; } $path = $this->GetFrontThemePath(); + if ($path === false) { $this->ApplicationDie('No Primary Theme Selected or Current Theme is Unknown or Disabled'); } - safeDefine('THEMES_PATH', $path); + kUtil::safeDefine('THEMES_PATH', $path); + /*$theme_id = $this->GetVar('m_theme'); if (!$theme_id) { $theme_id = $this->GetDefaultThemeId(); @@ -518,7 +530,8 @@ if (!$theme->IsLoaded() || !$theme->GetDBField('Enabled')) { if (!defined('IS_INSTALL')) $this->ApplicationDie('Unknown or disabled theme'); } - safeDefine('THEMES_PATH', '/themes/'.$theme->GetDBField('Name'));*/ + + kUtil::safeDefine('THEMES_PATH', '/themes/'.$theme->GetDBField('Name'));*/ } function GetFrontThemePath($force=0) @@ -586,7 +599,7 @@ return $theme_id; } - if (constOn('DBG_FORCE_THEME')) { + if (kUtil::constOn('DBG_FORCE_THEME')) { $theme_id = DBG_FORCE_THEME; } elseif (!$force_front && $this->isAdmin) { @@ -677,8 +690,15 @@ */ function RegisterDefaultClasses() { + $this->registerClass('kiCacheable', KERNEL_PATH . '/interfaces/cacheable.php', 'kiCacheable'); + $this->registerClass('kTempTablesHandler', KERNEL_PATH . '/utility/temp_handler.php'); - $this->registerClass('kEventManager', KERNEL_PATH . '/event_manager.php', 'EventManager'); + + $this->registerClass('kEventManager', KERNEL_PATH . '/event_manager.php', 'EventManager', 'kiCacheable'); + $this->registerClass('kHookManager', KERNEL_PATH . '/managers/hook_manager.php', 'kHookManager', 'kiCacheable'); + $this->registerClass('kAgentManager', KERNEL_PATH . '/managers/agent_manager.php', 'kAgentManager', 'kiCacheable'); + $this->registerClass('kRequestManager', KERNEL_PATH . '/managers/request_manager.php', 'kRequestManager'); + $this->registerClass('kUnitConfigReader', KERNEL_PATH . '/utility/unit_config_reader.php'); $this->registerClass('kArray', KERNEL_PATH . '/utility/params.php'); @@ -691,9 +711,9 @@ $this->registerClass('kMultipleFilter', KERNEL_PATH . '/utility/filters.php'); $this->registerClass('Session', KERNEL_PATH . '/session/session.php'); - $this->registerClass('SessionStorage', KERNEL_PATH . '/session/session.php'); + $this->registerClass('SessionStorage', KERNEL_PATH . '/session/session_storage.php'); $this->registerClass('InpSession', KERNEL_PATH . '/session/inp_session.php', 'Session'); - $this->registerClass('InpSessionStorage', KERNEL_PATH . '/session/inp_session.php', 'SessionStorage'); + $this->registerClass('InpSessionStorage', KERNEL_PATH . '/session/inp_session_storage.php', 'SessionStorage'); $this->registerClass('kTagProcessor', KERNEL_PATH . '/processors/tag_processor.php'); $this->registerClass('kMainTagProcessor', KERNEL_PATH . '/processors/main_processor.php','m_TagProcessor', 'kTagProcessor'); @@ -723,8 +743,7 @@ function RegisterDefaultBuildEvents() { - $event_manager =& $this->recallObject('EventManager'); - $event_manager->registerBuildEvent('kTempTablesHandler', 'OnTempHandlerBuild'); + $this->EventManager->registerBuildEvent('kTempTablesHandler', 'OnTempHandlerBuild'); } /** @@ -776,7 +795,8 @@ function getFilename($prefix, $id, $category_id = null) { if ($prefix == 'c') { - trigger_error('Method "' . __FUNCTION__ . '" no longer work with "c" prefix. Please use "getCategoryCache" method instead.', E_USER_ERROR); + throw new Exception('Method "' . __FUNCTION__ . '" no longer work with "c" prefix. Please use "getCategoryCache" method instead'); + return false; } @@ -830,7 +850,7 @@ if ($increment) { if (defined('DEBUG_MODE') && DEBUG_MODE && $this->isDebugMode()) { - $this->Application->Debugger->appendHTML('Incrementing serial: ' . $serial_name . '.'); + $this->Debugger->appendHTML('Incrementing serial: ' . $serial_name . '.'); } $this->setCache($serial_name, (int)$this->getCache($serial_name) + 1); @@ -867,7 +887,7 @@ * @param mixed $value * @param int $expiration */ - function setDBCache($name, &$value, $expiration = false) + function setDBCache($name, $value, $expiration = false) { if ((int)$expiration <= 0) { $expiration = -1; @@ -953,23 +973,13 @@ } /** - * Defines default constants if it's not defined before - in config.php - * - * @access private - */ - function SetDefaultConstants() // it's defined in startup.php - can be removed?? - { - safeDefine('SERVER_NAME', $_SERVER['HTTP_HOST']); - } - - /** * Registers each module specific constants if any found * */ function registerModuleConstants() { if (file_exists(KERNEL_PATH.'/constants.php')) { - k4_include_once(KERNEL_PATH.'/constants.php'); + kUtil::includeOnce(KERNEL_PATH.'/constants.php'); } if (!$this->ModuleInfo) { @@ -980,7 +990,7 @@ $contants_file = FULL_PATH . '/' . $module_info['Path'] . 'constants.php'; if (file_exists($contants_file)) { - k4_include_once($contants_file); + kUtil::includeOnce($contants_file); } } @@ -989,17 +999,14 @@ function ProcessRequest() { - $event_manager =& $this->recallObject('EventManager'); - /* @var $event_manager kEventManager */ - - if (defined('DEBUG_MODE') && $this->isDebugMode() && constOn('DBG_SHOW_HTTPQUERY')) { + if ( defined('DEBUG_MODE') && $this->isDebugMode() && kUtil::constOn('DBG_SHOW_HTTPQUERY') ) { $this->Debugger->appendHTML('HTTPQuery:'); $this->Debugger->dumpVars($this->HttpQuery->_Params); } - $event_manager->ProcessRequest(); - $event_manager->RunRegularEvents(reBEFORE); - $this->RequestProcessed = true; + $this->EventManager->ProcessRequest(); + $this->EventManager->runAgents(reBEFORE); + $this->RequestProcessed = true; } /** @@ -1012,7 +1019,7 @@ */ function Run() { - if (defined('DEBUG_MODE') && $this->isDebugMode() && constOn('DBG_PROFILE_MEMORY')) { + if (defined('DEBUG_MODE') && $this->isDebugMode() && kUtil::constOn('DBG_PROFILE_MEMORY')) { $this->Debugger->appendMemoryUsage('Application before Run:'); } @@ -1034,7 +1041,7 @@ } elseif ($this->GetVar('admin')) { // viewing front-end through admin's frame - $admin_session =& $this->Application->recallObject('Session.admin'); + $admin_session =& $this->recallObject('Session.admin'); $user = (int)$admin_session->RecallVar('user_id'); // in case, when no valid admin session found $perm_helper =& $this->recallObject('PermissionsHelper'); /* @var $perm_helper kPermissionsHelper */ @@ -1046,7 +1053,7 @@ } } - safeDefine('EDITING_MODE', ''); // user can't edit anything + kUtil::safeDefine('EDITING_MODE', ''); // user can't edit anything $this->Phrases->setPhraseEditing(); if (!$this->RequestProcessed) $this->ProcessRequest(); @@ -1068,13 +1075,13 @@ $cms_handler->SetCatByTemplate(); }*/ - if (defined('DEBUG_MODE') && $this->isDebugMode() && constOn('DBG_PROFILE_MEMORY')) { + if (defined('DEBUG_MODE') && $this->isDebugMode() && kUtil::constOn('DBG_PROFILE_MEMORY')) { $this->Debugger->appendMemoryUsage('Application before Parsing:'); } $this->HTML = $this->Parser->Run($t); - if (defined('DEBUG_MODE') && $this->isDebugMode() && constOn('DBG_PROFILE_MEMORY')) { + if (defined('DEBUG_MODE') && $this->isDebugMode() && kUtil::constOn('DBG_PROFILE_MEMORY')) { $this->Debugger->appendMemoryUsage('Application after Parsing:'); } } @@ -1102,15 +1109,15 @@ $debug_mode = defined('DEBUG_MODE') && $this->isDebugMode(); - if ($debug_mode && constOn('DBG_PROFILE_MEMORY')) { + if ($debug_mode && kUtil::constOn('DBG_PROFILE_MEMORY')) { $this->Debugger->appendMemoryUsage('Application before Done:'); } if ($debug_mode) { - $this->EventManager->RunRegularEvents(reAFTER); + $this->EventManager->runAgents(reAFTER); $this->Session->SaveData(); - if (constOn('DBG_CACHE')) { + if (kUtil::constOn('DBG_CACHE')) { $this->memoryCache->printStatistics(); } @@ -1140,7 +1147,7 @@ flush(); if (!$debug_mode) { - $this->EventManager->RunRegularEvents(reAFTER); + $this->EventManager->runAgents(reAFTER); $this->Session->SaveData(); } @@ -1157,7 +1164,7 @@ { global $start; - $script_time = getmicrotime() - $start; + $script_time = microtime(true) - $start; $query_statistics = $this->Conn->getQueryStatistics(); // time & count $sql = 'SELECT * @@ -1246,7 +1253,10 @@ */ function UseOutputCompression() { - if (constOn('IS_INSTALL') || constOn('DBG_ZEND_PRESENT') || constOn('SKIP_OUT_COMPRESSION')) return false; + if (kUtil::constOn('IS_INSTALL') || kUtil::constOn('DBG_ZEND_PRESENT') || kUtil::constOn('SKIP_OUT_COMPRESSION')) { + return false; + } + return $this->ConfigValue('UseOutputCompression') && function_exists('gzencode') && strstr($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip'); } @@ -1598,12 +1608,12 @@ // set session to GET_ONLY, to pass sid only if sid is REAL AND session is set if (!preg_match('#' . preg_quote($cookie_url) . '#', $target_url) && $session->SessionSet) { // when SSL<->NON-SSL redirect to different domain pass SID in url - $session->SetMode(smGET_ONLY); + $session->SetMode(Session::smGET_ONLY); } } if (isset($params['opener']) && $params['opener'] == 'u') { - $wid = $this->Application->GetVar('m_wid'); + $wid = $this->GetVar('m_wid'); $stack_name = rtrim('opener_stack_'.$wid, '_'); $opener_stack = $this->RecallVar($stack_name); @@ -1629,11 +1639,11 @@ } /*// store window relations - $window_relations = $this->Application->RecallVar('window_relations'); + $window_relations = $this->RecallVar('window_relations'); $window_relations = $window_relations ? unserialize($window_relations) : Array (); if (array_key_exists($wid, $window_relations)) { unset($window_relations[$wid]); - $this->Application->StoreVar('window_relations', serialize($window_relations)); + $this->StoreVar('window_relations', serialize($window_relations)); }*/ } return $ret; @@ -1689,7 +1699,6 @@ } // append pass through variables to each link to be build - // $params = array_merge_recursive2($this->getPassThroughVariables($params), $params); $params = array_merge($this->getPassThroughVariables($params), $params); if ($force_rewrite || ($this->RewriteURLs($ssl) && !$no_rewrite)) { @@ -1741,14 +1750,14 @@ if (is_null($cached_pass_through)) { $cached_pass_through = Array(); - $pass_through = $this->Application->GetVar('pass_through'); + $pass_through = $this->GetVar('pass_through'); if ($pass_through) { // names of variables to pass to each link $cached_pass_through['pass_through'] = $pass_through; $pass_through = explode(',', $pass_through); foreach ($pass_through as $pass_through_var) { - $cached_pass_through[$pass_through_var] = $this->Application->GetVar($pass_through_var); + $cached_pass_through[$pass_through_var] = $this->GetVar($pass_through_var); } } @@ -2048,7 +2057,7 @@ if (strtolower($t) == '__default__') { if (is_numeric($item_id)) { - $mod_rw_helper =& $this->Application->recallObject('ModRewriteHelper'); + $mod_rw_helper =& $this->recallObject('ModRewriteHelper'); /* @var $mod_rw_helper kModRewriteHelper */ $t = $mod_rw_helper->GetItemTemplate($category_id, $pass_element); // $pass_element should be the last processed element @@ -2148,7 +2157,7 @@ $params['__URLENCODE__'] = 1; $location = $this->HREF($t, $prefix, $params, $index_file); - if ($this->isDebugMode() && (constOn('DBG_REDIRECT') || (constOn('DBG_RAISE_ON_WARNINGS') && $this->Application->Debugger->WarningCount))) { + if ($this->isDebugMode() && (kUtil::constOn('DBG_REDIRECT') || (kUtil::constOn('DBG_RAISE_ON_WARNINGS') && $this->Debugger->WarningCount))) { $this->Debugger->appendTrace(); echo 'Debug output above !!!
' . "\n"; @@ -2194,7 +2203,7 @@ ob_end_flush(); // session expiration is called from session initialization, // that's why $this->Session may be not defined here - $session =& $this->Application->recallObject('Session'); + $session =& $this->recallObject('Session'); /* @var $session Session */ $this->HandleEvent( new kEvent('adm:OnBeforeShutdown') ); @@ -2215,11 +2224,9 @@ * @return string * @access public */ - function ReplaceLanguageTags($text, $force_escape=null) + function ReplaceLanguageTags($text, $force_escape = null) { - // !!!!!!!! -// if( !is_object($this->Phrases) ) $this->Debugger->appendTrace(); - return $this->Phrases->ReplaceLanguageTags($text,$force_escape); + return $this->Phrases->ReplaceLanguageTags($text, $force_escape); } /** @@ -2256,7 +2263,7 @@ $user->SetError('ValidateLogin', 'session_expired', 'la_text_sess_expired'); } - if (($user_id != USER_GUEST) && constOn('DBG_REQUREST_LOG') ) { + if (($user_id != USER_GUEST) && kUtil::constOn('DBG_REQUREST_LOG') ) { $http_query =& $this->recallObject('HTTPQuery'); $http_query->writeRequestLog(DBG_REQUREST_LOG); } @@ -2310,7 +2317,7 @@ function LoadStructureTemplateMapping() { if (!$this->isAdmin) { - $category_helper =& $this->Application->recallObject('CategoryHelper'); + $category_helper =& $this->recallObject('CategoryHelper'); /* @var $category_helper CategoryHelper */ $this->structureTemplateMapping = $category_helper->getTemplateMapping(); @@ -2372,6 +2379,7 @@ return false; } + $this->Conn->nextQueryCachable = true; $sql = 'SELECT VariableId, VariableValue FROM '.TABLE_PREFIX.'ConfigurationValues WHERE VariableName = '.$this->Conn->qstr($name); @@ -2380,6 +2388,7 @@ if ($res !== false) { $this->ConfigHash[$name] = $res['VariableValue']; $this->ConfigCacheIds[] = $res['VariableId']; + return $res['VariableValue']; } @@ -2397,16 +2406,18 @@ * Allows to process any type of event * * @param kEvent $event + * @param Array $params + * @param Array $specific_params * @access public * @author Alex */ - function HandleEvent(&$event, $params=null, $specificParams=null) + function HandleEvent(&$event, $params = null, $specific_params = null) { if ( isset($params) ) { - $event = new kEvent( $params, $specificParams ); + $event = new kEvent($params, $specific_params); } - if (!isset($this->EventManager)) { + if ( !isset($this->EventManager) ) { $this->EventManager =& $this->recallObject('EventManager'); } @@ -2429,6 +2440,17 @@ } /** + * Unregisters existing class from factory + * + * @param string $real_class Real name of class as in class declaration + * @param string $pseudo_class Name under this class object is accessed using getObject method + */ + function unregisterClass($real_class, $pseudo_class = null) + { + $this->Factory->unregisterClass($real_class, $pseudo_class); + } + + /** * Add $class_name to required classes list for $depended_class class. * All required class files are included before $depended_class file is included * @@ -2444,22 +2466,15 @@ /** * Registers Hook from subprefix event to master prefix event * - * @param string $hookto_prefix - * @param string $hookto_special - * @param string $hookto_event - * @param string $mode - * @param string $do_prefix - * @param string $do_special + * @param string $hook_event * @param string $do_event - * @param string $conditional + * @param int $mode + * @param bool $conditional * @access public - * @todo take care of a lot parameters passed - * @author Kostja */ - function registerHook($hookto_prefix, $hookto_special, $hookto_event, $mode, $do_prefix, $do_special, $do_event, $conditional) + public function registerHook($hook_event, $do_event, $mode = hAFTER, $conditional = false) { - $event_manager =& $this->recallObject('EventManager'); - $event_manager->registerHook($hookto_prefix, $hookto_special, $hookto_event, $mode, $do_prefix, $do_special, $do_event, $conditional); + $this->EventManager->registerHook($hook_event, $do_event, $mode, $conditional); } /** @@ -2475,35 +2490,18 @@ } /** - * Returns object using params specified, - * creates it if is required + * Returns object using params specified, creates it if is required * * @param string $name * @param string $pseudo_class * @param Array $event_params - * @return Object - * @author Alex + * @param Array $arguments + * @return kBase */ - function &recallObject($name,$pseudo_class=null,$event_params=Array()) + function &recallObject($name, $pseudo_class = null, $event_params = Array(), $arguments = Array ()) { - $result =& $this->Factory->getObject($name, $pseudo_class, $event_params); - return $result; - } + $result =& $this->Factory->getObject($name, $pseudo_class, $event_params, $arguments); - /** - * Returns object using Variable number of params, - * all params starting with 4th are passed to object consturctor - * - * @param string $name - * @param string $pseudo_class - * @param Array $event_params - * @return Object - * @author Alex - */ - function &recallObjectP($name,$pseudo_class=null,$event_params=Array()) - { - $func_args = func_get_args(); - $result =& ref_call_user_func_array( Array(&$this->Factory, 'getObjectP'), $func_args ); return $result; } @@ -2545,19 +2543,16 @@ } /** - * Get's real class name for pseudo class, - * includes class file and creates class - * instance + * Get's real class name for pseudo class, includes class file and creates class instance * * @param string $pseudo_class - * @return Object + * @param Array $arguments + * @return kBase * @access public - * @author Alex */ - function &makeClass($pseudo_class) + function &makeClass($pseudo_class, $arguments = Array ()) { - $func_args = func_get_args(); - $result =& ref_call_user_func_array( Array(&$this->Factory, 'makeClass'), $func_args); + $result =& $this->Factory->makeClass($pseudo_class, $arguments); return $result; } @@ -2601,7 +2596,7 @@ (!$ssl && (PROTOCOL == 'https://' || PROTOCOL == 'http://')) // always allow mod_rewrite for http || // or allow rewriting for redirect TO httpS or when already in httpS (($ssl || PROTOCOL == 'https://') && $this->ConfigValue('UseModRewriteWithSSL')); // but only if it's allowed in config! - return constOn('MOD_REWRITE') && $allow_rewriting; + return kUtil::constOn('MOD_REWRITE') && $allow_rewriting; } /** @@ -2688,10 +2683,9 @@ * @param string $event_name * @access public */ - function setEvent($prefix_special,$event_name) + function setEvent($prefix_special, $event_name) { - $event_manager =& $this->recallObject('EventManager'); - $event_manager->setEvent($prefix_special,$event_name); + $this->EventManager->setEvent($prefix_special,$event_name); } @@ -2707,25 +2701,26 @@ */ function handleSQLError($code, $msg, $sql) { - if ( isset($this->Debugger) ) - { - $errorLevel = constOn('DBG_SQL_FAILURE') && !defined('IS_INSTALL') ? E_USER_ERROR : E_USER_WARNING; - $this->Debugger->appendTrace(); + if ( isset($this->Debugger) ) { + $long_error_msg = '' . $msg . ' (' . $code . ')
SQL: ' . $this->Debugger->formatSQL($sql); + $long_id = $this->Debugger->mapLongError($long_error_msg); + $error_msg = mb_substr($msg . ' (' . $code . ') [' . $sql . ']', 0, 1000) . ' #' . $long_id; - $error_msg = ''.$msg.' ('.$code.')
SQL: '.$this->Debugger->formatSQL($sql); - $long_id = $this->Debugger->mapLongError($error_msg); - trigger_error( mb_substr($msg.' ('.$code.') ['.$sql.']',0,1000).' #'.$long_id, $errorLevel); - return true; + if ( kUtil::constOn('DBG_SQL_FAILURE') && !defined('IS_INSTALL') ) { + throw new Exception($error_msg); + } + else { + $this->Debugger->appendTrace(); + } } - else - { - //$errorLevel = constOn('IS_INSTALL') ? E_USER_WARNING : E_USER_ERROR; - $errorLevel = E_USER_WARNING; - trigger_error('SQL Error in sql: '.$sql.', code '.$code.' ('.$msg.')', $errorLevel); - /*echo 'xProcessing SQL: '.$sql.'
'; - echo 'Error ('.$code.'): '.$msg.'
';*/ - return $errorLevel == E_USER_ERROR ? false : true; + else { + // when not debug mode, then fatal database query won't break anything + $error_msg = 'SQL Error in sql: ' . $sql . ', code ' . $code . ' (' . $msg . ')'; } + + trigger_error($error_msg, E_USER_WARNING); + + return true; } /** @@ -2737,29 +2732,17 @@ * @param int $errline * @param Array $errcontext */ - function handleError($errno, $errstr, $errfile = '', $errline = '', $errcontext = '') + function handleError($errno, $errstr = '', $errfile = '', $errline = '', $errcontext = '') { - if (defined('SILENT_LOG') && SILENT_LOG) { - if ( !(defined('DBG_IGNORE_STRICT_ERRORS') && DBG_IGNORE_STRICT_ERRORS && defined('E_STRICT') && ($errno == E_STRICT)) ) { - $fp = fopen(FULL_PATH.'/silent_log.txt','a'); - $time = adodb_date('d/m/Y H:i:s'); - fwrite($fp, '['.$time.'] #'.$errno.': '.strip_tags($errstr).' in ['.$errfile.'] on line '.$errline."\n"); - fclose($fp); - } - } + $this->errorLogSilent($errno, $errstr, $errfile, $errline); $debug_mode = defined('DEBUG_MODE') && DEBUG_MODE; $skip_reporting = defined('DBG_SKIP_REPORTING') && DBG_SKIP_REPORTING; if (!$this->errorHandlers || ($debug_mode && $skip_reporting)) { // when debugger absent OR it's present, but we actually can't see it's error report (e.g. during ajax request) - $ignore_fatal_errors = defined('DBG_IGNORE_FATAL_ERRORS') && DBG_IGNORE_FATAL_ERRORS; - - if (($errno == E_USER_ERROR) && !$ignore_fatal_errors) { - echo ('
- Fatal Error: '."$errstr in $errfile on line $errline".' -
'); - exit; + if ($errno == E_USER_ERROR) { + $this->errorDisplayFatal('Fatal Error: ' . "{$errstr} in {$errfile} on line {$errline}"); } if (!$this->errorHandlers) { @@ -2768,24 +2751,87 @@ } $res = false; - $i = 0; // while (not foreach) because it is array of references in some cases - $eh_count = count($this->errorHandlers); - while ($i < $eh_count) { - if ( is_array($this->errorHandlers[$i]) ) { - $object =& $this->errorHandlers[$i][0]; - $method = $this->errorHandlers[$i][1]; + + foreach ($this->errorHandlers as $handler) { + if ( is_array($handler) ) { + $object =& $handler[0]; + $method = $handler[1]; $res = $object->$method($errno, $errstr, $errfile, $errline, $errcontext); } else { - $function = $this->errorHandlers[$i]; - $res = $function($errno, $errstr, $errfile, $errline, $errcontext); + $res = $handler($errno, $errstr, $errfile, $errline, $errcontext); } - $i++; } + return $res; } /** + * Handles exception + * + * @param Exception $exception + */ + function handleException($exception) + { + // transform exception to regular error (no need to rewrite existing error handlers) + $errno = $exception->getCode(); + $errstr = $exception->getMessage(); + $errfile = $exception->getFile(); + $errline = $exception->getLine(); + + $this->errorLogSilent($errno, $errstr, $errfile, $errline); + + $debug_mode = defined('DEBUG_MODE') && DEBUG_MODE; + $skip_reporting = defined('DBG_SKIP_REPORTING') && DBG_SKIP_REPORTING; + + if (!$this->exceptionHandlers || ($debug_mode && $skip_reporting)) { + // when debugger absent OR it's present, but we actually can't see it's error report (e.g. during ajax request) + $this->errorDisplayFatal('' . get_class($exception) . ': ' . "{$errstr} in {$errfile} on line {$errline}"); + + if (!$this->exceptionHandlers) { + return true; + } + } + + $res = false; + + foreach ($this->exceptionHandlers as $handler) { + if ( is_array($handler) ) { + $object =& $handler[0]; + $method = $handler[1]; + $res = $object->$method($exception); + } + else { + $res = $handler($exception); + } + } + + return $res; + } + + protected function errorLogSilent($errno, $errstr = '', $errfile = '', $errline = '') + { + if (!defined('SILENT_LOG') || !SILENT_LOG) { + return ; + } + + if ( !(defined('DBG_IGNORE_STRICT_ERRORS') && DBG_IGNORE_STRICT_ERRORS && defined('E_STRICT') && ($errno == E_STRICT)) ) { + $time = adodb_date('d/m/Y H:i:s'); + + $fp = fopen(FULL_PATH . '/silent_log.txt', 'a'); + fwrite($fp, '[' . $time . '] #' . $errno . ': ' . strip_tags($errstr) . ' in [' . $errfile . '] on line ' . $errline . "\n"); + fclose($fp); + } + } + + protected function errorDisplayFatal($msg) + { + $margin = $this->isAdmin ? '8px' : 'auto'; + echo '
' . $msg . '
'; + exit; + } + + /** * Returns & blocks next ResourceId available in system * * @return int @@ -2857,7 +2903,7 @@ */ function &EmailEventAdmin($email_event_name, $to_user_id = null, $send_params = Array ()) { - $event =& $this->EmailEvent($email_event_name, EVENT_TYPE_ADMIN, $to_user_id, $send_params); + $event =& $this->EmailEvent($email_event_name, EmailEvent::EVENT_TYPE_ADMIN, $to_user_id, $send_params); return $event; } @@ -2872,7 +2918,7 @@ */ function &EmailEventUser($email_event_name, $to_user_id = null, $send_params = Array ()) { - $event =& $this->EmailEvent($email_event_name, EVENT_TYPE_FRONTEND, $to_user_id, $send_params); + $event =& $this->EmailEvent($email_event_name, EmailEvent::EVENT_TYPE_FRONTEND, $to_user_id, $send_params); return $event; } @@ -2977,12 +3023,6 @@ } - function reportError($class, $method) - { - $this->Debugger->appendTrace(); - trigger_error('depricated method '.$class.'->'.$method.'(...)', E_USER_ERROR); - } - /** * Returns Window ID of passed prefix main prefix (in edit mode) * @@ -3005,11 +3045,7 @@ */ function GetTempName($table, $wid = '') { - if (preg_match('/prefix:(.*)/', $wid, $regs)) { - $wid = $this->GetTopmostWid($regs[1]); - } - - return TABLE_PREFIX.'ses_'.$this->GetSID().($wid ? '_'.$wid : '').'_edit_'.$table; + return $this->GetTempTablePrefix($wid) . $table; } function GetTempTablePrefix($wid = '') @@ -3018,12 +3054,18 @@ $wid = $this->GetTopmostWid($regs[1]); } - return TABLE_PREFIX.'ses_'.$this->GetSID().($wid ? '_'.$wid : '').'_edit_'; + return TABLE_PREFIX . 'ses_' . $this->GetSID() . ($wid ? '_' . $wid : '') . '_edit_'; } function IsTempTable($table) { - return preg_match('/'.TABLE_PREFIX.'ses_'.$this->GetSID().'(_[\d]+){0,1}_edit_(.*)/',$table); + static $cache = Array (); + + if ( !array_key_exists($table, $cache) ) { + $cache[$table] = preg_match('/'.TABLE_PREFIX.'ses_'.$this->GetSID().'(_[\d]+){0,1}_edit_(.*)/',$table); + } + + return (bool)$cache[$table]; } /** @@ -3034,7 +3076,7 @@ */ function IsTempMode($prefix, $special = '') { - $top_prefix = $this->Application->GetTopmostPrefix($prefix); + $top_prefix = $this->GetTopmostPrefix($prefix); $var_names = Array ( $top_prefix, @@ -3046,7 +3088,7 @@ $temp_mode = false; foreach ($var_names as $var_name) { - $value = $this->Application->GetVar($var_name . '_mode'); + $value = $this->GetVar($var_name . '_mode'); if ($value && (substr($value, 0, 1) == 't')) { $temp_mode = true; break; @@ -3174,7 +3216,7 @@ */ function getCounter($name, $params = Array (), $query_name = null, $multiple_results = false) { - $count_helper =& $this->Application->recallObject('CountHelper'); + $count_helper =& $this->recallObject('CountHelper'); /* @var $count_helper kCountHelper */ return $count_helper->getCounter($name, $params, $query_name, $multiple_results); @@ -3187,11 +3229,11 @@ */ function resetCounters($tables) { - if (constOn('IS_INSTALL')) { + if (kUtil::constOn('IS_INSTALL')) { return ; } - $count_helper =& $this->Application->recallObject('CountHelper'); + $count_helper =& $this->recallObject('CountHelper'); /* @var $count_helper kCountHelper */ return $count_helper->resetCounters($tables); @@ -3246,4 +3288,45 @@ return $this->ModuleInfo['Core']['RootCat']; } + /** + * Sets data from cache to object + * + * @param Array $data + * @access public + */ + public function setFromCache(&$data) + { + $this->ConfigHash = $data['Application.ConfigHash']; + + $this->Caches['ConfigVariables'] = $data['Application.ConfigCacheIds']; // undefined attribute + $this->ConfigCacheIds = $data['Application.ConfigCacheIds']; + + $this->ReplacementTemplates = $data['Application.ReplacementTemplates']; + $this->RewriteListeners = $data['Application.RewriteListeners']; + + $this->ModuleInfo = $data['Application.ModuleInfo']; + } + + /** + * Gets object data for caching + * The following caches should be reset based on admin interaction (adjusting config, enabling modules etc) + * + * @access public + * @return Array + */ + public function getToCache() + { + return Array ( + 'Application.ConfigHash' => $this->ConfigHash, + + 'Application.Caches.ConfigVariables' => $this->Caches['ConfigVariables'], // undefined attribute + 'Application.ConfigCacheIds' => $this->ConfigCacheIds, + + 'Application.ReplacementTemplates' => $this->ReplacementTemplates, + 'Application.RewriteListeners' => $this->RewriteListeners, + + 'Application.ModuleInfo' => $this->ModuleInfo, + ); + } + } \ No newline at end of file