Group Implementation Initial

This commit is contained in:
buddha87 2016-03-14 20:10:18 +01:00
parent f905e2c21b
commit c6f8769bfe
34 changed files with 671 additions and 175 deletions

View File

@ -32,7 +32,9 @@
"bower-asset/jquery-placeholder": "^2.3.0",
"bower-asset/blueimp-file-upload": "9.11.*",
"bower-asset/fontawesome": "^4.3.0",
"bower-asset/bootstrap-markdown": "2.10.*"
"bower-asset/bootstrap-markdown": "2.10.*",
"bower-asset/select2" : "^4.0.2",
"bower-asset/select2-bootstrap-theme" : "0.1.0-beta.4"
},
"require-dev": {
"yiisoft/yii2-codeception": "*",

View File

@ -20,7 +20,7 @@ class AppAsset extends AssetBundle
'css/temp.css',
'css/bootstrap-wysihtml5.css',
'css/flatelements.css',
'resources/at/jquery.atwho.css',
'resources/at/jquery.atwho.css'
];
public $jsOptions = ['position' => \yii\web\View::POS_BEGIN];
public $js = [
@ -40,8 +40,8 @@ class AppAsset extends AssetBundle
'resources/at/jquery.atwho.min.js',
'resources/file/fileuploader.js',
'resources/user/userpicker.js',
'js/app.js',
'js/humhub.js'
'js/app.js'
];
public $depends = [
'yii\web\YiiAsset',

View File

@ -0,0 +1,42 @@
<?php
/**
* @link https://www.humhub.org/
* @copyright Copyright (c) 2015 HumHub GmbH & Co. KG
* @license https://www.humhub.com/licences
*/
namespace humhub\assets;
use yii\web\AssetBundle;
/**
* jquery-knob
*
* @author luke
*/
class Select2Asset extends AssetBundle
{
public $jsOptions = ['position' => \yii\web\View::POS_BEGIN];
/**
* @inheritdoc
*/
public $sourcePath = '@bower/select2';
/**
* @inheritdoc
*/
public $js = ['dist/js/select2.min.js'];
/**
* @inheritdoc
*/
public $css = ['dist/css/select2.min.css'];
public $depends = [
'humhub\assets\AppAsset'
];
}

View File

@ -0,0 +1,39 @@
<?php
/**
* @link https://www.humhub.org/
* @copyright Copyright (c) 2015 HumHub GmbH & Co. KG
* @license https://www.humhub.com/licences
*/
namespace humhub\assets;
use yii\web\AssetBundle;
/**
* jquery-knob
*
* @author luke
*/
class Select2BootstrapAsset extends AssetBundle
{
/**
* @inheritdoc
*/
public $sourcePath = '@bower/select2-bootstrap-theme';
/**
* @inheritdoc
*/
public $css = ['dist/select2-bootstrap.css'];
/**
*
* @var type
*/
public $depends = [
'humhub\assets\Select2Asset'
];
}

View File

@ -187,6 +187,10 @@ class HForm extends \yii\base\Component
if ($model) {
$options = [];
if (isset($definition['id'])) {
$options['id'] = $definition['id'];
}
if (isset($definition['readonly']) && $definition['readonly']) {
$options['readOnly'] = true;
}
@ -197,33 +201,39 @@ class HForm extends \yii\base\Component
$options['label'] = $definition['label'];
}
if (isset($definition['type'])) {
if ($definition['type'] == 'text') {
$output .= $this->form->field($model, $name)->textInput($options);
} elseif ($definition['type'] == 'dropdownlist') {
$output .= $this->form->field($model, $name)->dropDownList($definition['items'], $options);
} elseif ($definition['type'] == 'checkbox') {
switch($definition['type']) {
case 'text':
return $this->form->field($model, $name)->textInput($options);
case 'multiselectdropdown':
$options['class'] = 'form-control multiselect_dropdown';
$options['multiple'] = 'multiple';
return $this->form->field($model, $name)->listBox($definition['items'], $options);
//return $this->form->field($model, $name)->dropDownList($definition['items'], $options);
case 'dropdownlist':
return $this->form->field($model, $name)->dropDownList($definition['items'], $options);
case 'checkbox':
if (isset($options['readOnly']) && $options['readOnly']) {
$options['disabled'] = 'disabled';
}
$output .= $this->form->field($model, $name)->checkbox($options);
} elseif ($definition['type'] == 'textarea') {
$output .= $this->form->field($model, $name)->textarea($options);
} elseif ($definition['type'] == 'hidden') {
$output .= $this->form->field($model, $name)->hiddenInput($options)->label(false);
} elseif ($definition['type'] == 'password') {
$output .= $this->form->field($model, $name)->passwordInput($options);
} elseif ($definition['type'] == 'datetime') {
return $this->form->field($model, $name)->checkbox($options);
case 'textarea':
return $this->form->field($model, $name)->textarea($options);
case 'hidden':
return $this->form->field($model, $name)->hiddenInput($options)->label(false);
case 'password':
return $this->form->field($model, $name)->passwordInput($options);
case 'datetime':
$format = Yii::$app->formatter->dateFormat;
if (isset($definition['format'])) {
$format = $definition['format'];
}
$output .= $this->form->field($model, $name)->widget(\yii\jui\DatePicker::className(), ['dateFormat' => $format, 'clientOptions' => ['changeYear' => true, 'yearRange' => (date('Y') - 100) . ":" . date('Y'), 'changeMonth' => true, 'disabled' => (isset($options['readOnly']) && $options['readOnly'])], 'options' => ['class' => 'form-control']]);
} else {
$output .= "Field Type " . $definition['type'] . " not supported by Compat HForm";
}
return $this->form->field($model, $name)->widget(\yii\jui\DatePicker::className(), ['dateFormat' => $format, 'clientOptions' => ['changeYear' => true, 'yearRange' => (date('Y') - 100) . ":" . date('Y'), 'changeMonth' => true, 'disabled' => (isset($options['readOnly']) && $options['readOnly'])], 'options' => ['class' => 'form-control']]);
default:
return "Field Type " . $definition['type'] . " not supported by Compat HForm";
}
} else {
$output .= "No model for: FieldName: " . $name . " Type:" . $definition['type'] . " Forms: " . print_r($forms, 1) . "<br>";
return "No model for: FieldName: " . $name . " Type:" . $definition['type'] . " Forms: " . print_r($forms, 1) . "<br>";
}
}
return $output;

