1
0
AntonLV 6 жил өмнө
parent
commit
878c821756

+ 5 - 3
inc/classes/BxDolGridConnections.php

@@ -24,7 +24,7 @@ class BxDolGridConnections extends BxTemplGrid
 
 
         $this->_aQueryAppendExclude[] = 'join_connections';
         $this->_aQueryAppendExclude[] = 'join_connections';
 
 
-        if(($iProfileId = bx_get('profile_id')) !== false)
+        if(($iProfileId = bx_process_input(bx_get('profile_id'), BX_DATA_INT)) !== false)
             $this->setProfile($iProfileId);
             $this->setProfile($iProfileId);
     }
     }
 
 
@@ -33,11 +33,11 @@ class BxDolGridConnections extends BxTemplGrid
         if(!$this->_oProfile)
         if(!$this->_oProfile)
             return false;
             return false;
 
 
-        if ($this->_oProfile->id() == bx_get_logged_profile_id())
+        if($this->_oProfile->id() == bx_get_logged_profile_id())
             $this->_bOwner = true;
             $this->_bOwner = true;
 
 
         $this->_oConnection = BxDolConnection::getObjectInstance($this->_sObjectConnections);
         $this->_oConnection = BxDolConnection::getObjectInstance($this->_sObjectConnections);
-        if (!$this->_oConnection)
+        if(!$this->_oConnection)
             return false;
             return false;
 
 
         $aSQLParts = $this->_oConnection->getConnectedInitiatorsAsSQLParts('p', 'id', $this->_oProfile->id(), $this->_bOwner ? false : true);
         $aSQLParts = $this->_oConnection->getConnectedInitiatorsAsSQLParts('p', 'id', $this->_oProfile->id(), $this->_bOwner ? false : true);
@@ -46,6 +46,8 @@ class BxDolGridConnections extends BxTemplGrid
             'profile_id' => $this->_oProfile->id(),
             'profile_id' => $this->_oProfile->id(),
             'join_connections' => $aSQLParts['join']
             'join_connections' => $aSQLParts['join']
         ));
         ));
+
+        return true;
     }
     }
 
 
     public function setProfile($iProfileId)
     public function setProfile($iProfileId)

+ 31 - 0
modules/base/groups/classes/BxBaseModGroupsConfig.php

@@ -11,6 +11,9 @@
 
 
 class BxBaseModGroupsConfig extends BxBaseModProfileConfig
 class BxBaseModGroupsConfig extends BxBaseModProfileConfig
 {
 {
+    protected $_bRoles;
+    protected $_aRoles;
+
     function __construct($aModule)
     function __construct($aModule)
     {
     {
         parent::__construct($aModule);
         parent::__construct($aModule);
@@ -23,6 +26,34 @@ class BxBaseModGroupsConfig extends BxBaseModProfileConfig
             'profile-actions-more' => 'checkAllowedViewMoreMenu',
             'profile-actions-more' => 'checkAllowedViewMoreMenu',
             'convos-compose' => 'checkAllowedCompose',
             'convos-compose' => 'checkAllowedCompose',
         );
         );
+
+        $this->_bRoles = false;
+        $this->_aRoles = false;
+    }
+
+    public function isRoles()
+    {
+        if($this->_aRoles === false)
+            $this->_initRoles();
+
+        return $this->_bRoles;
+    }
+
+    public function getRoles()
+    {
+        if($this->_aRoles === false)
+            $this->_initRoles();
+
+        return $this->_aRoles;
+    }
+    
+    protected function _initRoles()
+    {
+        if(empty($this->CNF['OBJECT_PRE_LIST_ROLES'])) 
+            return;
+
+        $this->_aRoles = BxDolFormQuery::getDataItems($this->CNF['OBJECT_PRE_LIST_ROLES']);
+        $this->_bRoles = !empty($this->_aRoles) && is_array($this->_aRoles);
     }
     }
 }
 }
 
 

+ 46 - 3
modules/base/groups/classes/BxBaseModGroupsDb.php

@@ -96,14 +96,57 @@ class BxBaseModGroupsDb extends BxBaseModProfileDb
         return $this->getOne($sQuery) ? true : false;
         return $this->getOne($sQuery) ? true : false;
     }
     }
 
 
