AntonLV 1 год назад
Родитель
Сommit
61bcb48a0f

+ 11 - 2
modules/boonex/reputation/classes/BxReputationAlertsResponse.php

@@ -54,9 +54,14 @@ class BxReputationAlertsResponse extends BxBaseModNotificationsResponse
 
         $iOwnerId = $oAlert->iSender;
         $iObjectOwnerId = abs($this->_getObjectOwnerId($oAlert->aExtras));
+        $iObjectPrivacyView = $this->_getObjectPrivacyView($oAlert->aExtras);
+
+        $bInContext = $iObjectPrivacyView < 0;
+        $iContextId = $bInContext ? abs($iObjectPrivacyView) : 0;
 
         $aEvent = [
             'owner_id' => 0,
+            'context_id' => $iContextId,
             'type' => $oAlert->sUnit,
             'action' => $oAlert->sAction,
             'object_id' => $oAlert->iObject,
@@ -71,7 +76,9 @@ class BxReputationAlertsResponse extends BxBaseModNotificationsResponse
                 'points' => $iPoints
             ]));
 
-            $this->_oModule->assignPoints($iOwnerId, $iPoints);
+            $this->_oModule->assignPoints($iOwnerId, 0, $iPoints);
+            if($bInContext)
+                $this->_oModule->assignPoints($iOwnerId, $iContextId, $iPoints);
         }
 
         if(($iPoints = (int)$aHandler['points_passive']) != 0 && $iOwnerId != $iObjectOwnerId) {
@@ -80,7 +87,9 @@ class BxReputationAlertsResponse extends BxBaseModNotificationsResponse
                 'points' => $iPoints
             ]));
 
-            $this->_oModule->assignPoints($iObjectOwnerId, $iPoints);
+            $this->_oModule->assignPoints($iObjectOwnerId, 0, $iPoints);
+            if($bInContext)
+                $this->_oModule->assignPoints($iObjectOwnerId, $iContextId, $iPoints);
         }
     }
 

+ 55 - 26
modules/boonex/reputation/classes/BxReputationDb.php

@@ -44,7 +44,14 @@ class BxReputationDb extends BxBaseModNotificationsDb
                     'owner_id' => $aParams['owner_id']
                 ];
 
-                $sWhereClause = 'AND `owner_id`=:owner_id';
+                $sWhereClause = 'AND `owner_id` = :owner_id';
+
+                if(isset($aParams['context_id']) && $aParams['context_id'] !== false) {
+                    $aMethod['params'][1]['context_id'] = $aParams['context_id'];
+
+                    $sWhereClause .= ' AND `context_id` = :context_id';
+                }
+
                 $sOrderClause = '`date` DESC';
                 if(isset($aParams['start'], $aParams['limit']))
                     $sLimitClause = $aParams['start'] . ', ' . $aParams['limit'];
@@ -58,8 +65,17 @@ class BxReputationDb extends BxBaseModNotificationsDb
 
                 $sSelectClause = '`owner_id`, SUM(`points`) AS `points`';
 
-                if(!empty($aParams['days']))
-                    $sWhereClause = $this->prepareAsString('AND `date` >= UNIX_TIMESTAMP(DATE_SUB(NOW(), INTERVAL ? DAY))', (int)$aParams['days']);
+                if(isset($aParams['context_id']) && $aParams['context_id'] !== false) {
+                    $aMethod['params'][3]['context_id'] = $aParams['context_id'];
+
+                    $sWhereClause .= ' AND `context_id` = :context_id';
+                }
+
+                if(!empty($aParams['days'])) {
+                    $aMethod['params'][3]['days'] = (int)$aParams['days'];
+
+                    $sWhereClause .= ' AND `date` >= UNIX_TIMESTAMP(DATE_SUB(NOW(), INTERVAL :days DAY))';
+                }
 
                 $sGroupClause = '`owner_id`';
                 $sOrderClause = '`points` DESC';
@@ -106,6 +122,12 @@ class BxReputationDb extends BxBaseModNotificationsDb
 
                     $sSelectClause .= ", `trpl`.`date` AS `date_assign`";
                     $sJoinClause = " INNER JOIN `" . $CNF['TABLE_PROFILES_LEVELS'] . "` AS `trpl` ON `trl`.`id`=`trpl`.`level_id` AND `trpl`.`profile_id`=:profile_id";
