Index: trunk/admin/category/permcacheupdate.php =================================================================== diff -u --- trunk/admin/category/permcacheupdate.php (revision 0) +++ trunk/admin/category/permcacheupdate.php (revision 570) @@ -0,0 +1,289 @@ +Stack = Array(); + } + + function Push($values) + { + array_push($this->Stack, $values); + } + + function Pop() + { + if ($this->Count() > 0) { + return array_pop($this->Stack); + } + else { + return false; + } + } + + function Get() + { + if ($this->Count() > 0) { + return end($this->Stack); +// return $this->Stack[count($this->Stack)-1]; + } + else { + return false; + } + } + + function Update($values) + { + $this->Stack[count($this->Stack)-1] = $values; + } + + function Count() + { + return count($this->Stack); + } +} + + +class clsCachedPermissions +{ + var $Allow; + var $Deny; + var $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 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 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 GetInsertSQL() + { + $values = array(); + + $has_deny = array(); + + foreach ($this->Deny as $perm => $groups) { + if (count($groups) > 0) { + $values[] = '('.$this->CatId.', '.$perm.', "", "'.join(',', $groups).'")'; + $has_deny[] = $perm; + } + } + + foreach ($this->Allow as $perm => $groups) { + if (in_array($perm, $has_deny)) continue; + if (count($groups) > 0) { + $values[] = '(' .$this->CatId. ', ' .$perm. ', "' .join(',', $groups). '", "")'; + } + } + if (!$values) return ''; + $sql = 'INSERT INTO inp_PermCache (CategoryId, PermId, ACL, DACL) VALUES '.join(',', $values); + return $sql; + } +} + +class clsCacheUpdater +{ + var $Stack; + var $iteration; + var $totalCats; + var $doneCats; + var $table; + + function clsCacheUpdater($continuing=false) + { + $this->conn =& GetADODBConnection(); + $this->iteration = 0; + $this->table=$GLOBALS['objSession']->GetEditTable('permCacheUpdate'); + + if (!$continuing) { + $this->Stack =& new clsRecursionStack(); + $sql = 'DELETE FROM inp_PermCache'; + $this->conn->Execute($sql); + $this->initData(); + } + else { + $this->getData(); +// $this->SetStack($data); + } + } + function getDonePercent() + { + if(!$this->totalCats)return 0; + return intval( round( $this->doneCats / $this->totalCats * 100 ) ); + } + function getData() + { + $sql='SELECT data FROM '.$this->table; + if( $rs = $this->conn->Execute($sql) ) + $tmp = unserialize($rs->fields['data']); + + $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(); + + } + function setData() + { + $tmp=Array + ( + 'totalCats' =>$this->totalCats, + 'doneCats' =>$this->doneCats, + 'stack' =>$this->Stack, + + ); + $sql='DELETE FROM '.$this->table; + $this->conn->Execute($sql); + $sql='INSERT '.$this->table.' SET data="'.addslashes(serialize($tmp)).'"'; + $this->conn->Execute($sql); + } + function initData() + { + $sql='CREATE TABLE '.$this->table.'(data LONGTEXT)'; + $this->conn->Execute($sql); + + $sql='SELECT COUNT(*) as count FROM '.GetTablePrefix().'Category'; + if( $rs = $this->conn->Execute($sql) ) + $this->totalCats=$rs->fields['count']; + + $this->doneCats=0; + } + function clearData() + { + $sql='DROP TABLE IF EXISTS '.$this->table; + $this->conn->Execute($sql); + } + + function DoTheJob() + { + $data = $this->Stack->Get(); + if ($data === false) { //If Stack is empty + $data['current_id'] = 0; + $this->Stack->Push($data); + } + + if (!isset($data['queried'])) { + + $this->QueryChildren($data); + $this->QueryPermissions($data); + $data['queried'] = 1; + + if($sql = $data['perms']->GetInsertSQL()) + { + $this->conn->Execute($sql); + $this->doneCats++; + } + $this->iteration++; + } + + // start with first child if we haven't started yet + if (!isset($data['current_child'])) $data['current_child'] = 0; + + // if we have more children + if (isset($data['children'][$data['current_child']])) + { + $next_data = array(); + $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']); + $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->Pop(); //remove ourself from stack if we have finished all the childs (or there are none) + // we are getting here if we finished with current level, so check if it's first level - then bail out. + return $this->Stack->Count() > 0; + } + } + + function QueryChildren(&$data) + { + $sql = sprintf('SELECT CategoryId From inp_Category WHERE ParentId = %s', + $data['current_id']); + $rs = $this->conn->Execute($sql); + + $data['children'] = Array(); + while ($rs && !$rs->EOF) + { + $data['children'][] = $rs->fields['CategoryId']; + $rs->MoveNext(); + } + } + + function QueryPermissions(&$data) + { + $sql = sprintf('SELECT ipc.PermissionConfigId, ip.GroupId, ip.PermissionValue FROM inp_Permissions AS ip + LEFT JOIN inp_PermissionConfig AS ipc + ON ipc.PermissionName = ip.Permission + WHERE CatId = %s AND Permission LIKE "%%.VIEW"', + $data['current_id']); + $rs = $this->conn->Execute($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']); + } + + while ($rs && !$rs->EOF) + { + if ($rs->fields['PermissionValue'] == 1) { + $data['perms']->AddAllow($rs->fields['PermissionConfigId'], $rs->fields['GroupId']); + } + else { + $data['perms']->AddDeny($rs->fields['PermissionConfigId'], $rs->fields['GroupId']); + } + $rs->MoveNext(); + } + } +} +?> \ No newline at end of file