+    public function getAdmin ($iGroupProfileId, $iProfileId, $bRoleOnly = false)
+    {
+        $sMethod = 'getRow';
+        $sSelectClause = '*';
+
+        if($bRoleOnly) {
+            $sMethod = 'getOne';
+            $sSelectClause = '`role`';
+        }
+
+        return $this->$sMethod("SELECT " . $sSelectClause . " FROM `" . $this->_oConfig->CNF['TABLE_ADMINS'] . "` WHERE `group_profile_id` = :group_profile_id AND `fan_id` = :fan_id LIMIT 1", array(
+            'group_profile_id' => $iGroupProfileId,
+            'fan_id' => $iProfileId
+        ));
+    }
+
     public function getAdmins ($iGroupProfileId, $iStart = 0, $iLimit = 0)
     public function getAdmins ($iGroupProfileId, $iStart = 0, $iLimit = 0)
     {
     {
-		$sQuery = $this->prepare("SELECT `fan_id` FROM `" . $this->_oConfig->CNF['TABLE_ADMINS'] . "` WHERE `group_profile_id` = ?", $iGroupProfileId);
-		if ($iLimit > 0)
+        if ($iLimit > 0)
             $sQuery = $this->prepare("SELECT `fan_id` FROM `" . $this->_oConfig->CNF['TABLE_ADMINS'] . "` WHERE `group_profile_id` = ? LIMIT ?, ?", $iGroupProfileId, $iStart, $iLimit);
             $sQuery = $this->prepare("SELECT `fan_id` FROM `" . $this->_oConfig->CNF['TABLE_ADMINS'] . "` WHERE `group_profile_id` = ? LIMIT ?, ?", $iGroupProfileId, $iStart, $iLimit);
+        else
+            $sQuery = $this->prepare("SELECT `fan_id` FROM `" . $this->_oConfig->CNF['TABLE_ADMINS'] . "` WHERE `group_profile_id` = ?", $iGroupProfileId);
+
         return $this->getColumn($sQuery);
         return $this->getColumn($sQuery);
     }
     }