+
+                    if(isset($aParams['context_id']) && $aParams['context_id'] !== false) {
+                        $aMethod['params'][1]['context_id'] = $aParams['context_id'];
+
+                        $sJoinClause .= "  AND `trpl`.`context_id`=:context_id";
+                    }
                     break;
 
                 case 'points':
@@ -115,15 +137,6 @@ class BxReputationDb extends BxBaseModNotificationsDb
 
                     $sWhereClause = "AND `trl`.`points_in` <= :points AND IF(`trl`.`points_out` <> 0, `trl`.`points_out` > :points, 1)";
                     break;
-
-                case 'id':
-                    $aMethod['name'] = 'getRow';
-                    $aMethod['params'][1] = [
-                        'id' => $aParams['id']
-                    ];
-
-                    $sWhereClause = "AND `trl`.`id` = :id";
-                    break;
                 
                 case 'all':
                     if(isset($aParams['active'])) {
@@ -149,21 +162,22 @@ class BxReputationDb extends BxBaseModNotificationsDb
         return call_user_func_array([$this, $aMethod['name']], $aMethod['params']);
     }
 
-    public function insertProfile($iId, $iPoints)
+    public function insertProfile($iProfileId, $iContextId, $iPoints)
     {
         $CNF = &$this->_oConfig->CNF;
 
-        return $this->query("INSERT INTO `" . $CNF['TABLE_PROFILES'] . "` (`id`, `points`) VALUES (:id, :points) ON DUPLICATE KEY UPDATE `points`=`points`+:points", [
-            'id' => $iId,
+        return $this->query("INSERT INTO `" . $CNF['TABLE_PROFILES'] . "` (`profile_id`, `context_id`, `points`) VALUES (:profile_id, :context_id, :points) ON DUPLICATE KEY UPDATE `points`=`points`+:points", [
+            'profile_id' => $iProfileId,
+            'context_id' => $iContextId,
             'points' => $iPoints
         ]);
     }
 
-    public function deleteProfile($iId)
+    public function deleteProfile($iProfileId)
     {
         $CNF = &$this->_oConfig->CNF;
 
-        return $this->query("DELETE FROM `" . $CNF['TABLE_PROFILES'] . "` WHERE `id`=:id", ['id' => $iId]);
+        return $this->query("DELETE FROM `" . $CNF['TABLE_PROFILES'] . "` WHERE `profile_id`=:profile_id", ['profile_id' => $iProfileId]);
     }
     
     public function getProfiles($aParams = [])
@@ -175,21 +189,28 @@ class BxReputationDb extends BxBaseModNotificationsDb
         $sJoinClause = $sWhereClause = $sOrderClause = $sLimitClause = '';
         
         switch($aParams['sample']) {
-            case 'id':
+            case 'profile_id':
                 $aMethod['name'] = 'getRow';
                 $aMethod['params'][1] = [
-                    'id' => $aParams['id']
+                    'profile_id' => $aParams['profile_id'],
+                    'context_id' => isset($aParams['context_id']) ? $aParams['context_id'] : 0 
                 ];
 
-                $sWhereClause = "AND `trp`.`id` = :id";
+                $sWhereClause = "AND `trp`.`profile_id` = :profile_id AND `trp`.`context_id` = :context_id";
                 break;
 
             case 'stats':
                 $aMethod['name'] = 'getPairs';
-                $aMethod['params'][1] = 'id';
+                $aMethod['params'][1] = 'profile_id';
                 $aMethod['params'][2] = 'points';
                 $aMethod['params'][3] = [];
 
+                if(isset($aParams['context_id']) && $aParams['context_id'] !== false) {
+                    $aMethod['params'][3]['context_id'] = $aParams['context_id'];
+
+                    $sWhereClause .= ' AND `context_id` = :context_id';
+                }
+
                 $sOrderClause = '`trp`.`points` DESC';
                 $sLimitClause = '0, ' . (int)$aParams['limit'];
                 break;
@@ -225,11 +246,12 @@ class BxReputationDb extends BxBaseModNotificationsDb
         return call_user_func_array([$this, $aMethod['name']], $aMethod['params']);
     }
 
-    public function getProfilePoints($iProfileId)
+    public function getProfilePoints($iProfileId, $iContextId = 0)
     {
         $aProfile = $this->getProfiles([
-            'sample' => 'id', 
-            'id' => $iProfileId
+            'sample' => 'profile_id', 
+            'profile_id' => $iProfileId,
+            'context_id' => $iContextId
         ]);
 
         return $aProfile && isset($aProfile['points']) ? (int)$aProfile['points'] : 0;
@@ -259,6 +281,12 @@ class BxReputationDb extends BxBaseModNotificationsDb
                 ];
 
                 $sWhereClause = "`profile_id`=:profile_id";
+                
+                if(isset($aParams['context_id']) && $aParams['context_id'] !== false) {
+                    $aBindings['context_id'] = $aParams['context_id'];
+
+                    $sWhereClause .= " AND `context_id` = :context_id";
+                }
                 break;
         }
 
@@ -268,15 +296,16 @@ class BxReputationDb extends BxBaseModNotificationsDb
         return $this->query("DELETE FROM `" . $CNF['TABLE_PROFILES_LEVELS'] . "` WHERE " . $sWhereClause, $aBindings);
     }
 