View File

@ -10,6 +10,7 @@ namespace humhub\modules\admin;
use Yii;
use humhub\modules\user\models\User;
use \humhub\modules\user\models\Group;
use humhub\modules\admin\libs\OnlineModuleManager;
use humhub\models\Setting;
@ -59,7 +60,7 @@ class Events extends \yii\base\Object
$latestVersion = libs\HumHubAPI::getLatestHumHubVersion();
if ($latestVersion != "") {
$adminUserQuery = User::find()->where(['super_admin' => 1]);
$adminUsers = \humhub\modules\user\models\Group::getAdminGroup()->user;
$latestNotifiedVersion = Setting::Get('lastVersionNotify', 'admin');
$adminsNotified = !($latestNotifiedVersion == "" || version_compare($latestVersion, $latestNotifiedVersion, ">"));
$newVersionAvailable = (version_compare($latestVersion, Yii::$app->version, ">"));
@ -67,14 +68,14 @@ class Events extends \yii\base\Object
// Cleanup existing notifications
if (!$newVersionAvailable || ($newVersionAvailable && !$adminsNotified)) {
foreach ($adminUserQuery->all() as $admin) {
foreach ($adminUsers as $admin) {
$updateNotification->delete($admin);
}
}
// Create new notification
if ($newVersionAvailable && !$adminsNotified) {
$updateNotification->sendBulk($adminUserQuery);
$updateNotification->sendBulk($adminUsers);
Setting::Set('lastVersionNotify', $latestVersion, 'admin');
}
}

View File

@ -10,10 +10,8 @@ namespace humhub\modules\admin\controllers;
use Yii;
use yii\helpers\Url;
use yii\data\ArrayDataProvider;
use humhub\modules\admin\components\Controller;
use humhub\modules\user\models\Group;
use humhub\modules\user\models\User;
/**
* Group Administration Controller
@ -90,14 +88,15 @@ class GroupController extends Controller
public function actionDelete()
{
$group = Group::findOne(['id' => Yii::$app->request->get('id')]);
if ($group == null)
if ($group == null) {
throw new \yii\web\HttpException(404, Yii::t('AdminModule.controllers_GroupController', 'Group not found!'));
}
$model = new \humhub\modules\admin\models\forms\AdminDeleteGroupForm;
if ($model->load(Yii::$app->request->post()) && $model->validate()) {
foreach (User::findAll(['group_id' => $group->id]) as $user) {
$user->group_id = $model->group_id;
$user->save();
//TODO: obsolete ? foreignkeys
foreach($group->groupUsers as $groupUser) {
$groupUser->delete();
}
$group->delete();
$this->redirect(Url::toRoute("/admin/group"));

View File

@ -15,6 +15,7 @@ use humhub\modules\user\models\forms\Registration;
use humhub\modules\admin\components\Controller;
use humhub\modules\user\models\User;
use humhub\modules\user\models\Group;
use humhub\modules\admin\models\forms\UserGroupForm;
/**
* User management
@ -36,7 +37,6 @@ class UserController extends Controller
{
$searchModel = new \humhub\modules\admin\models\UserSearch();
$dataProvider = $searchModel->search(Yii::$app->request->queryParams);
return $this->render('index', array(
'dataProvider' => $dataProvider,
'searchModel' => $searchModel
@ -63,7 +63,7 @@ class UserController extends Controller
$definition = array();
$definition['elements'] = array();
// Add User Form
$definition['elements']['User'] = array(
$definition['elements']['User'] = [
'type' => 'form',
'title' => 'Account',
'elements' => array(
@ -77,14 +77,6 @@ class UserController extends Controller
'class' => 'form-control',
'maxlength' => 100,
),
'group_id' => array(
'type' => 'dropdownlist',
'class' => 'form-control',
'items' => \yii\helpers\ArrayHelper::map(Group::find()->all(), 'id', 'name'),
),
'super_admin' => array(
'type' => 'checkbox',
),
'status' => array(
'type' => 'dropdownlist',
'class' => 'form-control',
@ -95,7 +87,22 @@ class UserController extends Controller
),
),
),
);
];
$userGroupForm = new UserGroupForm();
$userGroupForm->setUser($user);
// Add User Form
$definition['elements']['UserGroupForm'] = [
'type' => 'form',
'elements' => [
'groupSelection' => [
'id' => 'user_edit_groups',
'type' => 'multiselectdropdown',
'items' => UserGroupForm::getGroupItems(Group::find()->all())
]
]
];
// Add Profile Form
$definition['elements']['Profile'] = array_merge(array('type' => 'form'), $profile->getFormDefinition());
@ -122,9 +129,11 @@ class UserController extends Controller
$form = new HForm($definition);
$form->models['User'] = $user;
$form->models['Profile'] = $profile;
$form->models['UserGroupForm'] = $userGroupForm;
if ($form->submitted('save') && $form->validate()) {
if ($form->save()) {
return $this->redirect(Url::toRoute('/admin/user'));
}
}

View File

@ -53,7 +53,7 @@ class UserApprovalSearch extends User
*/
public function search($params = [])
{
$query = User::find()->joinWith(['profile', 'group']);
$query = User::find()->joinWith(['profile', 'groups']);
$dataProvider = new ActiveDataProvider([
'query' => $query,
@ -62,7 +62,6 @@ class UserApprovalSearch extends User
$dataProvider->setSort([
'attributes' => [
'group.id',
'username',
'email',
'super_admin',
@ -88,12 +87,9 @@ class UserApprovalSearch extends User
foreach ($groups as $group) {
$groupIds[] = $group->id;
}
$query->andWhere(['IN', 'group_id', $groupIds]);
$query->andWhere(['IN', 'group.id', $groupIds]);
$query->andWhere(['status' => User::STATUS_NEED_APPROVAL]);
$query->andFilterWhere(['id' => $this->id]);
$query->andFilterWhere(['group.id' => $this->getAttribute('group.id')]);
$query->andFilterWhere(['super_admin' => $this->super_admin]);
$query->andFilterWhere(['like', 'id', $this->id]);
$query->andFilterWhere(['like', 'username', $this->username]);
$query->andFilterWhere(['like', 'email', $this->email]);
@ -111,13 +107,7 @@ class UserApprovalSearch extends User
if (Yii::$app->user->isAdmin()) {
return \humhub\modules\user\models\Group::find()->all();
} else {
$groups = [];
foreach (\humhub\modules\user\models\GroupAdmin::find()->joinWith('group')->where(['user_id' => Yii::$app->user->id])->all() as $groupAdmin) {
if ($groupAdmin->group !== null)
$groups[] = $groupAdmin->group;
}
return $groups;
return Yii::$app->user->adminGroups;
}
}
}

View File

@ -30,7 +30,7 @@ class UserSearch extends User
public function rules()
{
return [
[['id', 'super_admin'], 'integer'],
[['id'], 'integer'],
[['username', 'email', 'created_at', 'profile.firstname', 'profile.lastname', 'last_login'], 'safe'],
];
}
@ -65,7 +65,6 @@ class UserSearch extends User
'id',
'username',
'email',
'super_admin',
'last_login',
'profile.firstname',
'profile.lastname',
@ -81,7 +80,6 @@ class UserSearch extends User
}
$query->andFilterWhere(['id' => $this->id]);
$query->andFilterWhere(['super_admin' => $this->super_admin]);
$query->andFilterWhere(['like', 'id', $this->id]);
$query->andFilterWhere(['like', 'username', $this->username]);
$query->andFilterWhere(['like', 'email', $this->email]);

View File

@ -0,0 +1,141 @@
<?php
/**
* @link https://www.humhub.org/
* @copyright Copyright (c) 2015 HumHub GmbH & Co. KG
* @license https://www.humhub.com/licences
*/
namespace humhub\modules\admin\models\forms;
use humhub\modules\user\models\Group;
/**
* Description of UserGroupForm
*
* @author buddha
*/
class UserGroupForm extends \yii\base\Model
{
/**
* GroupId selection array of the form.
* @var type
*/
public $groupSelection;
/**
* Current member groups (models) of the given $user
* @var type
*
*/
public $currentGroups;
/**
* User model object
* @var type
*/
public $user;
/**
* @inheritdoc
*/
public function rules()
{
return [
['groupSelection', 'safe']
];
}
/**
* @inheritdoc
*/
public function attributeLabels()
{
return [
'groupSelection' => 'Groups',
'adminGroupSelection' => 'Admin Groups'
];
}
/**
* Sets the user data and intitializes the from selection
* @param type $user
*/
public function setUser($user)
{
//Set form user and current group settings
$this->user = $user;
$this->currentGroups = $user->groups;
//Set the current group selection
$this->groupSelection = [];
foreach ($this->currentGroups as $group) {
$this->groupSelection[] = $group->id;
}
}
/**
* Aligns the given group selection with the db
* @return boolean
*/
public function save()
{
//Check old group selection and remove non selected groups
foreach($this->currentGroups as $userGroup) {
if(!$this->isInGroupSelection($userGroup)) {
$this->user->getGroupUsers()->where(['group_id' => $userGroup->id])->one()->delete();
}
}
//Add all selectedGroups to the given user and set the admin by means of the selectedAdminGroups
foreach ($this->groupSelection as $groupId) {
if (!$this->isCurrentlyMemberOf($groupId)) {
Group::findOne($groupId)->addUser($this->user);
}
}
return true;
}
/**
* Checks if the given group (id or model object) is contained in the form selection
* @param type $groupId groupId or Group model object
* @return boolean true if contained in selection else false
*/
private function isInGroupSelection($groupId)
{
$groupId = ($groupId instanceof Group) ? $groupId->id : $groupId;
$this->groupSelection = (is_array($this->groupSelection)) ? $this->groupSelection : [];
return is_array($this->groupSelection) && in_array($groupId, $this->groupSelection);
}
/**
* Checks if the user is member of the given group (id or model object)
* @param type $groupId $groupId groupId or Group model object
* @return boolean true if user is member else false
*/
private function isCurrentlyMemberOf($groupId)
{
foreach ($this->currentGroups as $userGroup) {
if ($userGroup->id === $groupId) {
return true;
}
}
return false;
}
/**
* Returns an id => groupname array representation of the given $groups array.
* @param array $groups array of Group models
* @return type array in form of id => groupname
*/
public static function getGroupItems($groups)
{
$result = [];
foreach ($groups as $group) {
$result[$group->id] = $group->name;
}
return $result;
}
}

View File

@ -21,15 +21,7 @@ use humhub\widgets\GridView;
'dataProvider' => $dataProvider,
'filterModel' => $searchModel,
'columns' => [
[
'attribute' => 'group.id',
'label' => 'Group',
'filter' => \yii\helpers\Html::activeDropDownList($searchModel, 'group.id', \yii\helpers\ArrayHelper::map($searchModel->getGroups(), 'id', 'name')),
'value' =>
function($data) {
return $data->group->name . " (" . $data->group->id . ")";
}
], 'username',
'username',
'email',
'profile.firstname',
'profile.lastname',

View File

@ -36,12 +36,14 @@ use yii\helpers\Html;
]);
?>
<?php echo $form->field($group, 'adminGuids', ['inputOptions' => ['id' => 'user_select']]); ?>
<?php
echo \humhub\modules\user\widgets\UserPicker::widget([
'inputId' => 'user_select',
'maxUsers' => 2,
'model' => $group,
'attribute' => 'adminGuids',
'userSearchUrl' => Url::toRoute('admin/group/admin-user-serach'),
'placeholderText' => 'Add a user'
]);
?>

View File

@ -1,11 +1,7 @@
<?php
use humhub\compat\CActiveForm;
use humhub\compat\CHtml;
use humhub\models\Setting;
use yii\helpers\Url;
use yii\helpers\Html;
use yii\grid\GridView;
humhub\assets\Select2Asset::register($this);
?>
<div class="panel panel-default">
<div class="panel-heading"><?php echo Yii::t('AdminModule.views_user_edit', '<strong>Edit</strong> user'); ?></div>
@ -14,4 +10,45 @@ use yii\grid\GridView;
<?php echo $hForm->render($form); ?>
<?php \yii\widgets\ActiveForm::end(); ?>
</div>
<script type="text/javascript">
$.fn.select2.defaults = {};
//This function manipulates the presentation of the dropdown results
//To fit the user picker style
var updateDropDown = function() {
$('span[role="presentation"]').hide();
$('.select2-selection__choice').addClass('userInput');
$closeButton = $('<i class="fa fa-times-circle"></i>');
$closeButton.on('click', function() {
$(this).siblings('span[role="presentation"]').trigger('click');
});
$('.select2-selection__choice').append($closeButton);
};
var isOpen = false;
//We have to overwrite the the result gui after every change
$('.multiselect_dropdown').select2({}).on('change', function() {
updateDropDown();
}).on('select2:open', function() {
isOpen = true;
}).on('select2:close', function() {
isOpen = false;
});
//For highlighting the input
$(".select2-container").on("focusin", function () {
$(this).find('.select2-selection').addClass('select2-selection--focus');
});
//Since the focusout of the ontainer is called when the dropdown is opened we have to use this focusout
$(document).on('focusout','.select2-search__field', function() {
if(!isOpen) {
$(this).closest('.select2-selection').removeClass('select2-selection--focus');
}
});
updateDropDown();
</script>
</div>

View File

@ -33,15 +33,6 @@ use humhub\widgets\GridView;
'email',
'profile.firstname',
'profile.lastname',
[
'attribute' => 'super_admin',
'label' => 'Admin',
'filter' => \yii\helpers\Html::activeDropDownList($searchModel, 'super_admin', array('' => 'All', '0' => 'No', '1' => 'Yes')),
'value' =>
function($data) {
return ($data->super_admin == 1) ? 'Yes' : 'No';
}
],
[
'attribute' => 'last_login',
'label' => Yii::t('AdminModule.views_user_index', 'Last login'),

View File

@ -596,7 +596,7 @@ class Content extends \humhub\components\ActiveRecord
}
// Check Superadmin can see all content option
if ($user->super_admin === 1 && Yii::$app->getModule('content')->adminCanViewAllContent) {
if ($user->isSystemAdmin() && Yii::$app->getModule('content')->adminCanViewAllContent) {
return true;
}

View File

@ -12,11 +12,11 @@ use humhub\modules\user\models\User;
<div class="panel-body">
<?php foreach ($groups as $group) : ?>
<?php $userCount = User::find()->andWhere(['group_id' => $group->id])->active()->count(); ?>
<?php $userCount = $group->getGroupUsers()->count(); ?>
<?php if ($userCount != 0) : ?>
<h1><?php echo Html::encode($group->name); ?></h1>
<?php foreach (User::find()->where(['group_id' => $group->id])->active()->limit(30)->joinWith('profile')->orderBy(['profile.lastname' => SORT_ASC])->all() as $user) : ?>
<?php foreach ($group->getUsers()->limit(30)->joinWith('profile')->orderBy(['profile.lastname' => SORT_ASC])->all() as $user) : ?>
<a id="<?php echo $user->guid; ?>" href="<?php echo $user->getUrl(); ?>">
<img data-toggle="tooltip" data-placement="top" title=""
data-original-title="<?php echo Html::encode($user->displayName); ?>"

View File

@ -64,8 +64,17 @@ use yii\helpers\Html;
<div class="media-body">
<h4 class="media-heading"><a
href="<?php echo $user->getUrl(); ?>"><?php echo Html::encode($user->displayName); ?></a>
<?php if ($user->group != null) { ?>
<small>(<?php echo Html::encode($user->group->name); ?>)</small><?php } ?>
<?php if ($user->hasGroup()) { ?>
<small>(
<?php $groups = $user->selectedGroups;
$last_key = end(array_keys($groups));
foreach($groups as $key => $group) {
echo $group->name;
if($key != $last_key) {
echo ', ';
}
} ?>
)</small><?php } ?>
</h4>
<h5><?php echo Html::encode($user->profile->title); ?></h5>

View File

@ -25,7 +25,7 @@ class GroupStatistics extends \yii\base\Widget
$users = User::find()->count();
$statsAvgMembers = $users / $groups;
$statsTopGroup = Group::find()->where('id = (SELECT group_id FROM user GROUP BY group_id ORDER BY count(*) DESC LIMIT 1)')->one();
$statsTopGroup = Group::find()->where('id = (SELECT group_id FROM group_user GROUP BY group_id ORDER BY count(*) DESC LIMIT 1)')->one();
// Render widgets view
return $this->render('groupStats', array(

View File

@ -247,7 +247,6 @@ class ConfigController extends Controller
$userModel->status = User::STATUS_ENABLED;
$userModel->username = "david1986";
$userModel->email = "david.roberts@humhub.com";
$userModel->super_admin = 0;
$userModel->language = '';
$userModel->group_id = 1;
$userModel->tags = "Microsoft Office, Marketing, SEM, Digital Native";
@ -276,7 +275,6 @@ class ConfigController extends Controller
$userModel2->status = User::STATUS_ENABLED;
$userModel2->username = "sara1989";
$userModel2->email = "sara.schuster@humhub.com";
$userModel2->super_admin = 0;
$userModel2->language = '';
$userModel2->group_id = 1;
$userModel2->tags = "Yoga, Travel, English, German, French";

View File

@ -408,7 +408,7 @@ class Space extends ContentContainerActiveRecord implements \humhub\modules\sear
*/
public function canAccessPrivateContent(\humhub\modules\user\models\User $user = null)
{
if (Yii::$app->getModule('space')->globalAdminCanAccessPrivateContent && Yii::$app->user->getIdentity()->super_admin === 1) {
if (Yii::$app->getModule('space')->globalAdminCanAccessPrivateContent && Yii::$app->user->getIdentity()->isSystemAdmin()) {
return true;
}

View File

@ -5,6 +5,7 @@ namespace humhub\modules\user;
use Yii;
use humhub\modules\user\models\User;
use humhub\modules\user\models\GroupAdmin;
use humhub\modules\user\models\Group;
use humhub\modules\user\models\Password;
use humhub\modules\user\models\Profile;
use humhub\modules\user\models\Mentioning;
@ -57,16 +58,15 @@ class Events extends \yii\base\Object
if ($user->profile == null) {
$integrityController->showWarning("User with id " . $user->id . " has no profile record!");
}
if ($user->group == null) {
if ($user->hasGroup() == null) {
$integrityController->showWarning("User with id " . $user->id . " has no group assignment!");
}
}
$integrityController->showTestHeadline("User Module - GroupAdmin (" . GroupAdmin::find()->count() . " entries)");
foreach (GroupAdmin::find()->joinWith(['user'])->all() as $groupAdmin) {
if ($groupAdmin->user == null) {
if ($integrityController->showFix("Deleting group admin " . $groupAdmin->id . " without existing user!")) {
$groupAdmin->delete();
foreach (GroupUser::find()->joinWith(['user'])->all() as $groupUser) {
if ($groupUser->user == null) {
if ($integrityController->showFix("Deleting group admin " . $groupUser->id . " without existing user!")) {
$groupUser->delete();
}
}
}

View File

@ -24,8 +24,8 @@ class PermissionManager extends \yii\base\Component
public function can(BasePermission $permission)
{
$groupId = Yii::$app->user->getIdentity()->group_id;
if ($this->getGroupState($groupId, $permission) == BasePermission::STATE_ALLOW) {
$groups = Yii::$app->user->getIdentity()->groups;
if ($this->getGroupState($groups, $permission) == BasePermission::STATE_ALLOW) {
return true;
}
@ -63,6 +63,31 @@ class PermissionManager extends \yii\base\Component
$record->save();
}
/**
* Returns the group permission state of the given group or goups.
* If the provided $group is an array we check if one of the group states
* is a BasePermission::STATE_ALLOW and return this state.
*
* @param type $groups either an array of groups or group ids or an single group or goup id
* @param BasePermission $permission
* @param type $returnDefaultState
* @return type
*/
public function getGroupState($groups, BasePermission $permission, $returnDefaultState = true)
{
if(is_array($groups)) {
$state = "";
foreach($groups as $group) {
$state = $this->getSingleGroupState($group, $permission, $returnDefaultState);
if($state === BasePermission::STATE_ALLOW) {
return $state;
}
}
return $state;
}
return $this->getSingleGroupState($groups, $permission, $returnDefaultState);
}
/**
* Returns the group state
*
@ -71,8 +96,12 @@ class PermissionManager extends \yii\base\Component
* @param boolean $returnDefaultState
* @return string the state
*/
public function getGroupState($groupId, BasePermission $permission, $returnDefaultState = true)
private function getSingleGroupState($groupId, BasePermission $permission, $returnDefaultState = true)
{
if($groupId instanceof \humhub\modules\user\models\Group) {
$groupId = $groupId->id;
}
// Check if database entry exists
$dbRecord = $this->getGroupStateRecord($groupId, $permission);

View File

@ -35,7 +35,7 @@ class User extends \yii\web\User
if ($this->isGuest)
return false;
return ($this->getIdentity()->super_admin == 1);
return $this->getIdentity()->isSystemAdmin();
}
public function getLanguage()

View File

@ -487,7 +487,7 @@ class AccountController extends BaseAccountController
*/
public function getUser()
{
if (Yii::$app->request->get('userGuid') != '' && Yii::$app->user->getIdentity()->super_admin === 1) {
if (Yii::$app->request->get('userGuid') != '' && Yii::$app->user->getIdentity()->isSystemAdmin()) {
$user = User::findOne(['guid' => Yii::$app->request->get('userGuid')]);
if ($user === null) {
throw new HttpException(404, 'Could not find user!');

View File

@ -227,7 +227,7 @@ class AuthController extends Controller
$output['userName'] = $httpSession->user->username;
$output['fullName'] = $httpSession->user->displayName;
$output['email'] = $httpSession->user->email;
$output['superadmin'] = $httpSession->user->super_admin;
$output['superadmin'] = $httpSession->user->isSystemAdmin();
}
return $output;
}

View File

@ -67,6 +67,7 @@ class Group extends \yii\db\ActiveRecord
'id' => 'ID',
'space_id' => 'Space ID',
'name' => 'Name',
'adminGuids' => 'Administrators',
'description' => 'Description',
'created_at' => 'Created At',
'created_by' => 'Created By',
@ -99,20 +100,31 @@ class Group extends \yii\db\ActiveRecord
public function afterSave($insert, $changedAttributes)
{
if ($this->scenario == 'edit') {
\humhub\modules\user\models\GroupAdmin::deleteAll(['group_id' => $this->id]);
$adminUsers = array();
foreach (explode(",", $this->adminGuids) as $adminGuid) {
$adminGuids = explode(",", $this->adminGuids);
foreach ($adminGuids as $adminGuid) {
// Ensure guids valid characters
$adminGuid = preg_replace("/[^A-Za-z0-9\-]/", '', $adminGuid);
// Try load user
$user = \humhub\modules\user\models\User::findOne(['guid' => $adminGuid]);
if ($user != null) {
$groupAdmin = new GroupAdmin;
$groupAdmin->user_id = $user->id;
$groupAdmin->group_id = $this->id;
$groupAdmin->save();
$groupUser = GroupUser::findOne(['group_id' => $this->id, 'user_id' => $user->id]);
if($groupUser != null && !$groupUser->is_group_admin) {
$groupUser->is_group_admin = true;
$groupUser->save();
} else {
$this->addUser($user, true);
}
}
}
foreach ($this->getAdmins()->all() as $admin) {
if(!in_array($admin->guid, $adminGuids)) {
$groupUser = GroupUser::findOne(['group_id' => $this->id, 'user_id' => $admin->id]);
if($groupUser != null) {
$groupUser->is_group_admin = false;
$groupUser->save();
}
}
}
}
@ -132,18 +144,54 @@ class Group extends \yii\db\ActiveRecord
{
$this->adminGuids = "";
foreach ($this->admins as $admin) {
$this->adminGuids .= $admin->user->guid . ",";
$this->adminGuids .= $admin->guid . ",";
}
}
public static function getAdminGroup()
{
return self::findOne(['is_admin_group', '1']);
}
public function getAdmins()
{
return $this->hasMany(GroupAdmin::className(), ['group_id' => 'id']);
return $this->hasMany(User::className(), ['id' => 'user_id'])
->via('groupUsers', function($query){
$query->where(['is_group_admin' => '1']);
});
}
public function hasAdmin()
{
return $this->getAdmins()->count() > 0;
}
public function getGroupUsers()
{
return $this->hasMany(GroupUser::className(), ['group_id' => 'id']);
}
public function getUsers()
{
return $this->hasMany(User::className(), ['user_id' => 'id']);
return $this->hasMany(User::className(), ['id' => 'user_id'])
->via('groupUsers');
}
public function hasUsers()
{
return $this->getUsers()->count() > 0;
}
public function addUser($user, $isAdmin = false)
{
$userId = ($user instanceof User) ? $user->id : $user;
$newGroupUser = new GroupUser();
$newGroupUser->user_id = $userId;
$newGroupUser->group_id = $this->id;
$newGroupUser->created_at = new \yii\db\Expression('NOW()');
$newGroupUser->created_by = Yii::$app->user->id;
$newGroupUser->is_group_admin = $isAdmin;
$newGroupUser->save();
}
public function getSpace()

View File

@ -0,0 +1,69 @@
<?php
namespace humhub\modules\user\models;
use humhub\modules\user\models\User;
use humhub\modules\user\models\Group;
/**
* This is the model class for table "group_admin".
*
* @property integer $id
* @property integer $user_id
* @property integer $group_id
* @property string $created_at
* @property integer $created_by
* @property string $updated_at
* @property integer $updated_by
*/
class GroupUser extends \yii\db\ActiveRecord
{
/**
* @inheritdoc
*/
public static function tableName()
{
return 'group_user';
}
/**
* @inheritdoc
*/
public function rules()
{
return [
[['user_id', 'group_id'], 'required'],
[['user_id', 'group_id', 'created_by', 'updated_by'], 'integer'],
[['created_at', 'updated_at'], 'safe'],
[['user_id', 'group_id'], 'unique', 'targetAttribute' => ['user_id', 'group_id'], 'message' => 'The combination of User ID and Group ID has already been taken.']
];
}
/**
* @inheritdoc
*/
public function attributeLabels()
{
return [
'id' => 'ID',
'user_id' => 'User ID',
'group_id' => 'Group ID',
'created_at' => 'Created At',
'created_by' => 'Created By',
'updated_at' => 'Updated At',
'updated_by' => 'Updated By',
];
}
public function getGroup()
{
return $this->hasOne(Group::className(), ['id' => 'group_id']);
}
public function getUser()
{
return $this->hasOne(User::className(), ['id' => 'user_id']);
}
}

View File

@ -11,7 +11,7 @@ namespace humhub\modules\user\models;
use Yii;
use yii\base\Exception;
use humhub\modules\content\components\ContentContainerActiveRecord;
use humhub\modules\user\models\GroupAdmin;
use humhub\modules\user\models\GroupUser;
use humhub\modules\user\components\ActiveQueryUser;
use humhub\modules\friendship\models\Friendship;
@ -21,9 +21,7 @@ use humhub\modules\friendship\models\Friendship;
* @property integer $id
* @property string $guid
* @property integer $wall_id
* @property integer $group_id
* @property integer $status
* @property integer $super_admin
* @property string $username
* @property string $email
* @property string $auth_mode
@ -86,7 +84,7 @@ class User extends ContentContainerActiveRecord implements \yii\web\IdentityInte
{
return [
[['username', 'email'], 'required'],
[['wall_id', 'group_id', 'status', 'super_admin', 'created_by', 'updated_by', 'visibility'], 'integer'],
[['wall_id', 'status', 'created_by', 'updated_by', 'visibility'], 'integer'],
[['tags'], 'string'],
[['last_activity_email', 'created_at', 'updated_at', 'last_login'], 'safe'],
[['guid'], 'string', 'max' => 45],
@ -103,13 +101,24 @@ class User extends ContentContainerActiveRecord implements \yii\web\IdentityInte
];
}
public function isSystemAdmin()
{
return $this->getGroups()->where(['is_admin_group' => '1'])->count() > 0;
}
public function __get($name)
{
if($name == 'super_admin') {
/**
* Replacement for old super_admin flag version
*/
return $this->isSystemAdmin();
} else if ($name == 'profile') {
/**
* Ensure there is always a related Profile Model also when it's
* not really exists yet.
*/
if ($name == 'profile') {
$profile = parent::__get('profile');
if (!$this->isRelationPopulated('profile') || $profile === null) {
$profile = new Profile();
@ -125,9 +134,9 @@ class User extends ContentContainerActiveRecord implements \yii\web\IdentityInte
{
$scenarios = parent::scenarios();
$scenarios['login'] = ['username', 'password'];
$scenarios['editAdmin'] = ['username', 'email', 'group_id', 'super_admin', 'status'];
$scenarios['registration_email'] = ['username', 'email', 'group_id'];
$scenarios['registration'] = ['username', 'group_id'];
$scenarios['editAdmin'] = ['username', 'email', 'status'];
$scenarios['registration_email'] = ['username', 'email'];
$scenarios['registration'] = ['username'];
return $scenarios;
}
@ -140,9 +149,7 @@ class User extends ContentContainerActiveRecord implements \yii\web\IdentityInte
'id' => 'ID',
'guid' => 'Guid',
'wall_id' => 'Wall ID',
'group_id' => 'Group ID',
'status' => 'Status',
'super_admin' => 'Super Admin',
'username' => 'Username',
'email' => 'Email',
'auth_mode' => 'Auth Mode',
@ -213,9 +220,38 @@ class User extends ContentContainerActiveRecord implements \yii\web\IdentityInte
return $this->hasOne(Profile::className(), ['user_id' => 'id']);
}
public function getGroup()
public function isAdminOf($group)
{
return $this->hasOne(Group::className(), ['id' => 'group_id']);
$groupId = ($group instanceof Group) ? $group.id : $group;
return $this->getAdminGroupUser()
->where(['group_id' => $groupId])->count() > 0;
}
public function getGroupUsers()
{
return $this->hasMany(GroupUser::className(), ['user_id' => 'id']);
}
public function getGroups()
{
return $this->hasMany(Group::className(), ['id' => 'group_id'])->via('groupUsers');
}
public function hasGroup()
{
return $this->getGroups()->count() > 0;
}
public function getAdminGroupsUser()
{
return $this->getGroupUsers()->where(['is_group_admin' => '1']);
}
public function getAdminGroups()
{
return $this->hasMany(Group::className(), ['id' => 'group_id'])->via('groupUsers', function($query) {
$query->andWhere(['is_group_admin' => '1']);
});
}
/**
@ -251,7 +287,7 @@ class User extends ContentContainerActiveRecord implements \yii\web\IdentityInte
Follow::deleteAll(['object_model' => $this->className(), 'object_id' => $this->id]);
Password::deleteAll(['user_id' => $this->id]);
Profile::deleteAll(['user_id' => $this->id]);
GroupAdmin::deleteAll(['user_id' => $this->id]);
GroupUser::deleteAll(['user_id' => $this->id]);
Session::deleteAll(['user_id' => $this->id]);
Setting::deleteAll(['user_id' => $this->id]);
@ -284,30 +320,12 @@ class User extends ContentContainerActiveRecord implements \yii\web\IdentityInte
if ($this->status == "") {
$this->status = self::STATUS_ENABLED;
}
if ((\humhub\models\Setting::Get('defaultUserGroup', 'authentication_internal'))) {
$this->group_id = \humhub\models\Setting::Get('defaultUserGroup', 'authentication_internal');
}
}
if ($this->time_zone == "") {
$this->time_zone = \humhub\models\Setting::Get('timeZone');
}
if ($this->group_id == "") {
// Try autoset group
$availableGroups = Group::getRegistrationGroups();
$defaultUserGroup = \humhub\models\Setting::Get('defaultUserGroup', 'authentication_internal');
if ($defaultUserGroup != '') {
$this->group_id = $defaultUserGroup;
} elseif (isset($availableGroups[0])) {
// Fallback to first available group
$this->group_id = $availableGroups[0]->id;
} else {
throw new \yii\base\Exception("Could not save user without group!");
}
}
return parent::beforeSave($insert);
}
@ -525,13 +543,15 @@ class User extends ContentContainerActiveRecord implements \yii\web\IdentityInte
*/
public function canApproveUsers()
{
if ($this->super_admin == 1) {
if ($this->isSystemAdmin()) {
return true;
}
//TODO: should be done per permission !
/*
if (GroupAdmin::find()->where(['user_id' => $this->id])->count() != 0) {
return true;
}
}*/
return false;
}
@ -545,6 +565,7 @@ class User extends ContentContainerActiveRecord implements \yii\web\IdentityInte
}
/**
* TODO: deprecated
* @inheritdoc
*/
public function getUserGroup()

View File

@ -110,9 +110,6 @@ class Registration extends HForm
$groupFieldType = "hidden";
$defaultUserGroup = $groupModels[0]->id;
}
if ($groupFieldType == 'hidden') {
$this->getUser()->group_id = $defaultUserGroup;
}
$form = array(
'type' => 'form',
@ -131,12 +128,12 @@ class Registration extends HForm
'class' => 'form-control',
];
}
$form['elements']['group_id'] = [
/*$form['elements']['group_id'] = [
'type' => $groupFieldType,
'class' => 'form-control',
'items' => ArrayHelper::map($groupModels, 'id', 'name'),
'value' => $defaultUserGroup,
];
];*/
return $form;
}

View File

@ -0,0 +1,45 @@
<?php
/**
* @link https://www.humhub.org/
* @copyright Copyright (c) 2016 HumHub GmbH & Co. KG
* @license https://www.humhub.com/licences
*/
namespace humhub\modules\user\permissions;
use Yii;
use humhub\modules\user\models\User;
/**
* ViewAboutPage Permission
*/
class SuperAdminPermition extends \humhub\libs\BasePermission
{
/**
* @inheritdoc
*/
protected $id = 'create_private_space';
/**
* @inheritdoc
*/
protected $title = "Create private space";
/**
* @inheritdoc
*/
protected $description = "Can create hidden (private) spaces.";
/**
* @inheritdoc
*/
protected $moduleId = 'space';
/**
* @inheritdoc
*/
protected $defaultState = self::STATE_DENY;
}

View File

@ -45,7 +45,7 @@ class ProfileHeader extends \yii\base\Widget
// Check if profile header can be edited
if (!Yii::$app->user->isGuest) {
if (Yii::$app->user->getIdentity()->super_admin === 1 && Yii::$app->params['user']['adminCanChangeProfileImages']) {
if (Yii::$app->user->getIdentity()->isSystemAdmin() && Yii::$app->params['user']['adminCanChangeProfileImages']) {
$this->isProfileOwner = true;
} elseif (Yii::$app->user->id == $this->user->id) {
$this->isProfileOwner = true;

File diff suppressed because one or more lines are too long

View File

@ -2051,6 +2051,33 @@ ul.tag_input {
height: 100%;
}
// Multi Dropdown Select2 Overwrites
.select2-container--default .select2-selection--multiple {
border: 2px solid #ededed !important;
background-image: url("../img/select_arrow.png") !important;
background-repeat: no-repeat;
background-position: right 16px;
}
.select2-container--default .select2-selection--focus {
border: 2px solid #6fdbe8 !important;
}
.select2-selection__choice {
background-color: #6fdbe8 !important;
padding: 5px 0px 5px 5px !important;
border: none !important;
}
.select2-search--inline {
background-color: transparent !important;
padding: 5px 0px 5px 5px !important;
}
.select2-selection__choice__remove {
display:none !important;
}
// Activities
.activities {
max-height: 400px;