-    
+
+    public function getRole ($iGroupProfileId, $iProfileId)
+    {
+        return (int)$this->getOne("SELECT `role` FROM `" . $this->_oConfig->CNF['TABLE_ADMINS'] . "` WHERE `group_profile_id` = :group_profile_id AND `fan_id` = :fan_id LIMIT 1", array(
+            'group_profile_id' => $iGroupProfileId,
+            'fan_id' => $iProfileId
+        ));
+    }
+
+    public function setRole ($iGroupProfileId, $iProfileId, $iRole)
+    {
+        if($iRole == 0)
+            $mixedResult = $this->query("DELETE FROM `" . $this->_oConfig->CNF['TABLE_ADMINS'] . "` WHERE `group_profile_id` = :group_profile_id AND `fan_id` = :fan_id", array(
+                'group_profile_id' => $iGroupProfileId,
+                'fan_id' => $iProfileId,
+            ));
+        else
+            $mixedResult = $this->query("REPLACE INTO `" . $this->_oConfig->CNF['TABLE_ADMINS'] . "` SET `group_profile_id` = :group_profile_id, `fan_id` = :fan_id, `role` = :role", array(
+                'group_profile_id' => $iGroupProfileId,
+                'fan_id' => $iProfileId,
+                'role' => $iRole
+            ));
+
+        return !$mixedResult ? false : true;
+    }
+
     public function insertInvite($sKey, $sGroupProfileId, $iAuthorProfileId, $iInvitedProfileId)
     public function insertInvite($sKey, $sGroupProfileId, $iAuthorProfileId, $iInvitedProfileId)
     {
     {
         $aBindings = array(
         $aBindings = array(

+ 128 - 16
modules/base/groups/classes/BxBaseModGroupsGridConnections.php

@@ -11,9 +11,13 @@
 
 
 class BxBaseModGroupsGridConnections extends BxDolGridConnections
 class BxBaseModGroupsGridConnections extends BxDolGridConnections
 {
 {
+    protected $_oModule;
     protected $_sContentModule;
     protected $_sContentModule;
+
+    protected $_bRoles;
+    protected $_aRoles;
+
     protected $_iGroupProfileId;
     protected $_iGroupProfileId;
-    protected $_oModule;
     protected $_aContentInfo = array();
     protected $_aContentInfo = array();
 
 
     public function __construct ($aOptions, $oTemplate = false)
     public function __construct ($aOptions, $oTemplate = false)
@@ -22,32 +26,129 @@ class BxBaseModGroupsGridConnections extends BxDolGridConnections
         $this->_sObjectConnections = $this->_oModule->_oConfig->CNF['OBJECT_CONNECTIONS'];
         $this->_sObjectConnections = $this->_oModule->_oConfig->CNF['OBJECT_CONNECTIONS'];
 
 
         parent::__construct ($aOptions, $oTemplate);
         parent::__construct ($aOptions, $oTemplate);
-
-        $iProfileId = bx_process_input(bx_get('profile_id'), BX_DATA_INT);
-        if (!$iProfileId)
+        if(!$this->_bInit) 
             return;
             return;
 
 
-        $oProfile = BxDolProfile::getInstance($iProfileId);
-        if (!$oProfile)
-            return;
+        $this->_bRoles = $this->_oModule->_oConfig->isRoles();
+        $this->_aRoles = $this->_oModule->_oConfig->getRoles();
 
 
-        $aProfileInfo = $oProfile->getInfo();
-        $this->_iGroupProfileId = $oProfile->id();
+        $this->_iGroupProfileId = $this->_oProfile->id();
 
 
-        $this->_aContentInfo = BxDolService::call($aProfileInfo['type'], 'get_content_info_by_id', array($aProfileInfo['content_id']));
-        if (CHECK_ACTION_RESULT_ALLOWED === $this->_oModule->checkAllowedEdit($this->_aContentInfo) || $oProfile->id() == bx_get_logged_profile_id())
+        $this->_aContentInfo = $this->_oModule->_oDb->getContentInfoById($this->_oProfile->getContentId());
+        if($this->_oModule->checkAllowedEdit($this->_aContentInfo) === CHECK_ACTION_RESULT_ALLOWED || $this->_iGroupProfileId == bx_get_logged_profile_id())
             $this->_bOwner = true;
             $this->_bOwner = true;
 
 
         $aSQLParts = $this->_oConnection->getConnectedInitiatorsAsSQLParts('p', 'id', $this->_iGroupProfileId, $this->_bOwner ? false : true);
         $aSQLParts = $this->_oConnection->getConnectedInitiatorsAsSQLParts('p', 'id', $this->_iGroupProfileId, $this->_bOwner ? false : true);
         $this->addMarkers(array(
         $this->addMarkers(array(
-            'profile_id' => $oProfile->id(),
+            'profile_id' => $this->_iGroupProfileId,
             'join_connections' => $aSQLParts['join'],
             'join_connections' => $aSQLParts['join'],
             'content_module' => $this->_sContentModule,
             'content_module' => $this->_sContentModule,
         ));
         ));
     }
     }
 
 
+    public function getCode ($isDisplayHeader = true)
+    {
+        $sResult = parent::getCode();
+        if(!$sResult)
+            return $sResult;
+
+        if($this->_bRoles)
+            $sResult .= $this->_oModule->_oTemplate->getJsCode('main', array(
+                'sObjNameGrid' => $this->_sObject,
+            ));
+
+        return $sResult;
+    }
+
+    public function performActionSetRole()
+    {
+        if(!$this->_bRoles)
+            return echoJson(array());
+
+        if($this->_oModule->checkAllowedManageAdmins($this->_iGroupProfileId) !== CHECK_ACTION_RESULT_ALLOWED)
+            return echoJson(array('msg' => _t('_sys_txt_access_denied')));
+
+        list($iId, $iViewedId) = $this->_prepareIds();
+        if(!$iId)
+            return echoJson(array('msg' => _t('_sys_txt_error_occured')));
+
+        $sJsObject = $this->_oModule->_oConfig->getJsObject('main');
+        $sHtmlIdPrefix = str_replace('_', '-', $this->_sContentModule) . '-set-role-';
+
+        $aMenuItems = array();
+        foreach($this->_aRoles as $iRole => $sRole)
+            $aMenuItems[] = array(
+                'id' => $sHtmlIdPrefix . $iRole, 
+                'name' => $sHtmlIdPrefix . $iRole, 
+                'class' => '', 
+                'link' => 'javascript:void(0)', 
+                'onclick' => $sJsObject . '.onClickSetRole(' . $iId . ', ' . $iRole . ')',
+                'target' => '_self', 
+                'title' => $sRole, 
+                'active' => 1
+            );
+
+        if(empty($aMenuItems))
+            return echoJson(array('msg' => _t('_sys_txt_error_occured')));
+
+        $oMenu = new BxTemplMenu(array('template' => 'menu_vertical.html', 'menu_id'=> $sHtmlIdPrefix . 'menu', 'menu_items' => $aMenuItems));
+
+        $iRole = $this->_oModule->_oDb->getRole($this->_iGroupProfileId, $iId);
+        if(!empty($iRole))
+            $oMenu->setSelected('', $sHtmlIdPrefix . $iRole);
+
+        return echoJson(array('popup' => BxTemplFunctions::getInstance()->transBox($sHtmlIdPrefix . 'popup', $oMenu->getCode())));
+    }
+
+    public function performActionSetRoleSubmit()
+    {
+        if(!$this->_bRoles)
+            return echoJson(array());
+
+        if($this->_oModule->checkAllowedManageAdmins($this->_iGroupProfileId) !== CHECK_ACTION_RESULT_ALLOWED)
+            return echoJson(array('msg' => _t('_sys_txt_access_denied')));
+
+        list($iId, $iViewedId) = $this->_prepareIds();
+
+        if(!$iId || bx_get('role') === false)
+            return echoJson(array('msg' => _t('_sys_txt_error_occured')));
+
+        $aResult = $this->_oModule->setRole($this->_iGroupProfileId, $iId, (int)bx_get('role'));
+        if($aResult['code'] != 0)
+            return echoJson(array('msg' => $aResult['msg']));
+
+        echoJson(array('grid' => $this->getCode(false), 'blink' => $iId));
+    }
+
+    protected function _getCellRole($mixedValue, $sKey, $aField, $aRow)
+    {
+        $mixedValue = '';
+
+        $iRole = $this->_oModule->_oDb->getRole($this->_iGroupProfileId, $aRow[$this->_aOptions['field_id']]);
+        if(!empty($iRole) && !empty($this->_aRoles[$iRole])) 
+            $mixedValue = $this->_aRoles[$iRole];
+
+        return parent::_getCellDefault($mixedValue, $sKey, $aField, $aRow);
+    }
+
+    protected function _getActionSetRole ($sType, $sKey, $a, $isSmall = false, $isDisabled = false, $aRow = array())
+    {
+        if ($this->_oModule->checkAllowedManageAdmins($this->_iGroupProfileId) !== CHECK_ACTION_RESULT_ALLOWED)
+            return '';
+
+        return parent::_getActionDefault ($sType, $sKey, $a, $isSmall, $isDisabled, $aRow);
+    }
+
+    protected function _getActionSetRoleSubmit ($sType, $sKey, $a, $isSmall = false, $isDisabled = false, $aRow = array())
+    {
+        return '';
+    }
+
     protected function _getActionAccept ($sType, $sKey, $a, $isSmall = false, $isDisabled = false, $aRow = array())
     protected function _getActionAccept ($sType, $sKey, $a, $isSmall = false, $isDisabled = false, $aRow = array())
     {
     {
+        if ($this->_oModule->checkAllowedManageFans($this->_iGroupProfileId) !== CHECK_ACTION_RESULT_ALLOWED)
+            return '';
+
         if (isset($aRow[$this->_aOptions['field_id']]))
         if (isset($aRow[$this->_aOptions['field_id']]))
             $a['attr']['bx_grid_action_data'] = $aRow[$this->_aOptions['field_id']] . ':' . $this->_iGroupProfileId;
             $a['attr']['bx_grid_action_data'] = $aRow[$this->_aOptions['field_id']] . ':' . $this->_iGroupProfileId;
 
 
@@ -56,6 +157,9 @@ class BxBaseModGroupsGridConnections extends BxDolGridConnections
 
 
     protected function _getActionDelete ($sType, $sKey, $a, $isSmall = false, $isDisabled = false, $aRow = array())
     protected function _getActionDelete ($sType, $sKey, $a, $isSmall = false, $isDisabled = false, $aRow = array())
     {
     {
+        if ($this->_oModule->checkAllowedManageFans($this->_iGroupProfileId) !== CHECK_ACTION_RESULT_ALLOWED)
+            return '';
+
         if (isset($aRow[$this->_aOptions['field_id']]))
         if (isset($aRow[$this->_aOptions['field_id']]))
             $a['attr']['bx_grid_action_data'] = $aRow[$this->_aOptions['field_id']] . ':' . $this->_iGroupProfileId;
             $a['attr']['bx_grid_action_data'] = $aRow[$this->_aOptions['field_id']] . ':' . $this->_iGroupProfileId;
 
 
@@ -67,7 +171,7 @@ class BxBaseModGroupsGridConnections extends BxDolGridConnections
         if ($this->_oModule->_oDb->isAdmin($this->_iGroupProfileId, $aRow[$this->_aOptions['field_id']]))
         if ($this->_oModule->_oDb->isAdmin($this->_iGroupProfileId, $aRow[$this->_aOptions['field_id']]))
             return '';
             return '';
 
 
-        return $this->_getAction_Admins ($sType, $sKey, $a, $isSmall, $isDisabled, $aRow);
+        return $this->_getActionManageAdmins ($sType, $sKey, $a, $isSmall, $isDisabled, $aRow);
     }
     }
 
 
     protected function _getActionFromAdmins ($sType, $sKey, $a, $isSmall = false, $isDisabled = false, $aRow = array())
     protected function _getActionFromAdmins ($sType, $sKey, $a, $isSmall = false, $isDisabled = false, $aRow = array())
@@ -75,15 +179,15 @@ class BxBaseModGroupsGridConnections extends BxDolGridConnections
         if (!$this->_oModule->_oDb->isAdmin($this->_iGroupProfileId, $aRow[$this->_aOptions['field_id']]))
         if (!$this->_oModule->_oDb->isAdmin($this->_iGroupProfileId, $aRow[$this->_aOptions['field_id']]))
             return '';
             return '';
 
 
-        return $this->_getAction_Admins ($sType, $sKey, $a, $isSmall, $isDisabled, $aRow);
+        return $this->_getActionManageAdmins ($sType, $sKey, $a, $isSmall, $isDisabled, $aRow);
     }
     }
 
 
-    protected function _getAction_Admins ($sType, $sKey, $a, $isSmall = false, $isDisabled = false, $aRow = array())
+    protected function _getActionManageAdmins ($sType, $sKey, $a, $isSmall = false, $isDisabled = false, $aRow = array())
     {
     {
         if (!$this->_oConnection->isConnected($aRow[$this->_aOptions['field_id']], $this->_iGroupProfileId, true))
         if (!$this->_oConnection->isConnected($aRow[$this->_aOptions['field_id']], $this->_iGroupProfileId, true))
             return '';
             return '';
 
 
-        if (CHECK_ACTION_RESULT_ALLOWED !== $this->_oModule->checkAllowedManageAdmins($this->_iGroupProfileId))
+        if ($this->_oModule->checkAllowedManageAdmins($this->_iGroupProfileId) !== CHECK_ACTION_RESULT_ALLOWED)
             return '';
             return '';
 
 
         if (isset($aRow[$this->_aOptions['field_id']]))
         if (isset($aRow[$this->_aOptions['field_id']]))
@@ -175,6 +279,14 @@ class BxBaseModGroupsGridConnections extends BxDolGridConnections
         else
         else
             return array($iId2, $iId1);
             return array($iId2, $iId1);
     }
     }
+
+    protected function _addJsCss()
+    {
+        parent::_addJsCss();
+
+        if($this->_bRoles)
+            $this->_oModule->_oTemplate->addJs('main.js');
+    }
 }
 }
 
 
 /** @} */
 /** @} */

+ 156 - 21
modules/base/groups/classes/BxBaseModGroupsModule.php

@@ -9,6 +9,16 @@
  * @{
  * @{
  */
  */
 
 
+define('BX_BASE_MOD_GROUPS_ROLE_ADMINISTRATOR', 1);
+define('BX_BASE_MOD_GROUPS_ROLE_MODERATOR', 2);
+
+define('BX_BASE_MOD_GROUPS_ACTION_EDIT', 'edit');
+define('BX_BASE_MOD_GROUPS_ACTION_CHANGE_COVER', 'change_cover');
+define('BX_BASE_MOD_GROUPS_ACTION_INVITE', 'invite');
+define('BX_BASE_MOD_GROUPS_ACTION_MANAGE_FANS', 'manage_fans');
+define('BX_BASE_MOD_GROUPS_ACTION_MANAGE_ROLES', 'manage_roles');
+define('BX_BASE_MOD_GROUPS_ACTION_DELETE', 'delete');
+
 /**
 /**
  * Groups profiles module.
  * Groups profiles module.
  */
  */
@@ -54,7 +64,7 @@ class BxBaseModGroupsModule extends BxBaseModProfileModule
             $this->_oDb->deleteInviteByKey($sKey, $iGroupProfileId);
             $this->_oDb->deleteInviteByKey($sKey, $iGroupProfileId);
         }   
         }   
     }
     }
