Index: trunk/admin/install/upgrades/inportal_check_v1.0.10.php =================================================================== diff -u -r891 -r1220 --- trunk/admin/install/upgrades/inportal_check_v1.0.10.php (.../inportal_check_v1.0.10.php) (revision 891) +++ trunk/admin/install/upgrades/inportal_check_v1.0.10.php (.../inportal_check_v1.0.10.php) (revision 1220) @@ -1,24 +1,100 @@ 1'; -$rs2 = $ado->Execute($sql); -if ($rs2 && !$rs2->EOF) -{ - $result|=$failCheck; - $CheckErrors[] = 'You have duplicate ResourceId in table "'.$g_TablePrefix.'Category"'; -} -$sql='SELECT ResourceId,COUNT(*) as c FROM '.$g_TablePrefix.'PortalGroup GROUP BY 1 HAVING c>1'; -$rs2 = $ado->Execute($sql); -if ($rs2 && !$rs2->EOF) -{ - $result|=$failCheck; - $CheckErrors[] = 'You have duplicate ResourceId in table "'.$g_TablePrefix.'PortalGroup"'; -} -$sql='SELECT ResourceId,COUNT(*) as c FROM '.$g_TablePrefix.'PortalUser GROUP BY 1 HAVING c>1'; -$rs2 = $ado->Execute($sql); -if ($rs2 && !$rs2->EOF) -{ - $result|=$failCheck; - $CheckErrors[] = 'You have duplicate ResourceId in table "'.$g_TablePrefix.'PortalUser"'; -} + // rid - ResourceId + + $rid_modules=GetModuleArray(); + foreach($rid_modules as $rid_module_name) + { + $rid_path=$pathtoroot.$rid_module_name.'admin/include/parser.php'; + if(file_exists($rid_path)) include_once($rid_path); + } + + function dupe_ResourceIDs_check() + { + global $objModules, $ado; + + // 1. get required info about each module installed + $ret=Array(); + $table_info=$objModules->ExecuteFunction('GetModuleInfo', 'dupe_resourceids'); + + foreach($table_info as $module_name => $module_info) + { + foreach($module_info as $module_sub_info) + { + $module_sub_info['Module']=$module_name; + array_push($ret,$module_sub_info); + } + } + + // 2. build mega sql joining all tables in on and search resource id throught them + $ado->Execute('DROP TABLE IF EXISTS '.GetTablePrefix().'DupeRIDs'); + + $sql=Array(); + $sql_template="SELECT %1\$s AS ID, '%1\$s' AS IDField, ResourceId, '%2\$s' AS TableName FROM ".GetTablePrefix()."%2\$s "; + foreach($ret as $sql_part) + { + $sql[]=sprintf($sql_template,$sql_part['IDField'],$sql_part['Table']); + } + + $module_table=GetTablePrefix().'DupeRIDs '; + + $sql='CREATE TABLE '.$module_table.' '.implode(' UNION ',$sql); + $ado->Execute($sql); + + $sql='SELECT ResourceId FROM '.$module_table.' GROUP BY ResourceId HAVING COUNT(*)>1'; + $duplicate_rids=$ado->GetCol($sql); + if(!$duplicate_rids) return; + + $sql='SELECT * FROM '.$module_table.' WHERE ResourceId IN ('.implode(',',$duplicate_rids).') ORDER BY TableName,ResourceId,ID'; + $rs=$ado->Execute($sql); + + $originals=Array(); // this are originals + $dupes=Array(); // this is dupes + + $update_tpl='UPDATE '.GetTablePrefix().'%s SET ResourceId=%s WHERE %s=%s'; + while(!$rs->EOF) + { + $rec=&$rs->fields; + if( isset($originals[$rec['ResourceId']]) ) + { + // this is dupe + $next_id=GetNextResourceId(); + $update_sql=sprintf($update_tpl,$rec['TableName'],$next_id,$rec['IDField'],$rec['ID']); + $ado->Execute($update_sql); + $dupes[$next_id]=$rec['ID']; + } + else + { + // this is original + $originals[ $rec['ResourceId'] ]=$rec['ID']; + } + $rs->MoveNext(); + } + + if($dupes) + { + // find lost+found category + global $objCatList; + if( !(isset($objCatList) && is_object($objCatList)) ) $objCatList=new clsCatList(); + + $cat=$objCatList->GetItemByField('Name','Lost & Found'); + if( !is_object($cat) ) + { + $cat=&$objCatList->Add(0,'Lost & Found','Lost & Found Items',time(),0,0,2,2,2,0,'',''); + } + + $cat_id=$cat->UniqueId(); + + // move to lost + found category + foreach($dupes as $dupe_rid => $dupe_id) + { + $ado->Execute('INSERT INTO '.GetTablePrefix().'CategoryItems VALUES ('.$cat_id.','.$dupe_rid.',1)'); + } + + } + $ado->Execute('DROP TABLE IF EXISTS '.$module_table); + } + + dupe_ResourceIDs_check(); + ?> \ No newline at end of file Index: trunk/kernel/admin/include/parser.php =================================================================== diff -u -r259 -r1220 --- trunk/kernel/admin/include/parser.php (.../parser.php) (revision 259) +++ trunk/kernel/admin/include/parser.php (.../parser.php) (revision 1220) @@ -270,6 +270,13 @@ case 'all_bitmask': // return bitmask value equals to "all" for module filter return Array('VarName' => 'Category_View', 'Bits' => 127); break; + + case 'dupe_resourceids': + $ret=Array(); + $ret[]=Array('Table'=>'Category','IDField'=>'CategoryId'); + $ret[]=Array('Table'=>'PortalGroup','IDField'=>'GroupId'); + $ret[]=Array('Table'=>'PortalUser','IDField'=>'PortalUserId'); + return $ret; } return false;