-    public function deleteProfilesLevelsByPoints($iProfileId, $iPoints)
+    public function deleteProfilesLevelsByPoints($iProfileId, $iContextId, $iPoints)
     {
         $CNF = &$this->_oConfig->CNF;
 
         return $this->query("DELETE FROM `trpl` 
                 USING `" . $CNF['TABLE_PROFILES_LEVELS'] . "` AS `trpl` 
                 LEFT JOIN `" . $CNF['TABLE_LEVELS'] . "` AS `trl` ON `trpl`.`level_id`=`trl`.`id` 
-                WHERE `trpl`.`profile_id` = :profile_id AND (`trl`.`points_in` > :points OR IF(`trl`.`points_out` <> 0, `trl`.`points_out` <= :points, 0))", [
+                WHERE `trpl`.`profile_id` = :profile_id AND `trpl`.`context_id` = :context_id AND (`trl`.`points_in` > :points OR IF(`trl`.`points_out` <> 0, `trl`.`points_out` <= :points, 0))", [
             'profile_id' => $iProfileId,
+            'context_id' => $iContextId,
             'points' => $iPoints
         ]);
     }

+ 63 - 21
modules/boonex/reputation/classes/BxReputationModule.php

@@ -44,9 +44,9 @@ class BxReputationModule extends BxBaseModNotificationsModule
     /**
      * SERVICE METHODS
      */
-    public function serviceAssignPoints($iProfileId, $iPoints)
+    public function serviceAssignPoints($iProfileId, $iPoints, $iContextId = 0)
     {
-        return $this->assignPoints($iProfileId, $iPoints);
+        return $this->assignPoints($iProfileId, $iContextId, $iPoints);
     }
 
     public function serviceGetLevels($iProfileId)
@@ -80,14 +80,14 @@ class BxReputationModule extends BxBaseModNotificationsModule
         ];
     }
 