- 
+
     public function serviceGetSearchResultUnit ($iContentId, $sUnitTemplate = '')
     public function serviceGetSearchResultUnit ($iContentId, $sUnitTemplate = '')
     {
     {
         if(empty($sUnitTemplate))
         if(empty($sUnitTemplate))
@@ -659,48 +669,121 @@ class BxBaseModGroupsModule extends BxBaseModProfileModule
         return $this->_checkAllowedConnect ($aDataEntry, $isPerformAction, $this->_oConfig->CNF['OBJECT_CONNECTIONS'], false, true, false);
         return $this->_checkAllowedConnect ($aDataEntry, $isPerformAction, $this->_oConfig->CNF['OBJECT_CONNECTIONS'], false, true, false);
     }
     }
 
 
-    public function checkAllowedManageAdmins ($mixedDataEntry, $isPerformAction = false)
+    protected function _checkAllowedActionByFan($sAction, $aDataEntry, $iPerformerId = 0)
     {
     {
-        if (is_array($mixedDataEntry)) {
-            $aDataEntry = $mixedDataEntry;
+        $CNF = &$this->_oConfig->CNF;
+
+        $bRoles = $this->_oConfig->isRoles();
+        if(empty($iPerformerId))
+            $iPerformerId = bx_get_logged_profile_id();
+
+        $oGroupProfile = BxDolProfile::getInstanceByContentAndType($aDataEntry[$CNF['FIELD_ID']], $this->getName());
+        $iGroupProfileId = $oGroupProfile->id();
+
+        if(!$bRoles && $this->_oDb->isAdmin($iGroupProfileId, $iPerformerId, $aDataEntry))
+            return CHECK_ACTION_RESULT_ALLOWED;
+
+        if($bRoles && $this->isAllowedActionByRole($sAction, $aDataEntry, $iGroupProfileId, $iPerformerId))
+            return CHECK_ACTION_RESULT_ALLOWED;
+
+        return _t('_sys_txt_access_denied');
+    }
+
+    public function isAllowedActionByRole($sAction, $aDataEntry, $iGroupProfileId, $iPerformerId)
+    {
+        $bResult = false;
+
+        $iRole = $this->_oDb->getRole($iGroupProfileId, $iPerformerId);
+        if(!empty($iRole))
+            switch($sAction) {
+                case BX_BASE_MOD_GROUPS_ACTION_MANAGE_ROLES:
+                    if($iRole == BX_BASE_MOD_GROUPS_ROLE_ADMINISTRATOR)
+                        $bResult = true;
+                    break;
+
+                default:
+                    $bResult = true;
+            }
+
+        // call alert to allow custom checks
+        bx_alert('system', 'check_allowed_action_by_role', 0, 0, array(
+            'module' => $this->getName(), 
+            'action' => $sAction,
+            'content_info' => $aDataEntry, 
+            'profile_id' => $iPerformerId, 
+            'profile_role' => $iRole,
+            'override_result' => &$bResult
+        ));
+
+        return $bResult;
+    }
+
+    public function checkAllowedManageFans($mixedDataEntry, $isPerformAction = false)
+    {
+        $aDataEntry = array();
+        if(!is_array($mixedDataEntry)) {
+            $oGroupProfile = BxDolProfile::getInstance((int)$mixedDataEntry);
+            if($oGroupProfile && $this->getName() == $oGroupProfile->getModule())
+                $aDataEntry = $this->_oDb->getContentInfoById($oGroupProfile->getContentId());
         }
         }
-        else {
+        else
+            $aDataEntry = $mixedDataEntry;
+
+        if($this->_checkAllowedActionByFan(BX_BASE_MOD_GROUPS_ACTION_MANAGE_FANS, $aDataEntry) === CHECK_ACTION_RESULT_ALLOWED)
+            return CHECK_ACTION_RESULT_ALLOWED;
+
+        return parent::checkAllowedEdit($aDataEntry, $isPerformAction);
+    }
+
+    public function checkAllowedManageAdmins($mixedDataEntry, $isPerformAction = false)
+    {
+        $aDataEntry = array();
+        if(!is_array($mixedDataEntry)) {
             $oGroupProfile = BxDolProfile::getInstance((int)$mixedDataEntry);
             $oGroupProfile = BxDolProfile::getInstance((int)$mixedDataEntry);
-            $aDataEntry = $oGroupProfile && $this->getName() == $oGroupProfile->getModule() ? $this->_oDb->getContentInfoById($oGroupProfile->getContentId()) : array();
+            if($oGroupProfile && $this->getName() == $oGroupProfile->getModule())
+                $aDataEntry = $this->_oDb->getContentInfoById($oGroupProfile->getContentId());
         }
         }
+        else
+            $aDataEntry = $mixedDataEntry;
 
 
-        return parent::checkAllowedEdit ($aDataEntry, $isPerformAction);
+        if($this->_checkAllowedActionByFan(BX_BASE_MOD_GROUPS_ACTION_MANAGE_ROLES, $aDataEntry) === CHECK_ACTION_RESULT_ALLOWED)
+            return CHECK_ACTION_RESULT_ALLOWED;
+
+        return parent::checkAllowedEdit($aDataEntry, $isPerformAction);
     }
     }
 
 
