Index: trunk/tools/debug_sample.php =================================================================== diff -u -N -r8397 -r8815 --- trunk/tools/debug_sample.php (.../debug_sample.php) (revision 8397) +++ trunk/tools/debug_sample.php (.../debug_sample.php) (revision 8815) @@ -1,74 +1,52 @@ '193.68.72.64/26;69.17.25.153', // !!!REQUIRED!!! Define IP addreses, which are allowed to use debugger (semicolon separated) - 'DEBUG_MODE' => 1, // Debug mode is allowed/disabled (note: set DBG_IP to use this one) -// 'DBG_LOCAL_BASE_PATH' => 'w:', // Folder name on mapped drive, where site resides -// 'DBG_TOOLBAR_BUTTONS' => 1, // Show "Show Debugger" & "Refresh Frame" buttons (on front) + $dbg_options = Array ( + // !!! DEBUG MODE will be off if IP does not match !!! + 'DBG_IP' => '193.68.72.64/26;69.17.25.153', // !!!REQUIRED!!! Define IP addreses, which are allowed to use debugger (semicolon separated) + 'DEBUG_MODE' => 1, // Debug mode is allowed/disabled (note: set DBG_IP to use this one) +// 'DBG_LOCAL_BASE_PATH' => 'w:', // Folder name on mapped drive, where site resides +// 'DBG_TOOLBAR_BUTTONS' => 1, // Show "Show Debugger" & "Refresh Frame" buttons (on front) -// 'DBG_USE_HIGHLIGHT' => 0, // Use "highlight_string" php function for debugger output formatting -// 'DBG_RAISE_ON_WARNINGS' => 1, // Show debugger output in case of any non-fatal error - 'DBG_SQL_PROFILE' => 1, // Profile SQL queries - 'DBG_SQL_FAILURE' => defined('IS_INSTALL') && IS_INSTALL ? 0 : 1, // treat sql errors as fatal errors except for installation process +// 'DBG_USE_HIGHLIGHT' => 0, // Use "highlight_string" php function for debugger output formatting +// 'DBG_RAISE_ON_WARNINGS' => 1, // Show debugger output in case of any non-fatal error + 'DBG_SQL_PROFILE' => 1, // Profile SQL queries + 'DBG_SQL_FAILURE' => defined('IS_INSTALL') && IS_INSTALL ? 0 : 1, // treat sql errors as fatal errors except for installation process - 'DBG_SHOW_HTTPQUERY' => 1, // Show http query content (parsed user submit, GPC) - 'DBG_SHOW_SESSIONDATA' => 1, // Show session data (at script finish) + 'DBG_SHOW_HTTPQUERY' => 1, // Show http query content (parsed user submit, GPC) + 'DBG_SHOW_SESSIONDATA' => 1, // Show session data (at script finish) - 'DBG_EDIT_HELP' => 1, // Show help filename on help screen -// 'DBG_HELP' => 1, // Show FCK editor when viewing help screen + 'DBG_EDIT_HELP' => 1, // Show help filename on help screen +// 'DBG_HELP' => 1, // Show FCK editor when viewing help screen -// 'DBG_FORCE_THEME' => 1, // Use this theme_id instead of one in url - 'DBG_PHRASES' => 1, // Add ability to translate phrases on the fly (K4 templates only) -// 'DBG_WINDOW_WIDTH' => 700, // Set custom debugger layer width (in pixels) +// 'DBG_FORCE_THEME' => 1, // Use this theme_id instead of one in url + 'DBG_PHRASES' => 1, // Add ability to translate phrases on the fly (K4 templates only) +// 'DBG_WINDOW_WIDTH' => 700, // Set custom debugger layer width (in pixels) -// 'DBG_REDIRECT' => 1, // Show links with redirect url instead of performing it (useful in events debugging) +// 'DBG_REDIRECT' => 1, // Show links with redirect url instead of performing it (useful in events debugging) -// 'DBG_VALIDATE_CONFIGS' => 1, // Check that config fields match ones from database -// 'DBG_SHOW_TAGS' => 1, // Show tags beeing processed -// 'DBG_PRE_PARSE' => 1, // Show new compiled functions in debugger -// 'DBG_SHOW_TREE_PRIORITY'=> 1, // Show tree node priority -// 'DBG_SKIP_AJAX' => 1, // Don't debug AJAX requests -// 'DBG_PAYMENT_GW' => 1, // All requests to payment gateways goes in TEST MODE -// 'DBG_IMAGE_RECOVERY' => 1, // Don't replace missing images with noimage.gif - ); +// 'DBG_VALIDATE_CONFIGS' => 1, // Check that config fields match ones from database +// 'DBG_SHOW_TAGS' => 1, // Show tags beeing processed +// 'DBG_PRE_PARSE' => 1, // Show new compiled functions in debugger +// 'DBG_SHOW_TREE_PRIORITY'=> 1, // Show tree node priority +// 'DBG_SKIP_AJAX' => 1, // Don't debug AJAX requests +// 'DBG_PAYMENT_GW' => 1, // All requests to payment gateways goes in TEST MODE +// 'DBG_IMAGE_RECOVERY' => 1, // Don't replace missing images with noimage.gif + ); + // for ADODB to work: begin + define('ADODB_OUTP', 'dbg_SQLLog'); + function dbg_SQLLog($msg, $new_line = false) { } + // for ADODB to work: end - // for ADODB to work: begin - define('ADODB_OUTP', 'dbg_SQLLog'); - function dbg_SQLLog($msg, $new_line = false) { } - // for ADODB to work: end - - - function isSkipTable($sql) - { -// return false; - - // don't show sqls that use one or more tables from list below - static $skipTables = Array( 'PermissionConfig','SessionData','Permissions', - 'Phrase','Cache','Modules','Events', - 'PersistantSessionData','EmailQueue','UserSession', - 'ThemeFiles', 'Language','ConfigurationValues'); - - foreach ($skipTables as $table) { - if( dbg_tableMatch($table, $sql) ) { - return true; - } - } - - return false; - } - function dbg_tableMatch($table_name,$sql) - { - static $prefix = ''; - $prefix = defined('TABLE_PREFIX')?TABLE_PREFIX:GetTablePrefix(); - return strpos($sql,$prefix.$table_name)!==false; - } - -?> + { + static $prefix = ''; + $prefix = defined('TABLE_PREFIX')?TABLE_PREFIX:GetTablePrefix(); + return strpos($sql,$prefix.$table_name)!==false; + } +?> \ No newline at end of file Index: trunk/kernel/include/adodb/adodb.inc.php =================================================================== diff -u -N -r8436 -r8815 --- trunk/kernel/include/adodb/adodb.inc.php (.../adodb.inc.php) (revision 8436) +++ trunk/kernel/include/adodb/adodb.inc.php (.../adodb.inc.php) (revision 8815) @@ -737,13 +737,12 @@ $profileSQLs = constOn('DBG_SQL_PROFILE'); if ($profileSQLs) { - $isSkipTable = isSkipTable($sql); $queryID = $debugger->generateID(); - if(!$isSkipTable) $debugger->profileStart('sql_'.$queryID, $debugger->formatSQL($sql) ); + $debugger->profileStart('sql_'.$queryID, $debugger->formatSQL($sql) ); //$debugger->appendTrace(); } $this->_queryID = $this->_query($sql,$inputarr,$arg3); - if ($profileSQLs && !$isSkipTable) { + if ($profileSQLs) { $debugger->profileFinish('sql_'.$queryID, null, null, $this->Affected_Rows()); $debugger->profilerAddTotal('sql', 'sql_'.$queryID); } Index: trunk/core/units/categories/cache_updater.php =================================================================== diff -u -N -r8555 -r8815 --- trunk/core/units/categories/cache_updater.php (.../cache_updater.php) (revision 8555) +++ trunk/core/units/categories/cache_updater.php (.../cache_updater.php) (revision 8815) @@ -1,418 +1,486 @@ Stack = Array(); - } + function clsRecursionStack() + { + $this->Stack = Array(); + } - function Push($values) - { - array_push($this->Stack, $values); - } + function Push($values) + { + array_push($this->Stack, $values); + } - function Pop() - { - if ($this->Count() > 0) { - return array_pop($this->Stack); + function Pop() + { + if ($this->Count() > 0) { + return array_pop($this->Stack); + } + else { + return false; + } } - else { - return false; + + function Get() + { + if ($this->Count() > 0) { + // return end($this->Stack); + return $this->Stack[count($this->Stack)-1]; + } + else { + return false; + } } - } - function Get() - { - if ($this->Count() > 0) { -// return end($this->Stack); - return $this->Stack[count($this->Stack)-1]; + function Update($values) + { + $this->Stack[count($this->Stack)-1] = $values; } - else { - return false; + + function Count() + { + return count($this->Stack); } } - function Update($values) - { - $this->Stack[count($this->Stack)-1] = $values; - } + class clsCachedPermissions { + var $Allow = Array(); + var $Deny = Array(); + var $CatId; - function Count() - { - return count($this->Stack); - } -} + /** + * Table name used for inserting permissions + * + * @var string + */ + var $table = ''; + function clsCachedPermissions($CatId, $table_name) + { + $this->CatId = $CatId; + $this->table = $table_name; + } -class clsCachedPermissions -{ - var $Allow = Array(); - var $Deny = Array(); - var $CatId; + function SetCatId($CatId) + { + $this->CatId = $CatId; + } - function clsCachedPermissions($CatId) - { - $this->CatId = $CatId; - } - - function SetCatId($CatId) - { - $this->CatId = $CatId; - } - - function CheckPermArray($Perm) - { - if (!isset($this->Allow[$Perm])) { - $this->Allow[$Perm] = array(); - $this->Deny[$Perm] = array(); + function CheckPermArray($Perm) + { + if (!isset($this->Allow[$Perm])) { + $this->Allow[$Perm] = array(); + $this->Deny[$Perm] = array(); + } } - } - function AddAllow($Perm, $GroupId) - { - $this->CheckPermArray($Perm); - if (!in_array($GroupId, $this->Allow[$Perm])) { - array_push($this->Allow[$Perm], $GroupId); - $this->RemoveDeny($Perm, $GroupId); + function AddAllow($Perm, $GroupId) + { + $this->CheckPermArray($Perm); + if (!in_array($GroupId, $this->Allow[$Perm])) { + array_push($this->Allow[$Perm], $GroupId); + $this->RemoveDeny($Perm, $GroupId); + } } - } - function AddDeny($Perm, $GroupId) - { - $this->CheckPermArray($Perm); - if (!in_array($GroupId, $this->Deny[$Perm])) { - array_push($this->Deny[$Perm], $GroupId); - $this->RemoveAllow($Perm, $GroupId); + function AddDeny($Perm, $GroupId) + { + $this->CheckPermArray($Perm); + if (!in_array($GroupId, $this->Deny[$Perm])) { + array_push($this->Deny[$Perm], $GroupId); + $this->RemoveAllow($Perm, $GroupId); + } } - } - function RemoveDeny($Perm, $GroupId) - { - if (in_array($GroupId, $this->Deny[$Perm])) { - array_splice($this->Deny[$Perm], array_search($GroupId, $this->Deny[$Perm]), 1); + function RemoveDeny($Perm, $GroupId) + { + if (in_array($GroupId, $this->Deny[$Perm])) { + array_splice($this->Deny[$Perm], array_search($GroupId, $this->Deny[$Perm]), 1); + } } - } - function RemoveAllow($Perm, $GroupId) - { - if (in_array($GroupId, $this->Allow[$Perm])) { - array_splice($this->Allow[$Perm], array_search($GroupId, $this->Allow[$Perm]), 1); + function RemoveAllow($Perm, $GroupId) + { + if (in_array($GroupId, $this->Allow[$Perm])) { + array_splice($this->Allow[$Perm], array_search($GroupId, $this->Allow[$Perm]), 1); + } } - } - function GetInsertSQL() - { - $values = array(); - foreach ($this->Allow as $perm => $groups) { - if (count($groups) > 0) { - $values[] = '(' .$this->CatId. ', ' .$perm. ', "' .join(',', $groups). '")'; + function GetInsertSQL() + { + $values = array(); + foreach ($this->Allow as $perm => $groups) { + if (count($groups) > 0) { + $values[] = '(' .$this->CatId. ', ' .$perm. ', "' .join(',', $groups). '")'; + } } + if (!$values) return ''; + $sql = 'INSERT INTO '.$this->table.' (CategoryId, PermId, ACL) VALUES '.join(',', $values); + return $sql; } - if (!$values) return ''; - $sql = 'INSERT INTO '.TABLE_PREFIX.'PermCache (CategoryId, PermId, ACL) VALUES '.join(',', $values); - return $sql; } -} -class kPermCacheUpdater extends kHelper -{ - /** - * Holds Stack - * - * @var clsRecursionStack - */ - var $Stack; - var $iteration; - var $totalCats; - var $doneCats; - var $table; + class kPermCacheUpdater extends kHelper { + /** + * Holds Stack + * + * @var clsRecursionStack + */ + var $Stack; - var $primaryLanguageId = 0; - var $languageCount = 0; - var $root_prefixes = Array(); - var $StrictPath = false; + /** + * Rebuild process iteration + * + * @var int + */ + var $iteration; - function Init($prefix, $special, $event_params = null) - { - parent::Init($prefix, $special, $event_params); + /** + * Categories count to process + * + * @var unknown_type + */ + var $totalCats = 0; - $continuing = isset($event_params['continue']) ? $event_params['continue'] : 1; - $this->StrictPath = isset($event_params['strict_path']) ? $event_params['strict_path'] : false; - if ($this->StrictPath && !is_array($this->StrictPath)) { - $this->StrictPath = explode('|', trim($this->StrictPath, '|')); - } + /** + * Processed categories count + * + * @var int + */ + var $doneCats = 0; - // cache widely used values to speed up process: begin - $ml_helper =& $this->Application->recallObject('kMultiLanguageHelper'); - $this->languageCount = $ml_helper->getLanguageCount(); - $this->primaryLanguageId = $this->Application->GetDefaultLanguageId(); - // cache widely used values to speed up process: end + /** + * Temporary table name used for storing cache building progress + * + * @var string + */ + var $progressTable = ''; - foreach ($this->Application->ModuleInfo as $module_name => $module_info) { - $this->root_prefixes[ $module_info['RootCat'] ] = $module_info['Var']; - } + /** + * Temporary table name used for storing not fully built permissions cache + * 1. preserves previous cache while new cache is building + * 2. when rebuild process fails allows previous cache (in live table) is used + * + * @var string + */ + var $permCacheTable = ''; - $this->iteration = 0; - $this->table = $this->Application->GetTempName('permCacheUpdate'); + var $primaryLanguageId = 0; + var $languageCount = 0; + var $root_prefixes = Array(); - if ($continuing == 1) { - $this->InitUpdater(); + /** + * Update cache only for requested categories and it's parent categories + * + * @var bool + */ + var $StrictPath = false; + + function Init($prefix, $special, $event_params = null) + { + parent::Init($prefix, $special, $event_params); + + $continuing = isset($event_params['continue']) ? $event_params['continue'] : 1; + $this->StrictPath = isset($event_params['strict_path']) ? $event_params['strict_path'] : false; + if ($this->StrictPath && !is_array($this->StrictPath)) { + $this->StrictPath = explode('|', trim($this->StrictPath, '|')); + } + + // cache widely used values to speed up process: begin + $ml_helper =& $this->Application->recallObject('kMultiLanguageHelper'); + $this->languageCount = $ml_helper->getLanguageCount(); + $this->primaryLanguageId = $this->Application->GetDefaultLanguageId(); + // cache widely used values to speed up process: end + + foreach ($this->Application->ModuleInfo as $module_name => $module_info) { + $this->root_prefixes[ $module_info['RootCat'] ] = $module_info['Var']; + } + + $this->iteration = 0; + $this->progressTable = $this->Application->GetTempName('permCacheUpdate'); + $this->permCacheTable = $this->Application->GetTempName(TABLE_PREFIX.'PermCache'); + + if ($continuing == 1) { + $this->InitUpdater(); + } + elseif ($continuing == 2) { + $this->getData(); + } } - elseif ($continuing == 2) { - $this->getData(); + + function InitUpdater() + { + $this->Stack =& new clsRecursionStack(); + $this->initData(); } - } - function InitUpdater() - { - $this->Stack =& new clsRecursionStack(); - $sql = 'DELETE FROM '.TABLE_PREFIX.'PermCache'; - if ($this->StrictPath) { - $sql .= ' WHERE CategoryId IN ('.implode(',',$this->StrictPath).')'; + function getDonePercent() + { + if (!$this->totalCats) { + return 0; + } + return min(100, intval( floor( $this->doneCats / $this->totalCats * 100 ) )); } - $this->Conn->Query($sql); - $this->initData(); - } - function getDonePercent() - { - if(!$this->totalCats)return 0; - return min(100, intval( floor( $this->doneCats / $this->totalCats * 100 ) )); - } + function getData() + { + $tmp = $this->Conn->GetOne('SELECT data FROM '.$this->progressTable); + if ($tmp) $tmp = unserialize($tmp); - function getData() - { - $tmp = $this->Conn->GetOne('SELECT data FROM '.$this->table); - if ($tmp) $tmp = unserialize($tmp); - - $this->totalCats = isset($tmp['totalCats']) ? $tmp['totalCats'] : 0; - $this->doneCats = isset($tmp['doneCats']) ? $tmp['doneCats'] : 0; - if (isset($tmp['stack'])) { - $this->Stack = $tmp['stack']; + $this->totalCats = isset($tmp['totalCats']) ? $tmp['totalCats'] : 0; + $this->doneCats = isset($tmp['doneCats']) ? $tmp['doneCats'] : 0; + if (isset($tmp['stack'])) { + $this->Stack = $tmp['stack']; + } + else { + $this->Stack =& new clsRecursionStack(); + } } - else { - $this->Stack = & new clsRecursionStack(); - } - } - function setData() - { - $tmp = Array ( - 'totalCats' => $this->totalCats, - 'doneCats' => $this->doneCats, - 'stack' => $this->Stack, - ); + function setData() + { + $tmp = Array ( + 'totalCats' => $this->totalCats, + 'doneCats' => $this->doneCats, + 'stack' => $this->Stack, + ); - $this->Conn->Query('DELETE FROM '.$this->table); + $this->Conn->Query('DELETE FROM '.$this->progressTable); - $fields_hash = Array('data' => serialize($tmp)); - $this->Conn->doInsert($fields_hash, $this->table); - } + $fields_hash = Array('data' => serialize($tmp)); + $this->Conn->doInsert($fields_hash, $this->progressTable); + } - function initData() - { - $this->clearData(); // drop table before starting anyway + function initData() + { + $this->clearData(true); // drop table before starting anyway - $this->Conn->Query('CREATE TABLE '.$this->table.'(data LONGTEXT)'); + // 1. create table for rebuilding permissions cache + $this->Conn->Query('CREATE TABLE '.$this->permCacheTable.' LIKE '.TABLE_PREFIX.'PermCache'); - $this->totalCats = (int)$this->Conn->GetOne('SELECT COUNT(*) FROM '.TABLE_PREFIX.'Category'); - $this->doneCats = 0; - } + if ($this->StrictPath) { + // when using strict path leave all other cache intact + $sql = 'INSERT INTO '.$this->permCacheTable.' + SELECT * + FROM '.TABLE_PREFIX.'PermCache'; + $this->Conn->Query($sql); - function clearData() - { - $this->Conn->Query('DROP TABLE IF EXISTS '.$this->table); - $this->Conn->Query('DELETE FROM '.TABLE_PREFIX.'Cache WHERE VarName = \'ForcePermCacheUpdate\''); - } + // delete only cache related to categories in path + $sql = 'DELETE FROM '.$this->permCacheTable.' + WHERE CategoryId IN ('.implode(',', $this->StrictPath).')'; + $this->Conn->Query($sql); + } - function DoTheJob() - { - $data = $this->Stack->Get(); - if ($data === false) { //If Stack is empty - $data['current_id'] = 0; - $data['titles'] = Array(); - $data['parent_path'] = Array(); - $data['named_path'] = Array(); - $data['category_template'] = ''; - $data['item_template'] = ''; - $data['children_count'] = 0; - $data['system'] = 0; - $data['left'] = 0; - $data['right'] = 2; - $data['debug_title'] = 'ROOT'; - $this->Stack->Push($data); + $this->Conn->Query('CREATE TABLE '.$this->progressTable.'(data LONGTEXT)'); + + $this->totalCats = (int)$this->Conn->GetOne('SELECT COUNT(*) FROM '.TABLE_PREFIX.'Category'); + $this->doneCats = 0; } - if (!isset($data['queried'])) { - $this->QueryTitle($data); - $this->QueryChildren($data); - $data['children_count'] = count($data['children']); - $this->QueryPermissions($data); - $data['queried'] = 1; - $data['right'] = $data['left']+1; + function clearData($init_updater = false) + { + if (!$init_updater) { + // copy data from temp permission cache table back to live + $this->Conn->Query('TRUNCATE '.TABLE_PREFIX.'PermCache'); - if ($sql = $data['perms']->GetInsertSQL()) { + $sql = 'INSERT INTO '.TABLE_PREFIX.'PermCache + SELECT * + FROM '.$this->permCacheTable; $this->Conn->Query($sql); - // $this->doneCats++; // moved to the place where it pops out of the stack by Kostja } - $this->iteration++; + + $this->Conn->Query('DROP TABLE IF EXISTS '.$this->progressTable); + $this->Conn->Query('DROP TABLE IF EXISTS '.$this->permCacheTable); + $this->Conn->Query('DELETE FROM '.TABLE_PREFIX.'Cache WHERE VarName = \'ForcePermCacheUpdate\''); } - // start with first child if we haven't started yet - if (!isset($data['current_child'])) $data['current_child'] = 0; + function DoTheJob() + { + $data = $this->Stack->Get(); + if ($data === false) { //If Stack is empty + $data['current_id'] = 0; + $data['titles'] = Array(); + $data['parent_path'] = Array(); + $data['named_path'] = Array(); + $data['category_template'] = ''; + $data['item_template'] = ''; + $data['children_count'] = 0; + $data['system'] = 0; + $data['left'] = 0; + $data['right'] = 2; + $data['debug_title'] = 'ROOT'; + $this->Stack->Push($data); + } - // if we have more children on CURRENT LEVEL - if (isset($data['children'][$data['current_child']])) { - if ($this->StrictPath) { - while ( isset($data['children'][ $data['current_child'] ]) && !in_array($data['children'][ $data['current_child'] ], $this->StrictPath) ) { - $data['current_child']++; - continue; + if (!isset($data['queried'])) { + $this->QueryTitle($data); + $this->QueryChildren($data); + $data['children_count'] = count($data['children']); + $this->QueryPermissions($data); + $data['queried'] = 1; + $data['right'] = $data['left']+1; + + if ($sql = $data['perms']->GetInsertSQL()) { + $this->Conn->Query($sql); + // $this->doneCats++; // moved to the place where it pops out of the stack by Kostja } - if (!isset($data['children'][ $data['current_child'] ])) return false; //error + $this->iteration++; } - $next_data = Array(); - $next_data['titles'] = $data['titles']; - $next_data['parent_path'] = $data['parent_path']; - $next_data['named_path'] = $data['named_path']; - $next_data['category_template'] = $data['category_template']; - $next_data['item_template'] = $data['item_template']; - $next_data['current_id'] = $data['children'][ $data['current_child'] ]; //next iteration should process child - $next_data['perms'] = $data['perms']; //we should copy our permissions to child - inheritance - $next_data['perms']->SetCatId($next_data['current_id']); - $next_data['left'] = $data['right']; - $data['current_child']++; - $this->Stack->Update($data); //we need to update ourself for the iteration after the next (or further) return to next child - $this->Stack->Push($next_data); //next iteration should process this child - return true; - } - else { - $this->Stack->Update($data); - $prev_data = $this->Stack->Pop(); //remove ourself from stack if we have finished all the childs (or there are none) - $data['right'] = $prev_data['right']; - $this->UpdateCachedPath($data); - // we are getting here if we finished with current level, so check if it's first level - then bail out. - $this->doneCats++; // moved by Kostja from above, seems to fix the prob - $has_more = $this->Stack->Count() > 0; - if ($has_more) { - $next_data = $this->Stack->Get(); - $next_data['right'] = $data['right']+1; - $next_data['children_count'] += $data['children_count']; - $this->Stack->Update($next_data); + // start with first child if we haven't started yet + if (!isset($data['current_child'])) $data['current_child'] = 0; + + // if we have more children on CURRENT LEVEL + if (isset($data['children'][$data['current_child']])) { + if ($this->StrictPath) { + while ( isset($data['children'][ $data['current_child'] ]) && !in_array($data['children'][ $data['current_child'] ], $this->StrictPath) ) { + $data['current_child']++; + continue; + } + if (!isset($data['children'][ $data['current_child'] ])) return false; //error + } + $next_data = Array(); + $next_data['titles'] = $data['titles']; + $next_data['parent_path'] = $data['parent_path']; + $next_data['named_path'] = $data['named_path']; + $next_data['category_template'] = $data['category_template']; + $next_data['item_template'] = $data['item_template']; + $next_data['current_id'] = $data['children'][ $data['current_child'] ]; //next iteration should process child + $next_data['perms'] = $data['perms']; //we should copy our permissions to child - inheritance + $next_data['perms']->SetCatId($next_data['current_id']); + $next_data['left'] = $data['right']; + $data['current_child']++; + $this->Stack->Update($data); //we need to update ourself for the iteration after the next (or further) return to next child + $this->Stack->Push($next_data); //next iteration should process this child + return true; } - return $has_more; - } - } + else { + $this->Stack->Update($data); + $prev_data = $this->Stack->Pop(); //remove ourself from stack if we have finished all the childs (or there are none) + $data['right'] = $prev_data['right']; + $this->UpdateCachedPath($data); + // we are getting here if we finished with current level, so check if it's first level - then bail out. - function UpdateCachedPath(&$data) - { - $fields_hash = Array ( - 'ParentPath' => '|'.implode('|', $data['parent_path']).'|', - 'NamedParentPath' => $data['system'] ? $data['file_name'] : implode('/', $data['named_path'] ), - 'CachedCategoryTemplate' => $data['category_template'], - 'CachedDescendantCatsQty' => $data['children_count'], - 'TreeLeft' => $data['left'], - 'TreeRight' => $data['right'], - ); - - $i = 1; - while ($i <= $this->languageCount) { - $fields_hash['l'.$i.'_CachedNavbar'] = implode('&|&', $data['titles'][$i]); - $i++; + $this->doneCats++; // moved by Kostja from above, seems to fix the prob + $has_more = $this->Stack->Count() > 0; + if ($has_more) { + $next_data = $this->Stack->Get(); + $next_data['right'] = $data['right']+1; + $next_data['children_count'] += $data['children_count']; + $this->Stack->Update($next_data); + } + return $has_more; + } } - $this->Conn->doUpdate($fields_hash, TABLE_PREFIX.'Category', 'CategoryId = '.$data['current_id']); - } + function UpdateCachedPath(&$data) + { + $fields_hash = Array ( + 'ParentPath' => '|'.implode('|', $data['parent_path']).'|', + 'NamedParentPath' => $data['system'] ? $data['file_name'] : implode('/', $data['named_path'] ), + 'CachedCategoryTemplate' => $data['category_template'], + 'CachedDescendantCatsQty' => $data['children_count'], + 'TreeLeft' => $data['left'], + 'TreeRight' => $data['right'], + ); - function QueryTitle(&$data) - { - $category_id = $data['current_id']; - $sql = 'SELECT * - FROM '.TABLE_PREFIX.'Category - WHERE CategoryId = '.$category_id; - - $record = $this->Conn->GetRow($sql); - if ($record) { $i = 1; while ($i <= $this->languageCount) { - $data['titles'][$i][] = $record['l'.$i.'_Name'] ? $record['l'.$i.'_Name'] : $record['l'.$this->primaryLanguageId.'_Name']; + $fields_hash['l'.$i.'_CachedNavbar'] = implode('&|&', $data['titles'][$i]); $i++; } - $data['debug_title'] = $record['l1_Name']; - $data['parent_path'][] = $category_id; - $data['named_path'][] = preg_replace('/^Content\\//', '', $record['Filename']); - $data['system'] = $record['IsSystem']; - $data['file_name'] = $record['Filename']; + $this->Conn->doUpdate($fields_hash, TABLE_PREFIX.'Category', 'CategoryId = '.$data['current_id']); + } - // it is one of the modules root category - $root_prefix = isset($this->root_prefixes[$category_id]) ? $this->root_prefixes[$category_id] : false; - if ($root_prefix) { - $fields_hash = Array(); - if (!$record['CategoryTemplate']) { - $record['CategoryTemplate'] = $this->Application->ConfigValue($root_prefix.'_CategoryTemplate'); - $fields_hash['CategoryTemplate'] = $record['CategoryTemplate']; + function QueryTitle(&$data) + { + $category_id = $data['current_id']; + $sql = 'SELECT * + FROM '.TABLE_PREFIX.'Category + WHERE CategoryId = '.$category_id; + + $record = $this->Conn->GetRow($sql); + if ($record) { + $i = 1; + while ($i <= $this->languageCount) { + $data['titles'][$i][] = $record['l'.$i.'_Name'] ? $record['l'.$i.'_Name'] : $record['l'.$this->primaryLanguageId.'_Name']; + $i++; } + $data['debug_title'] = $record['l1_Name']; - $this->Conn->doUpdate($fields_hash, TABLE_PREFIX.'Category', 'CategoryId = '.$category_id); - } + $data['parent_path'][] = $category_id; + $data['named_path'][] = preg_replace('/^Content\\//', '', $record['Filename']); + $data['system'] = $record['IsSystem']; + $data['file_name'] = $record['Filename']; - // if explicitly set, then use it; use parent template otherwise - if ($record['CategoryTemplate']) { - $data['category_template'] = $record['CategoryTemplate']; + // it is one of the modules root category + $root_prefix = isset($this->root_prefixes[$category_id]) ? $this->root_prefixes[$category_id] : false; + if ($root_prefix) { + $fields_hash = Array(); + if (!$record['CategoryTemplate']) { + $record['CategoryTemplate'] = $this->Application->ConfigValue($root_prefix.'_CategoryTemplate'); + $fields_hash['CategoryTemplate'] = $record['CategoryTemplate']; + } + + $this->Conn->doUpdate($fields_hash, TABLE_PREFIX.'Category', 'CategoryId = '.$category_id); + } + + // if explicitly set, then use it; use parent template otherwise + if ($record['CategoryTemplate']) { + $data['category_template'] = $record['CategoryTemplate']; + } } + } - } + function QueryChildren(&$data) + { + $sql = 'SELECT CategoryId + FROM '.TABLE_PREFIX.'Category + WHERE ParentId = '.$data['current_id']; + $data['children'] = $this->Conn->GetCol($sql); + } - function QueryChildren(&$data) - { - $sql = 'SELECT CategoryId - FROM '.TABLE_PREFIX.'Category - WHERE ParentId = '.$data['current_id']; - $data['children'] = $this->Conn->GetCol($sql); - } + function QueryPermissions(&$data) + { + // don't search for section "view" permissions here :) + $sql = 'SELECT ipc.PermissionConfigId, ip.GroupId, ip.PermissionValue + FROM '.TABLE_PREFIX.'Permissions AS ip + LEFT JOIN '.TABLE_PREFIX.'PermissionConfig AS ipc ON ipc.PermissionName = ip.Permission + WHERE (CatId = '.$data['current_id'].') AND (Permission LIKE "%.VIEW") AND (ip.Type = 0)'; - function QueryPermissions(&$data) - { - // don't search for section "view" permissions here :) - $sql = 'SELECT ipc.PermissionConfigId, ip.GroupId, ip.PermissionValue - FROM '.TABLE_PREFIX.'Permissions AS ip - LEFT JOIN '.TABLE_PREFIX.'PermissionConfig AS ipc ON ipc.PermissionName = ip.Permission - WHERE (CatId = '.$data['current_id'].') AND (Permission LIKE "%.VIEW") AND (ip.Type = 0)'; + $records = $this->Conn->Query($sql); - $records = $this->Conn->Query($sql); + //create permissions array only if we don't have it yet (set by parent) + if (!isset($data['perms'])) { + $data['perms'] = new clsCachedPermissions($data['current_id'], $this->permCacheTable); + } - //create permissions array only if we don't have it yet (set by parent) - if (!isset($data['perms'])) { - $data['perms'] = new clsCachedPermissions($data['current_id']); + foreach ($records as $record) { + if ($record['PermissionValue'] == 1) { + $data['perms']->AddAllow($record['PermissionConfigId'], $record['GroupId']); + } + else { + $data['perms']->AddDeny($record['PermissionConfigId'], $record['GroupId']); + } + } } - foreach ($records as $record) { - if ($record['PermissionValue'] == 1) { - $data['perms']->AddAllow($record['PermissionConfigId'], $record['GroupId']); + /** + * Rebuild all cache in one step + * + */ + function OneStepRun($path='') + { + $this->InitUpdater(); + $needs_more = true; + while ($needs_more) { + // until proceeeded in this step category count exceeds category per step limit + $needs_more = $this->DoTheJob(); } - else { - $data['perms']->AddDeny($record['PermissionConfigId'], $record['GroupId']); - } + $this->clearData(); } } - - /** - * Rebuild all cache in one step - * - */ - function OneStepRun($path='') - { - $this->InitUpdater(); - $needs_more = true; - while ($needs_more) { - // until proceeeded in this step category count exceeds category per step limit - $needs_more = $this->DoTheJob(); - } - $this->clearData(); - } -} ?> \ No newline at end of file Index: trunk/core/kernel/db/db_connection.php =================================================================== diff -u -N -r8598 -r8815 --- trunk/core/kernel/db/db_connection.php (.../db_connection.php) (revision 8598) +++ trunk/core/kernel/db/db_connection.php (.../db_connection.php) (revision 8815) @@ -374,14 +374,10 @@ $query_func = $this->getMetaFunction('query'); // set 1st checkpoint: begin - $isSkipTable = true; $profileSQLs = defined('DBG_SQL_PROFILE') && DBG_SQL_PROFILE; if ($profileSQLs) { - $isSkipTable = isSkipTable($sql); - if (!$isSkipTable) { - $queryID = $debugger->generateID(); - $debugger->profileStart('sql_'.$queryID, $debugger->formatSQL($sql)); - } + $queryID = $debugger->generateID(); + $debugger->profileStart('sql_'.$queryID, $debugger->formatSQL($sql)); } // set 1st checkpoint: end @@ -406,22 +402,18 @@ } } // set 2nd checkpoint: begin - if(!$isSkipTable) { - $first_cell = count($ret) == 1 && count(current($ret)) == 1 ? current(current($ret)) : null; + $first_cell = count($ret) == 1 && count(current($ret)) == 1 ? current(current($ret)) : null; - $debugger->profileFinish('sql_'.$queryID, null, null, $this->getAffectedRows(), $first_cell); - $debugger->profilerAddTotal('sql', 'sql_'.$queryID); - } + $debugger->profileFinish('sql_'.$queryID, null, null, $this->getAffectedRows(), $first_cell); + $debugger->profilerAddTotal('sql', 'sql_'.$queryID); $this->Destroy(); // set 2nd checkpoint: end return $ret; } else { // set 2nd checkpoint: begin - if(!$isSkipTable) { - $debugger->profileFinish('sql_'.$queryID, null, null, $this->getAffectedRows()); - $debugger->profilerAddTotal('sql', 'sql_'.$queryID); - } + $debugger->profileFinish('sql_'.$queryID, null, null, $this->getAffectedRows()); + $debugger->profilerAddTotal('sql', 'sql_'.$queryID); // set 2nd checkpoint: end } $this->showError($sql);