-    public function serviceGetBlockSummary($iProfileId = 0)
+    public function serviceGetBlockSummary($iProfileId = 0, $iContextId = 0)
     {
         if(!$iProfileId && ($iLoggedId = bx_get_logged_profile_id()))
             $iProfileId = $iLoggedId;
         if(!$iProfileId)
             return false;
 
-        $mixedResult = $this->_oTemplate->getBlockSummary($iProfileId);
+        $mixedResult = $this->_oTemplate->getBlockSummary($iProfileId, $iContextId);
 
         return !$this->_bIsApi ? $mixedResult : [
             bx_api_get_block('reputation_summary', array_merge($mixedResult, [
@@ -97,7 +97,7 @@ class BxReputationModule extends BxBaseModNotificationsModule
         ];
     }
 
-    public function serviceGetBlockHistory($iProfileId = 0, $iStart = 0, $iLimit = 0)
+    public function serviceGetBlockHistory($iProfileId = 0, $iContextId = 0, $iStart = 0, $iLimit = 0)
     {
         if(!$iProfileId && ($iLoggedId = bx_get_logged_profile_id()))
             $iProfileId = $iLoggedId;
@@ -109,23 +109,58 @@ class BxReputationModule extends BxBaseModNotificationsModule
         if(($iGetPerPage = bx_get('per_page')) !== false)
             $iLimit = (int)$iGetPerPage;
 
-        return $this->_oTemplate->getBlockHistory($iProfileId, $iStart, $iLimit);
+        return $this->_oTemplate->getBlockHistory($iProfileId, $iContextId, $iStart, $iLimit);
     }
 
-    public function serviceGetBlockLeaderboard($iDays = 0)
+    public function serviceGetBlockLeaderboard($iContextId = 0, $iDays = 0)
     {
-        return $this->_oTemplate->getBlockLeaderboard($iDays);
+        return $this->_oTemplate->getBlockLeaderboard($iContextId, $iDays);
+    }
+
+    public function serviceGetBlockWidget($iProfileId = 0, $iContextId = 0)
+    {
+        if(!$iProfileId && ($iLoggedId = bx_get_logged_profile_id()))
+            $iProfileId = $iLoggedId;
+        if(!$iProfileId)
+            return false;
+
+        if(!$this->_bIsApi)
+            return false;
+
+        $sModule = $this->getName();
+        $sLangKey = '_bx_reputation_page_block_title_';
+
+        $sParamProfile = '&params[]=' . $iProfileId;
+        $sParamContext = ($iContextId = (int)$iContextId) ? '&params[]=' . $iContextId : '';
+
+        return [
+            bx_api_get_block('reputation_widget', [
+                'tabs'=> [
+                    ['url' => '/api.php?r=' . $sModule . '/get_block_summary' . $sParamProfile . $sParamContext, 'title' => _t($sLangKey . 'summary')],
+                    ['url' => '/api.php?r=' . $sModule . '/get_block_leaderboard' . $sParamContext . '&params[]=7', 'title' => _t($sLangKey . 'leaderboard_week')],
+                    ['url' => '/api.php?r=' . $sModule . '/get_block_leaderboard' . $sParamContext . '&params[]=30', 'title' => _t($sLangKey . 'leaderboard_month')],
+                    ['url' => '/api.php?r=' . $sModule . '/get_block_leaderboard' . $sParamContext . '', 'title' => _t($sLangKey . 'leaderboard_all_time')]
+                ]
+            ])
+        ];
     }
 
     /**
      * COMMON METHODS
      */
-    public function assignPoints($iProfileId, $iPoints)
+    public function assignPoints($iProfileId, $iContextId, $iPoints)
     {
-        if(!$this->_oDb->insertProfile($iProfileId, $iPoints))
+        if(!$this->_oDb->insertProfile($iProfileId, $iContextId, $iPoints))
             return false; 
-            
-        $iProfilePoints = $this->_oDb->getProfilePoints($iProfileId);
+
+        $this->assignLevels($iProfileId, $iContextId);
+
+        return true; 
+    }
+    
+    public function assignLevels($iProfileId, $iContextId)
+    {
+        $iProfilePoints = $this->_oDb->getProfilePoints($iProfileId, $iContextId);
 
         $aLevels = $this->_oDb->getLevels([
             'sample' => 'points', 
@@ -134,27 +169,34 @@ class BxReputationModule extends BxBaseModNotificationsModule
 
         $bMultilevel = $this->_oConfig->isMultilevel();
         if($bMultilevel)
-            $this->_oDb->deleteProfilesLevelsByPoints($iProfileId, $iProfilePoints);
+            $this->_oDb->deleteProfilesLevelsByPoints($iProfileId, $iContextId, $iProfilePoints);
 
         foreach($aLevels as $aLevel) {
             $iLevelId = (int)$aLevel['id'];
-            if($this->hasLevel($iProfileId, $iLevelId))
+            if($this->hasLevel($iProfileId, $iContextId, $iLevelId))
                 continue;
 
             if(!$bMultilevel)
-                $this->_oDb->deleteProfilesLevels(['sample' => 'profile_id', 'profile_id' => $iProfileId]);
-
-            $this->_oDb->insertProfilesLevels(['profile_id' => $iProfileId, 'level_id' => $iLevelId]);
+                $this->_oDb->deleteProfilesLevels([
+                    'sample' => 'profile_id', 
+                    'profile_id' => $iProfileId, 
+                    'context_id' => $iContextId
+                ]);
+
+            $this->_oDb->insertProfilesLevels([
+                'profile_id' => $iProfileId, 
+                'context_id' => $iContextId,
+                'level_id' => $iLevelId
+            ]);
         }
-
-        return true; 
     }
 
-    public function hasLevel($iProfileId, $iLevelId)
+    public function hasLevel($iProfileId, $iContextId, $iLevelId)
     {
         $aProfileLevels = $this->_oDb->getLevels([
             'sample' => 'profile_id', 
-            'profile_id' => $iProfileId
+            'profile_id' => $iProfileId,
+            'context_id' => $iContextId
         ]);
 
         foreach($aProfileLevels as $aProfileLevel)

+ 2 - 2
modules/boonex/reputation/classes/BxReputationStudioPage.php

@@ -44,9 +44,9 @@ class BxReputationStudioPage extends BxBaseModNotificationsStudioPage
                     $aProfiles = $this->_oModule->_oDb->getProfiles(['sample' => 'points_range', 'points_in' => $aLevel['points_in'], 'points_out' => $aLevel['points_out']]);
                     if(empty($aProfiles) || !is_array($aProfiles))
                         continue;
-                    
+
                     foreach($aProfiles as $aProfile)
-                        if($this->_oModule->_oDb->insertProfilesLevels(['profile_id' => $aProfile['id'], 'level_id' => $aLevel['id']]))
+                        if($this->_oModule->_oDb->insertProfilesLevels(['profile_id' => $aProfile['profile_id'], 'level_id' => $aLevel['id']]))
                             $iUpdated++;
                 }
 

+ 25 - 10
modules/boonex/reputation/classes/BxReputationTemplate.php

@@ -113,7 +113,7 @@ class BxReputationTemplate extends BxBaseModNotificationsTemplate
         ]);
     }
 
-    public function getBlockSummary($iProfileId)
+    public function getBlockSummary($iProfileId, $iContextId = 0)
     {
         $CNF = &$this->_oConfig->CNF;
 
@@ -121,11 +121,16 @@ class BxReputationTemplate extends BxBaseModNotificationsTemplate
         if(!$oProfile)
             return false;
 
-        $aProfileInfo = $this->_oDb->getProfiles(['sample' => 'id', 'id' => $iProfileId]);
+        $aProfileInfo = $this->_oDb->getProfiles([
+            'sample' => 'profile_id', 
+            'profile_id' => $iProfileId, 
+            'context_id' => $iContextId
+        ]);
         $bProfileInfo = !empty($aProfileInfo) && is_array($aProfileInfo);
         $aProfileLevels = $this->_oDb->getLevels([
             'sample' => 'profile_id', 
-            'profile_id' => $iProfileId
+            'profile_id' => $iProfileId,
+            'context_id' => $iContextId
         ]);
 
         $oFunctions = BxTemplFunctions::getInstance();
@@ -182,7 +187,7 @@ class BxReputationTemplate extends BxBaseModNotificationsTemplate
         ]);
     }
 