-    public function checkAllowedEdit ($aDataEntry, $isPerformAction = false)
+    public function checkAllowedEdit($aDataEntry, $isPerformAction = false)
     {
     {
-        $oGroupProfile = BxDolProfile::getInstanceByContentAndType($aDataEntry[$this->_oConfig->CNF['FIELD_ID']], $this->getName());
-        if ($this->_oDb->isAdmin($oGroupProfile->id(), bx_get_logged_profile_id(), $aDataEntry))
+        if($this->_checkAllowedActionByFan(BX_BASE_MOD_GROUPS_ACTION_EDIT, $aDataEntry) === CHECK_ACTION_RESULT_ALLOWED)
             return CHECK_ACTION_RESULT_ALLOWED;
             return CHECK_ACTION_RESULT_ALLOWED;
-        return parent::checkAllowedEdit ($aDataEntry, $isPerformAction);
+
+        return parent::checkAllowedEdit($aDataEntry, $isPerformAction);
     }
     }
 
 
-    public function checkAllowedInvite ($aDataEntry, $isPerformAction = false)
+    public function checkAllowedInvite($aDataEntry, $isPerformAction = false)
     {
     {
+        if($this->_checkAllowedActionByFan(BX_BASE_MOD_GROUPS_ACTION_INVITE, $aDataEntry) === CHECK_ACTION_RESULT_ALLOWED)
+            return CHECK_ACTION_RESULT_ALLOWED;
+
         return $this->checkAllowedEdit ($aDataEntry, $isPerformAction);
         return $this->checkAllowedEdit ($aDataEntry, $isPerformAction);
     }
     }
     
     
