mirror of
https://github.com/humhub/humhub.git
synced 2025-02-22 18:22:43 +01:00
Merge branch 'develop' of github.com:humhub/humhub into develop
This commit is contained in:
commit
1820a734fd
@ -35,3 +35,4 @@
|
||||
- Enh #5080: Show available module updates directly in admin menu
|
||||
- Fix #5331: Fix js error on pjax open "Directory" page
|
||||
- Enh #5333: Module's events handlers registration: check if method exists
|
||||
- Enh #5300: Blocking users for space
|
||||
|
@ -9,6 +9,8 @@ namespace humhub\modules\content\models;
|
||||
|
||||
use humhub\components\ActiveRecord;
|
||||
use humhub\modules\content\components\ContentContainerActiveRecord;
|
||||
use humhub\modules\friendship\models\Friendship;
|
||||
use humhub\modules\space\models\Space;
|
||||
use humhub\modules\user\models\User;
|
||||
use humhub\modules\user\Module;
|
||||
use Yii;
|
||||
@ -38,9 +40,32 @@ class ContentContainerBlockedUsers extends ActiveRecord
|
||||
return [
|
||||
[['contentcontainer_id', 'user_id'], 'required'],
|
||||
[['contentcontainer_id', 'user_id'], 'integer'],
|
||||
[['user_id'], 'validateUser'],
|
||||
];
|
||||
}
|
||||
|
||||
public function validateUser()
|
||||
{
|
||||
$blockingUser = $this->getUser();
|
||||
$contentContainer = $this->getContentContainer();
|
||||
|
||||
if (!$blockingUser || !$contentContainer) {
|
||||
$this->addError('user_id', 'User and container ids should be specified!');
|
||||
}
|
||||
|
||||
if ($blockingUser->is($contentContainer)) {
|
||||
$this->addError('user_id', Yii::t('ContentModule.base', 'You cannot block the user of the same container!'));
|
||||
}
|
||||
|
||||
if (!Yii::$app->user->isGuest && $blockingUser->is(Yii::$app->user->getIdentity())) {
|
||||
$this->addError('user_id', Yii::t('ContentModule.base', 'You cannot block yourself!'));
|
||||
}
|
||||
|
||||
if (($contentContainer instanceof Space) && $contentContainer->isSpaceOwner($blockingUser)) {
|
||||
$this->addError('user_id', Yii::t('ContentModule.base', 'You cannot block the space owner!'));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get blocked user guids of the Content Container
|
||||
*
|
||||
@ -81,9 +106,6 @@ class ContentContainerBlockedUsers extends ActiveRecord
|
||||
$newBlockedUserIds = [];
|
||||
foreach ($newBlockedUsers as $newBlockedUser) {
|
||||
/* @var User $newBlockedUser */
|
||||
if ($newBlockedUser->is($contentContainer)) {
|
||||
continue;
|
||||
}
|
||||
$newBlockedUserRelation = new ContentContainerBlockedUsers();
|
||||
$newBlockedUserRelation->contentcontainer_id = $contentContainer->contentcontainer_id;
|
||||
$newBlockedUserRelation->user_id = $newBlockedUser->id;
|
||||
@ -95,6 +117,60 @@ class ContentContainerBlockedUsers extends ActiveRecord
|
||||
$contentContainer->settings->set(self::BLOCKED_USERS_SETTING, empty($newBlockedUserIds) ? null : implode(',', $newBlockedUserIds));
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function save($runValidation = true, $attributeNames = null)
|
||||
{
|
||||
if (!$this->validate()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return parent::save($runValidation, $attributeNames);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function afterSave($insert, $changedAttributes)
|
||||
{
|
||||
$this->afterBlockUserForUser();
|
||||
$this->afterBlockUserForSpace();
|
||||
parent::afterSave($insert, $changedAttributes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Call additional actions after save a blocked user for a User container
|
||||
*/
|
||||
public function afterBlockUserForUser()
|
||||
{
|
||||
$containerUser = $this->getContentContainer();
|
||||
if (!($containerUser instanceof User)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($blockedUser = $this->getUser()) {
|
||||
Friendship::cancel($containerUser, $blockedUser);
|
||||
$containerUser->unfollow($blockedUser->id);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Call additional actions after save a blocked user for a Space container
|
||||
*/
|
||||
public function afterBlockUserForSpace()
|
||||
{
|
||||
$space = $this->getContentContainer();
|
||||
if (!($space instanceof Space)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($blockedUser = $this->getUser()) {
|
||||
$space->removeMember($blockedUser->id);
|
||||
$space->unfollow($blockedUser->id);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete blocked user relations of the Content Container
|
||||
*
|
||||
@ -110,4 +186,30 @@ class ContentContainerBlockedUsers extends ActiveRecord
|
||||
|
||||
$contentContainer->settings->delete(self::BLOCKED_USERS_SETTING);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Content Container(Space/User) of this relation
|
||||
*
|
||||
* @return ContentContainerActiveRecord|null
|
||||
*/
|
||||
public function getContentContainer(): ?ContentContainerActiveRecord
|
||||
{
|
||||
if (empty($this->contentcontainer_id)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$contentContainer = ContentContainer::findOne($this->contentcontainer_id);
|
||||
|
||||
return $contentContainer ? $contentContainer->getPolymorphicRelation() : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get blocked User of this relation
|
||||
*
|
||||
* @return User|null
|
||||
*/
|
||||
public function getUser(): ?User
|
||||
{
|
||||
return empty($this->user_id) ? null : User::findOne($this->user_id);
|
||||
}
|
||||
}
|
||||
|
@ -14,9 +14,9 @@ use humhub\modules\space\models\Membership;
|
||||
use humhub\modules\space\models\Space;
|
||||
use humhub\modules\user\components\ActiveQueryUser;
|
||||
use humhub\modules\user\models\User;
|
||||
use humhub\modules\user\Module;
|
||||
use Yii;
|
||||
use yii\db\ActiveQuery;
|
||||
use yii\db\Expression;
|
||||
|
||||
|
||||
/**
|
||||
@ -96,4 +96,32 @@ class ActiveQuerySpace extends ActiveQuery
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Exclude blocked spaces for the given $user or for the current User
|
||||
*
|
||||
* @param User $user
|
||||
* @return ActiveQueryUser the query
|
||||
*/
|
||||
public function filterBlockedSpaces(?User $user = null): ActiveQuerySpace
|
||||
{
|
||||
if ($user === null && !Yii::$app->user->isGuest) {
|
||||
$user = Yii::$app->user->getIdentity();
|
||||
}
|
||||
|
||||
if (!($user instanceof User)) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
/* @var Module $userModule */
|
||||
$userModule = Yii::$app->getModule('user');
|
||||
if (!$userModule->allowBlockUsers()) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
$this->leftJoin('contentcontainer_blocked_users', 'contentcontainer_blocked_users.contentcontainer_id=space.contentcontainer_id AND contentcontainer_blocked_users.user_id=:blockedUserId', [':blockedUserId' => $user->id]);
|
||||
$this->andWhere('contentcontainer_blocked_users.user_id IS NULL');
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
|
@ -48,6 +48,7 @@ class SpaceDirectoryQuery extends ActiveQuerySpace
|
||||
|
||||
$this->visible();
|
||||
|
||||
$this->filterBlockedSpaces();
|
||||
$this->filterByKeyword();
|
||||
$this->filterByConnection();
|
||||
|
||||
|
@ -48,7 +48,7 @@ class BrowseController extends Controller
|
||||
{
|
||||
Yii::$app->response->format = 'json';
|
||||
|
||||
$query = Space::find()->visible();
|
||||
$query = Space::find()->visible()->filterBlockedSpaces();
|
||||
$query->search(Yii::$app->request->get('keyword'));
|
||||
|
||||
$countQuery = clone $query;
|
||||
|
@ -119,7 +119,7 @@ class Space extends ContentContainerActiveRecord implements Searchable
|
||||
[['join_policy', 'visibility', 'status', 'auto_add_new_members', 'default_content_visibility'], 'integer'],
|
||||
[['name'], 'required'],
|
||||
[['description', 'about', 'color'], 'string'],
|
||||
[['tagsField'], 'safe'],
|
||||
[['tagsField', 'blockedUsersField'], 'safe'],
|
||||
[['description'], 'string', 'max' => 100],
|
||||
[['join_policy'], 'in', 'range' => [0, 1, 2]],
|
||||
[['visibility'], 'in', 'range' => [0, 1, 2]],
|
||||
@ -146,7 +146,7 @@ class Space extends ContentContainerActiveRecord implements Searchable
|
||||
{
|
||||
$scenarios = parent::scenarios();
|
||||
|
||||
$scenarios[static::SCENARIO_EDIT] = ['name', 'color', 'description', 'about', 'tagsField', 'join_policy', 'visibility', 'default_content_visibility', 'url'];
|
||||
$scenarios[static::SCENARIO_EDIT] = ['name', 'color', 'description', 'about', 'tagsField', 'blockedUsersField', 'join_policy', 'visibility', 'default_content_visibility', 'url'];
|
||||
$scenarios[static::SCENARIO_CREATE] = ['name', 'color', 'description', 'join_policy', 'visibility'];
|
||||
$scenarios[static::SCENARIO_SECURITY_SETTINGS] = ['default_content_visibility', 'join_policy', 'visibility'];
|
||||
|
||||
@ -173,7 +173,8 @@ class Space extends ContentContainerActiveRecord implements Searchable
|
||||
'updated_at' => Yii::t('SpaceModule.base', 'Updated At'),
|
||||
'updated_by' => Yii::t('SpaceModule.base', 'Updated by'),
|
||||
'ownerUsernameSearch' => Yii::t('SpaceModule.base', 'Owner'),
|
||||
'default_content_visibility' => Yii::t('SpaceModule.base', 'Default content visibility')
|
||||
'default_content_visibility' => Yii::t('SpaceModule.base', 'Default content visibility'),
|
||||
'blockedUsersField' => Yii::t('SpaceModule.base', 'Blocked users'),
|
||||
];
|
||||
}
|
||||
|
||||
@ -360,6 +361,10 @@ class Space extends ContentContainerActiveRecord implements Searchable
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($this->isBlockedForUser(User::findOne($userId))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -49,6 +49,7 @@ class DefaultController extends Controller
|
||||
{
|
||||
$space = $this->contentContainer;
|
||||
$space->scenario = 'edit';
|
||||
$space->blockedUsersField = $space->getBlockedUserGuids();
|
||||
|
||||
if ($space->load(Yii::$app->request->post()) && $space->validate() && $space->save()) {
|
||||
RichText::postProcess($space->about, $space);
|
||||
|
@ -6,6 +6,7 @@ use humhub\modules\space\models\Space;
|
||||
use humhub\modules\space\modules\manage\widgets\DefaultMenu;
|
||||
use humhub\modules\space\widgets\SpaceNameColorInput;
|
||||
use humhub\modules\ui\form\widgets\ActiveForm;
|
||||
use humhub\modules\user\widgets\UserPickerField;
|
||||
use humhub\widgets\Button;
|
||||
|
||||
/* @var $this \humhub\modules\ui\view\components\View
|
||||
@ -31,6 +32,9 @@ use humhub\widgets\Button;
|
||||
<?= $form->field($model, 'description')->textInput(['maxlength' => 100]); ?>
|
||||
<?= $form->field($model, 'about')->widget(RichTextField::class); ?>
|
||||
<?= $form->field($model, 'tagsField')->widget(ContainerTagPicker::class, ['minInput' => 2]); ?>
|
||||
<?php if (Yii::$app->getModule('user')->allowBlockUsers()) : ?>
|
||||
<?= $form->field($model, 'blockedUsersField')->widget(UserPickerField::class, ['minInput' => 2]); ?>
|
||||
<?php endif; ?>
|
||||
|
||||
<?= Button::save()->submit() ?>
|
||||
|
||||
|
@ -0,0 +1,58 @@
|
||||
<?php
|
||||
namespace space\acceptance;
|
||||
|
||||
use space\AcceptanceTester;
|
||||
|
||||
class BlockSpacesCest
|
||||
{
|
||||
public function testBlockUsers(AcceptanceTester $I)
|
||||
{
|
||||
$I->wantTo('test users blocking for space');
|
||||
|
||||
$I->amGoingTo('check the users blocking is enabled in system by default');
|
||||
$I->amAdmin();
|
||||
$this->isUsersBlockingEnabled($I);
|
||||
|
||||
$I->amGoingTo('block some users for the space "Sara Tester"');
|
||||
$I->selectUserFromPicker('#space-blockedusersfield', 'Peter Tester');
|
||||
$I->click('Save');
|
||||
$I->seeSuccess('Saved');
|
||||
$I->see('Peter Tester', '.field-space-blockedusersfield');
|
||||
|
||||
$I->amGoingTo('check the current user "Peter Tester" is blocked for the space "Space 1"');
|
||||
$I->amUser1(true);
|
||||
$I->amOnSpace1();
|
||||
$I->see('You are blocked for this page!');
|
||||
|
||||
$I->amGoingTo('disable the users blocking');
|
||||
$I->amAdmin(true);
|
||||
$this->disableUsersBlocking($I);
|
||||
|
||||
$I->amUser1(true);
|
||||
$this->isUsersBlockingDisabled($I);
|
||||
$I->amGoingTo('be sure the Space 1 is viewable for the user "Peter Tester"');
|
||||
$I->amOnSpace1();
|
||||
$I->see('Space 1');
|
||||
}
|
||||
|
||||
private function disableUsersBlocking(AcceptanceTester $I)
|
||||
{
|
||||
$I->amOnPage('/admin/authentication');
|
||||
$I->click('[for="authenticationsettingsform-blockusers"]');
|
||||
$I->wait(1);
|
||||
$I->click('Save');
|
||||
}
|
||||
|
||||
private function isUsersBlockingDisabled(AcceptanceTester $I)
|
||||
{
|
||||
$I->amOnPage('/user/account/edit-settings');
|
||||
$I->dontSee('Blocked users');
|
||||
}
|
||||
|
||||
private function isUsersBlockingEnabled(AcceptanceTester $I)
|
||||
{
|
||||
$I->amOnSpace1('/space/manage/default/index');
|
||||
$I->see('Blocked users');
|
||||
}
|
||||
|
||||
}
|
@ -130,6 +130,10 @@ class MembershipButton extends Widget
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
if ($this->space->isBlockedForUser()) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$options = $this->getOptions();
|
||||
|
||||
if ($options['becomeMember']['mode'] == 'link') {
|
||||
|
@ -56,6 +56,7 @@ class PeopleQuery extends ActiveQueryUser
|
||||
|
||||
$this->visible();
|
||||
|
||||
$this->filterBlockedUsers();
|
||||
$this->filterByKeyword();
|
||||
$this->filterByGroup();
|
||||
$this->filterByConnection();
|
||||
|
Loading…
x
Reference in New Issue
Block a user