-    public function getBlockHistory($iProfileId, $iStart = 0, $iLimit = 0)
+    public function getBlockHistory($iProfileId, $iContextId = 0, $iStart = 0, $iLimit = 0)
     {
         $CNF = &$this->_oConfig->CNF;
         $oModule = $this->getModule();
@@ -193,6 +198,7 @@ class BxReputationTemplate extends BxBaseModNotificationsTemplate
         $aItems = $this->_oDb->getEvents([
             'sample' => 'owner_id', 
             'owner_id' => $iProfileId,
+            'context_id' => ($iContextId = (int)$iContextId) ? $iContextId : false,
             'start' => $iStart,
             'limit' => $iLimit + 1
         ]);
@@ -232,19 +238,28 @@ class BxReputationTemplate extends BxBaseModNotificationsTemplate
         ]);
     }
 
-    public function getBlockLeaderboard($iDays = 0, $iLimit = 0)
+    public function getBlockLeaderboard($iContextId = 0, $iDays = 0, $iLimit = 0)
     {
         $CNF = &$this->_oConfig->CNF;
-        
-        if(!$iLimit)
-            $iLimit = (int)getParam($CNF['PARAM_LEADERBOARD_LIMIT']);
 
+        $iContextId = (int)$iContextId;
+        $iDays = (int)$iDays;
+        $iLimit = $iLimit ? (int)$iLimit : (int)getParam($CNF['PARAM_LEADERBOARD_LIMIT']);
         $bGrowth = $iDays > 0;
 
         if($bGrowth) 
-            $aItems = $this->_oDb->getEvents(['sample' => 'stats', 'days' => $iDays, 'limit' => $iLimit]);
+            $aItems = $this->_oDb->getEvents([
+                'sample' => 'stats', 
+                'context_id' => $iContextId ?: false,
+                'days' => $iDays, 
+                'limit' => $iLimit
+            ]);
         else
-            $aItems = $this->_oDb->getProfiles(['sample' => 'stats', 'limit' => $iLimit]);
+            $aItems = $this->_oDb->getProfiles([
+                'sample' => 'stats',
+                'context_id' => $iContextId,
+                'limit' => $iLimit
+            ]);
 
         $aTmplVarsProfiles = [];
         foreach($aItems as $iProfileId => $iPoints)

+ 2 - 2
modules/boonex/reputation/install/sql/enable.sql

@@ -23,8 +23,8 @@ INSERT INTO `sys_objects_page`(`object`, `title_system`, `title`, `module`, `lay
 ('bx_reputation_leaderboard', '_bx_reputation_page_title_sys_leaderboard', '_bx_reputation_page_title_leaderboard', @sName, 8, 2147483647, 1, 'leaderboard', 'page.php?i=leaderboard', '', '', '', 0, 1, 0, '', '');
 
 INSERT INTO `sys_pages_blocks` (`object`, `cell_id`, `module`, `title`, `designbox_id`, `visible_for_levels`, `type`, `content`, `deletable`, `copyable`, `order`) VALUES
-('bx_reputation_leaderboard', 2, @sName, '_bx_reputation_page_block_title_leaderboard_week', 11, 2147483647, 'service', 'a:3:{s:6:"module";s:13:"bx_reputation";s:6:"method";s:21:"get_block_leaderboard";s:6:"params";a:1:{i:0;i:7;}}', 0, 1, 1),
-('bx_reputation_leaderboard', 3, @sName, '_bx_reputation_page_block_title_leaderboard_month', 11, 2147483647, 'service', 'a:3:{s:6:"module";s:13:"bx_reputation";s:6:"method";s:21:"get_block_leaderboard";s:6:"params";a:1:{i:0;i:30;}}', 0, 1, 1),
+('bx_reputation_leaderboard', 2, @sName, '_bx_reputation_page_block_title_leaderboard_week', 11, 2147483647, 'service', 'a:3:{s:6:"module";s:13:"bx_reputation";s:6:"method";s:21:"get_block_leaderboard";s:6:"params";a:2:{i:0;i:0;i:1;i:7;}}', 0, 1, 1),
+('bx_reputation_leaderboard', 3, @sName, '_bx_reputation_page_block_title_leaderboard_month', 11, 2147483647, 'service', 'a:3:{s:6:"module";s:13:"bx_reputation";s:6:"method";s:21:"get_block_leaderboard";s:6:"params";a:2:{i:0;i:0;i:1;i:30;}}', 0, 1, 1),
 ('bx_reputation_leaderboard', 4, @sName, '_bx_reputation_page_block_title_leaderboard_all_time', 11, 2147483647, 'service', 'a:2:{s:6:"module";s:13:"bx_reputation";s:6:"method";s:21:"get_block_leaderboard";}', 0, 1, 1);
 
 -- PAGE: history

+ 7 - 2
modules/boonex/reputation/install/sql/install.sql

@@ -29,6 +29,7 @@ INSERT INTO `bx_reputation_handlers`(`group`, `type`, `alert_unit`, `alert_actio
 CREATE TABLE IF NOT EXISTS `bx_reputation_events` (
   `id` int(11) NOT NULL auto_increment,
   `owner_id` int(11) NOT NULL default '0',
+  `context_id` int(11) NOT NULL default '0',
   `type` varchar(64) NOT NULL default '',
   `action` varchar(64) NOT NULL default '',
   `object_id` int(11) NOT NULL default '0',
@@ -68,15 +69,19 @@ INSERT INTO `bx_reputation_levels` (`name`, `title`, `icon`, `points_in`, `point
 
 -- TABLE: profiles
 CREATE TABLE IF NOT EXISTS `bx_reputation_profiles` (
-  `id` int(11) NOT NULL DEFAULT '0',
+  `id` int(11) NOT NULL auto_increment,
+  `profile_id` int(11) NOT NULL DEFAULT '0',
+  `context_id` int(11) NOT NULL default '0',
   `points` int(11) NOT NULL DEFAULT '0',
-  PRIMARY KEY (`id`)
+  PRIMARY KEY (`id`),
+  UNIQUE KEY `profile` (`profile_id`, `context_id`)
 );
 
 -- TABLE: profiles' levels
 CREATE TABLE IF NOT EXISTS `bx_reputation_profiles_levels` (
   `id` int(11) NOT NULL auto_increment,
   `profile_id` int(11) NOT NULL DEFAULT '0',
+  `context_id` int(11) NOT NULL default '0',
   `level_id` int(11) NOT NULL DEFAULT '0',
   `date` int(11) NOT NULL default '0',
   PRIMARY KEY (`id`)