-    public function checkAllowedChangeCover ($aDataEntry, $isPerformAction = false)
+    public function checkAllowedChangeCover($aDataEntry, $isPerformAction = false)
     {
     {
-        $oGroupProfile = BxDolProfile::getInstanceByContentAndType($aDataEntry[$this->_oConfig->CNF['FIELD_ID']], $this->getName());
-        if ($this->_oDb->isAdmin($oGroupProfile->id(), bx_get_logged_profile_id(), $aDataEntry))
+        if($this->_checkAllowedActionByFan(BX_BASE_MOD_GROUPS_ACTION_CHANGE_COVER, $aDataEntry) === CHECK_ACTION_RESULT_ALLOWED)
             return CHECK_ACTION_RESULT_ALLOWED;
             return CHECK_ACTION_RESULT_ALLOWED;
-        return parent::checkAllowedChangeCover ($aDataEntry, $isPerformAction);
+
+        return parent::checkAllowedChangeCover($aDataEntry, $isPerformAction);
     }
     }
 
 
-    public function checkAllowedDelete (&$aDataEntry, $isPerformAction = false)
+    public function checkAllowedDelete(&$aDataEntry, $isPerformAction = false)
     {
     {
-        $oGroupProfile = BxDolProfile::getInstanceByContentAndType($aDataEntry[$this->_oConfig->CNF['FIELD_ID']], $this->getName());
-        if ($oGroupProfile && $this->_oDb->isAdmin($oGroupProfile->id(), bx_get_logged_profile_id(), $aDataEntry))
+        if($this->_checkAllowedActionByFan(BX_BASE_MOD_GROUPS_ACTION_DELETE, $aDataEntry) === CHECK_ACTION_RESULT_ALLOWED)
             return CHECK_ACTION_RESULT_ALLOWED;
             return CHECK_ACTION_RESULT_ALLOWED;
-        return parent::checkAllowedDelete ($aDataEntry, $isPerformAction);
+
+        return parent::checkAllowedDelete($aDataEntry, $isPerformAction);
     }
     }
-    
+
     public function checkAllowedJoin(&$aDataEntry, $isPerformAction = false)
     public function checkAllowedJoin(&$aDataEntry, $isPerformAction = false)
     {
     {
         if (bx_get('key')){
         if (bx_get('key')){
@@ -821,6 +904,58 @@ class BxBaseModGroupsModule extends BxBaseModProfileModule
         return true;
         return true;
     }
     }
 
 
+    public function setRole($iGroupProfileId, $iFanProfileId, $iRole)
+    {
+        if(($mixedResult = $this->checkAllowedManageAdmins($iGroupProfileId)) !== CHECK_ACTION_RESULT_ALLOWED)
+            return array('code' => 1, 'msg' => $mixedResult);
+
+        if(!$this->_oDb->setRole($iGroupProfileId, $iFanProfileId, $iRole))
+            return array('code' => 2, 'msg' => _t('_error occured'));
+
+        $this->onSetRole($iGroupProfileId, $iFanProfileId, $iRole);
+
+        return array('code' => 0);
+    }
+
+    public function onSetRole($iGroupProfileId, $iFanProfileId, $iRole)
+    {
+        $CNF = &$this->_oConfig->CNF;
+
+        $iProfileId = bx_get_logged_profile_id();
+        $oGroupProfile = BxDolProfile::getInstance($iGroupProfileId);
+        $aGroupProfileInfo = $this->_oDb->getContentInfoById((int)$oGroupProfile->getContentId());
+        $aRoles = BxDolFormQuery::getDataItems($CNF['OBJECT_PRE_LIST_ROLES']);
+
+        // notify about admin status
+        if(!empty($CNF['EMAIL_FAN_SET_ROLE']) && $iFanProfileId != $iProfileId)
+            sendMailTemplate($CNF['EMAIL_FAN_SET_ROLE'], 0, $iFanProfileId, array(
+                'EntryUrl' => $oGroupProfile->getUrl(),
+                'EntryTitle' => $oGroupProfile->getDisplayName(),
+                'Role' => $aRoles[$iRole]
+            ), BX_EMAIL_NOTIFY);
+
+        // subscribe advanced group members automatically
+        $oConnection = BxDolConnection::getObjectInstance('sys_profiles_subscriptions');
+        if($iRole != 0)
+            $oConnection->addConnection($iFanProfileId, $iGroupProfileId);
+        else 
+            $oConnection->removeConnection($iFanProfileId, $iGroupProfileId);
+
+        bx_alert($this->getName(), 'set_role', $aGroupProfileInfo[$CNF['FIELD_ID']], $iGroupProfileId, array(
+            'object_author_id' => $iGroupProfileId,
+            'performer_id' => $iProfileId, 
+            'fan_id' => $iFanProfileId,
+
+            'content' => $aGroupProfileInfo, 
+            'role' => $iRole,
+
+            'group_profile' => $iGroupProfileId, 
+            'profile' => $iProfileId
+        ));
+
+        $this->doAudit($iGroupProfileId, $iFanProfileId, '_sys_audit_action_group_role_changed');
+    }
+
     protected function _getImagesForTimelinePost($aEvent, $aContentInfo, $sUrl, $aBrowseParams = array())
     protected function _getImagesForTimelinePost($aEvent, $aContentInfo, $sUrl, $aBrowseParams = array())
     {
     {
         $CNF = &$this->_oConfig->CNF;
         $CNF = &$this->_oConfig->CNF;

+ 6 - 0
modules/base/groups/template/css/main.css

@@ -22,3 +22,9 @@
 .bx-search-result-block {
 .bx-search-result-block {
     text-align:center;
     text-align:center;
 }
 }
+
+
+/*-- Group Roles --*/
+#bx-groups-set-role-popup .bx-menu-ver {
+    margin: 0;
+}

+ 1 - 0
modules/boonex/english/data/langs/system/en.xml

@@ -1799,6 +1799,7 @@
   <string name="_sys_audit_action_unfeature"><![CDATA[Unfeatured]]></string>
   <string name="_sys_audit_action_unfeature"><![CDATA[Unfeatured]]></string>
   <string name="_sys_audit_action_group_to_admins"><![CDATA[Added to group admins]]></string>
   <string name="_sys_audit_action_group_to_admins"><![CDATA[Added to group admins]]></string>
   <string name="_sys_audit_action_group_from_admins"><![CDATA[Removed from group admins]]></string>
   <string name="_sys_audit_action_group_from_admins"><![CDATA[Removed from group admins]]></string>
+  <string name="_sys_audit_action_group_role_changed"><![CDATA[Group role was changed]]></string>
   <string name="_sys_audit_action_group_join_request_accepted"><![CDATA[Join request accepted]]></string>
   <string name="_sys_audit_action_group_join_request_accepted"><![CDATA[Join request accepted]]></string>
   <string name="_sys_audit_action_account_change_role_to_3"><![CDATA[Made operator]]></string>
   <string name="_sys_audit_action_account_change_role_to_3"><![CDATA[Made operator]]></string>
   <string name="_sys_audit_action_account_change_role_to_1"><![CDATA[Unmade operator]]></string>
   <string name="_sys_audit_action_account_change_role_to_1"><![CDATA[Unmade operator]]></string>

+ 1 - 0
modules/boonex/russian/data/langs/system/ru.xml

@@ -1786,6 +1786,7 @@
   <string name="_sys_audit_action_unfeature"><![CDATA[Удален из избранных]]></string>
   <string name="_sys_audit_action_unfeature"><![CDATA[Удален из избранных]]></string>
   <string name="_sys_audit_action_group_to_admins"><![CDATA[Добавлен в администраторы группы]]></string>
   <string name="_sys_audit_action_group_to_admins"><![CDATA[Добавлен в администраторы группы]]></string>
   <string name="_sys_audit_action_group_from_admins"><![CDATA[Удален из администраторов группы]]></string>
   <string name="_sys_audit_action_group_from_admins"><![CDATA[Удален из администраторов группы]]></string>
+  <string name="_sys_audit_action_group_role_changed"><![CDATA[Роль в группе изменена]]></string>
   <string name="_sys_audit_action_group_join_request_accepted"><![CDATA[Запрос принят]]></string>
   <string name="_sys_audit_action_group_join_request_accepted"><![CDATA[Запрос принят]]></string>
   <string name="_sys_audit_action_account_change_role_to_3"><![CDATA[Добавлен в операторы]]></string>
   <string name="_sys_audit_action_account_change_role_to_3"><![CDATA[Добавлен в операторы]]></string>
   <string name="_sys_audit_action_account_change_role_to_1"><![CDATA[Удален из операторов]]></string>
   <string name="_sys_audit_action_account_change_role_to_1"><![CDATA[Удален из операторов]]></string>