Merge branch 'develop' of github.com:humhub/humhub into develop

This commit is contained in:
buddh4 2019-12-20 11:03:15 +01:00
commit e71f54d6d7
30 changed files with 571 additions and 41 deletions

View File

@ -34,7 +34,6 @@ class AppAsset extends AssetBundle
* @inheritdoc
*/
public $css = [
'css/temp.css',
'css/bootstrap-wysihtml5.css',
'css/flatelements.css',
];

View File

@ -15,6 +15,7 @@ use humhub\modules\ui\form\widgets\DatePicker;
use humhub\modules\ui\form\widgets\MultiSelect;
use Yii;
use yii\helpers\Html;
use yii\widgets\ActiveForm;
/**
* HForm - Yii1 compatible form generator
@ -37,7 +38,13 @@ class HForm extends \yii\base\Component
const EVENT_BEFORE_RENDER = 'beforeRender';
public $showErrorSummary;
/**
* @var ActiveForm
*/
protected $form;
public $primaryModel = null;
public $models = [];
public $definition = [];

View File

@ -36,6 +36,15 @@ class I18N extends BaseI18N
*/
public $unsupportedYiiLanguages = ['an'];
/**
* Called before the translate method is executed.
* e.g. to modify translations on the fly.
*
* @since 1.4
* @var callable
*/
public $beforeTranslateCallback;
/**
* Automatically sets the current locale and time zone
*/
@ -131,6 +140,11 @@ class I18N extends BaseI18N
$category = 'humhub.yii';
}
if (is_callable($this->beforeTranslateCallback)) {
list($category, $message, $params, $language) =
$this->beforeTranslateCallback->call($this, $category, $message, $params, $language);
}
return parent::translate($category, $message, $params, $language);
}

View File

@ -1,8 +1,22 @@
HumHub Change Log (DEVELOP)
=================
1.4.beta2
---
1.4.0 (Unreleased)
------------
- Fix #3789: TopicPicker `addOptions` flag ignored
- Fix #3790: "Create post" permission visible in profile permissions settings for guest user group
- Fix: `AdminMenu:reset()` fails on console requests using user switch
- Fix: Default `ContentContainerController::subLayout` can't be overwritten directly or within controller `init`
- Fix #3791: Topic overview missing for user profiles
- Fix #3787: Required checkboxlist input shows asterisk on each option
- Chng: **Theme:** removed `static/temp.css`, moved required form style to `form.less`
- Enh: **Theme:** use of colored required input field asterisk
- Fix #3784: `ActiveQueryContent::readable()` not working for global content
- Chng: Removed italic text from summary mail of comment and content activities for better readability
1.4.0-beta.2
------------
- Fix #3703: Fixed user profile image dimension of mobile
- Fix #3732: Reverted changes of default oembed style

View File

@ -36,12 +36,12 @@ Available user groups in space context:
| Group | Description |
|---|---|
| \humhub\modules\user\models\User::USERGROUP_OWNER | The owner of the space |
| \humhub\modules\user\models\User::USERGROUP_ADMIN | An administrator of the space |
| \humhub\modules\user\models\User::USERGROUP_MODERATOR | A moderator of the space |
| \humhub\modules\user\models\User::USERGROUP_MEMBER | A member of the space |
| \humhub\modules\user\models\User::USERGROUP_USER | Any registered user |
| \humhub\modules\user\models\User::USERGROUP_GUEST | Any user, even unauthenticated if available |
| \humhub\modules\space\models\Space::USERGROUP_OWNER | The owner of the space |
| \humhub\modules\space\models\Space::USERGROUP_ADMIN | An administrator of the space |
| \humhub\modules\space\models\Space::USERGROUP_MODERATOR | A moderator of the space |
| \humhub\modules\space\models\Space::USERGROUP_MEMBER | A member of the space |
| \humhub\modules\space\models\Space::USERGROUP_USER | Any registered user |
| \humhub\modules\space\models\Space::USERGROUP_GUEST | Any user, even unauthenticated if available |
Core Permissions

View File

@ -4,6 +4,7 @@
- Minor changes in `notification/views/index.php`
- Refactored `widget/views/panelMenu.php`
- Use of new WallEntryControls in `modules/content/widgets/views/wallEntry.php`
- Chng: **Theme:** removed `static/temp.css`, moved required form style to `form.less`
> Note: This list may not be complete and only contains changes which could interfere with your theme in case you overwrote
> specific views. In case you notice other problems with your theme, please let us know in the community!

View File

@ -8,6 +8,7 @@
namespace humhub\modules\admin;
use humhub\components\Application;
use humhub\modules\admin\widgets\AdminMenu;
use humhub\modules\user\events\UserEvent;
use Yii;
@ -57,6 +58,8 @@ class Events extends \yii\base\BaseObject
* @param $event UserEvent
*/
public static function onSwitchUser($event) {
AdminMenu::reset();
if(Yii::$app instanceof Application) {
AdminMenu::reset();
}
}
}

View File

@ -8,6 +8,7 @@
namespace humhub\modules\admin\widgets;
use humhub\components\Application;
use Yii;
use humhub\modules\admin\permissions\ManageModules;
use humhub\modules\admin\permissions\ManageSpaces;
@ -118,6 +119,10 @@ class AdminMenu extends LeftNavigation
public static function canAccess()
{
if(!(Yii::$app instanceof Application)) {
return false;
}
$canSeeAdminSection = Yii::$app->session->get(static::SESSION_CAN_SEE_ADMIN_SECTION);
if ($canSeeAdminSection == null) {
$canSeeAdminSection = Yii::$app->user->isAdmin() ? true : self::checkNonAdminAccess();
@ -129,7 +134,9 @@ class AdminMenu extends LeftNavigation
public static function reset()
{
Yii::$app->session->remove(static::SESSION_CAN_SEE_ADMIN_SECTION);
if(Yii::$app instanceof Application) {
Yii::$app->session->remove(static::SESSION_CAN_SEE_ADMIN_SECTION);
}
}
private static function checkNonAdminAccess()

View File

@ -12,4 +12,4 @@ echo Yii::t('CommentModule.base', "{displayName} wrote a new comment ", [
?>
<br>
<em>"<?= RichText::preview($source->message); ?>"</em>
"<?= RichText::preview($source->message); ?>"

View File

@ -12,4 +12,4 @@ echo Yii::t('ContentModule.activities', '{displayName} created a new {contentTit
]);
?>
<br />
<em>"<?= RichText::preview($source->getContentDescription()); ?>"</em>
"<?= RichText::preview($source->getContentDescription()); ?>"

View File

@ -55,6 +55,7 @@ class ActiveQueryContent extends \yii\db\ActiveQuery
$this->leftJoin('user cuser', 'contentcontainer.pk=cuser.id AND contentcontainer.class=:userClass', [':userClass' => User::class]);
$conditionSpace = '';
$conditionUser = '';
$globalCondition = '';
if ($user !== null) {
$this->leftJoin('space_membership', 'contentcontainer.pk=space_membership.space_id AND contentcontainer.class=:spaceClass AND space_membership.user_id=:userId', [':userId' => $user->id, ':spaceClass' => Space::class]);
@ -77,14 +78,16 @@ class ActiveQueryContent extends \yii\db\ActiveQuery
// Created content of is always visible
$conditionUser .= 'OR content.created_by=' . $user->id;
$globalCondition .= 'content.contentcontainer_id IS NULL';
} elseif (AuthHelper::isGuestAccessEnabled()) {
$conditionSpace = 'space.id IS NOT NULL and space.visibility=' . Space::VISIBILITY_ALL . ' AND content.visibility=1';
$conditionUser = 'cuser.id IS NOT NULL and cuser.visibility=' . User::VISIBILITY_ALL . ' AND content.visibility=1';
$globalCondition .= 'content.contentcontainer_id IS NULL AND content.visibility=1';
} else {
$this->emulateExecution();
}
$this->andWhere("{$conditionSpace} OR {$conditionUser}");
$this->andWhere("{$conditionSpace} OR {$conditionUser} OR {$globalCondition}");
return $this;

View File

@ -17,7 +17,7 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*/
return [
return [
['id' => 1, 'guid' => '01e50e0d-82cd-41fc-8b0c-552392f5839c', 'class' => 'humhub\modules\user\models\User', 'pk' => '1', 'owner_user_id' => 1],
['id' => 2, 'guid' => '01e50e0d-82cd-41fc-8b0c-552392f5839d', 'class' => 'humhub\modules\user\models\User', 'pk' => '2', 'owner_user_id' => 2],
['id' => 3, 'guid' => '01e50e0d-82cd-41fc-8b0c-552392f5839e', 'class' => 'humhub\modules\user\models\User', 'pk' => '3', 'owner_user_id' => 3],
@ -29,4 +29,5 @@ return [
['id' => 9, 'guid' => '01e50e0d-82cd-41fc-8b0c-552392f5839g', 'class' => 'humhub\modules\user\models\User', 'pk' => '5', 'owner_user_id' => 5],
['id' => 10, 'guid' => '01e50e0d-82cd-41fc-8b0c-552392f5839h', 'class' => 'humhub\modules\user\models\User', 'pk' => '6', 'owner_user_id' => 6],
['id' => 11, 'guid' => '01e50e0d-82cd-41fc-8b0c-552392f5839i', 'class' => 'humhub\modules\user\models\User', 'pk' => '7', 'owner_user_id' => 7],
['id' => 12, 'guid' => '5396d499-20d6-4233-800b-c6c86e5fa34e', 'class' => 'humhub\modules\space\models\Space', 'pk' => '5', 'owner_user_id' => 1],
];

View File

@ -0,0 +1,383 @@
<?php
namespace tests\codeception\unit\modules\content;
use humhub\modules\user\models\User;
use Yii;
use tests\codeception\_support\HumHubDbTestCase;
use humhub\modules\post\models\Post;
use humhub\modules\space\models\Space;
use humhub\modules\content\models\Content;
class ReadableContentQueryTest extends HumHubDbTestCase
{
/**
* @var User
*/
private $user;
private $publicSpace;
private $privateSpace;
private $globalPublicPost;
private $globalPrivatePost;
private $publicSpacePublicPost;
private $publicSpacePrivatePost;
private $privateSpacePublicPost;
private $privateSpacePrivatePost;
private $profilePublicPost;
private $profilePrivatePost;
private $posts = [];
public function _before()
{
parent::_before();
// TODO: would be cleaner to somehow exclude this from default fixtures
foreach (Post::find()->all() as $post) {
$post->delete();
}
$this->posts = [];
// Note: User2 is moderator of Space3
// Note: User1 is member of Space3
// Note: User3 is not member of Space3
$this->becomeUser('User2');
$this->publicSpace = Space::findOne(['id' => 3]);
$this->privateSpace = Space::findOne(['id' => 5]);
$this->user = Yii::$app->user->identity;
$this->globalPrivatePost = new Post;
$this->globalPrivatePost->message = "Global Public Post";
$this->globalPrivatePost->content->visibility = Content::VISIBILITY_PRIVATE;
$this->globalPrivatePost->save();
$this->globalPublicPost = new Post;
$this->globalPublicPost->message = "Global Private Post";
$this->globalPublicPost->content->visibility = Content::VISIBILITY_PUBLIC;
$this->globalPublicPost->save();
$this->publicSpacePublicPost = new Post;
$this->publicSpacePublicPost->message = "Public Space Public Post";
$this->publicSpacePublicPost->content->visibility = Content::VISIBILITY_PUBLIC;
$this->publicSpacePublicPost->content->setContainer($this->publicSpace);
$this->publicSpacePublicPost->save();
$this->publicSpacePrivatePost = new Post;
$this->publicSpacePrivatePost->message = "Public Space Private Post";
$this->publicSpacePrivatePost->content->visibility = Content::VISIBILITY_PRIVATE;
$this->publicSpacePrivatePost->content->setContainer($this->publicSpace);
$this->publicSpacePrivatePost->save();
$this->profilePublicPost = new Post;
$this->profilePublicPost->message = "Profile Public Post";
$this->profilePublicPost->content->visibility = Content::VISIBILITY_PUBLIC;
$this->profilePublicPost->content->setContainer($this->user);
$this->profilePublicPost->save();
$this->profilePrivatePost = new Post;
$this->profilePrivatePost->message = "Profile Private Post";
$this->profilePrivatePost->content->visibility = Content::VISIBILITY_PRIVATE;
$this->profilePrivatePost->content->setContainer($this->user);
$this->profilePrivatePost->save();
// User1 is member of the private space
$this->becomeUser('User1');
// Note: public content in a private space should not exist
$this->privateSpacePublicPost = new Post;
$this->privateSpacePublicPost->message = "Private Space Public Post";
$this->privateSpacePublicPost->content->visibility = Content::VISIBILITY_PUBLIC;
$this->privateSpacePublicPost->content->setContainer($this->privateSpace);
$this->privateSpacePublicPost->save();
$this->privateSpacePrivatePost = new Post;
$this->privateSpacePrivatePost->message = "Private Space Private Post";
$this->privateSpacePrivatePost->content->visibility = Content::VISIBILITY_PRIVATE;
$this->privateSpacePrivatePost->content->setContainer($this->privateSpace);
$this->privateSpacePrivatePost->save();
}
/**
* This test queries all visible global posts for User1 (not the content owner)
* The should be able to see both global content, since he is member of the network.
*
* @throws \Throwable
* @throws \yii\base\Exception
*/
public function testGlobalContentAsMember()
{
$this->becomeUser('User1');
$posts = Post::find()->contentContainer(null)->readable()->all();
$this->assertCount(2, $posts);
$this->assertEquals($this->globalPublicPost->id, $posts[1]->id);
$this->assertEquals($this->globalPrivatePost->id, $posts[0]->id);
}
public function testGlobalContentAsGuest()
{
$this->allowGuestAccess();
$this->logout();
$this->posts = Post::find()->contentContainer(null)->readable()->all();
$this->assertPostCount(1);
$this->assertInPosts($this->globalPublicPost);
}
public function testGlobalContentGuestNonGuestMode()
{
$this->allowGuestAccess(false);
$this->logout();
$posts = Post::find()->contentContainer(null)->readable()->all();
$this->assertPostCount(0);
}
public function testPublicSpaceContentAsMember()
{
$this->becomeUser('User1');
$this->posts = Post::find()->contentContainer($this->publicSpace)->readable()->all();
$this->assertPostCount(2);
$this->assertInPosts($this->publicSpacePublicPost);
$this->assertInPosts($this->publicSpacePrivatePost);
}
public function testPublicSpaceContentAsNonMember()
{
$this->becomeUser('User3');
$this->posts = Post::find()->contentContainer($this->publicSpace)->readable()->all();
$this->assertPostCount(1);
$this->assertInPosts($this->publicSpacePublicPost);
}
public function testPublicSpaceContentAsGuest()
{
$this->allowGuestAccess(true);
$this->logout();
$this->posts = Post::find()->contentContainer($this->publicSpace)->readable()->all();
$this->assertPostCount(1);
$this->assertInPosts($this->publicSpacePublicPost);
}
public function testPublicSpaceContentAsGuestNonGuestMode()
{
$this->allowGuestAccess(false);
$this->logout();
$posts = Post::find()->contentContainer($this->publicSpace)->readable()->all();
$this->assertCount(0, $posts);
}
public function testPrivateSpaceContentAsMember()
{
$this->becomeUser('User1');
$this->posts = Post::find()->contentContainer($this->privateSpace)->readable()->all();
$this->assertPostCount(2);
$this->assertInPosts($this->privateSpacePublicPost);
$this->assertInPosts($this->privateSpacePrivatePost);
}
public function tesPrivateSpaceContentAsNonMember()
{
$this->becomeUser('User3');
$this->posts = Post::find()->contentContainer($this->privateSpace)->readable()->all();
$this->assertPostCount(0);
}
public function testPrivateSpaceContentAsGuest()
{
$this->logout();
$this->posts = Post::find()->contentContainer($this->privateSpace)->readable()->all();
$this->assertPostCount(0);
}
public function testProfileContentOfGlobalUserAsOwner()
{
$this->becomeUser('User2');
$this->user->updateAttributes(['visibility' => User::VISIBILITY_ALL]);
$this->posts = Post::find()->contentContainer($this->user)->readable()->all();
$this->assertPostCount(2);
$this->assertInPosts($this->profilePublicPost);
$this->assertInPosts($this->profilePrivatePost);
}
public function testProfileContentOfMembersOnlyUserAsOwner()
{
$this->becomeUser('User2');
$this->user->updateAttributes(['visibility' => User::VISIBILITY_REGISTERED_ONLY]);
$this->posts = Post::find()->contentContainer($this->user)->readable()->all();
$this->assertPostCount(2);
$this->assertInPosts($this->profilePublicPost);
$this->assertInPosts($this->profilePrivatePost);
}
public function testProfileContentOfGlobalUserAsMember()
{
$this->becomeUser('User1');
$this->user->updateAttributes(['visibility' => User::VISIBILITY_ALL]);
$this->posts = Post::find()->contentContainer($this->user)->readable()->all();
$this->assertPostCount(1);
$this->assertInPosts($this->profilePublicPost);
}
public function testProfileContentOfMembersOnlyUser()
{
$this->becomeUser('User1');
$this->user->updateAttributes(['visibility' => User::VISIBILITY_REGISTERED_ONLY]);
$this->posts = Post::find()->contentContainer($this->user)->readable()->all();
$this->assertPostCount(1);
$this->assertInPosts($this->profilePublicPost);
}
public function testProfileContentOfGlobalUserAsGuest()
{
$this->allowGuestAccess();
$this->user->updateAttributes(['visibility' => User::VISIBILITY_ALL]);
$this->logout();
$this->posts = Post::find()->contentContainer($this->user)->readable()->all();
$this->assertPostCount(1);
$this->assertInPosts($this->profilePublicPost);
}
public function testProfileContentOfGlobalUserAsGuestNonGuestMode()
{
$this->allowGuestAccess(false);
$this->user->updateAttributes(['visibility' => User::VISIBILITY_ALL]);
$this->logout();
$this->posts = Post::find()->contentContainer($this->user)->readable()->all();
$this->assertPostCount(0);
}
public function testProfileContentOfMembersOnlyUserAsGuest()
{
$this->allowGuestAccess();
$this->user->updateAttributes(['visibility' => User::VISIBILITY_REGISTERED_ONLY]);
$this->logout();
$this->posts = Post::find()->contentContainer($this->user)->readable()->all();
$this->assertPostCount(0);
}
public function testReadableOnlyAsMemberOfPrivateSpace()
{
$this->user->updateAttributes(['visibility' => User::VISIBILITY_ALL]);
$this->becomeUser('User1');
$this->posts = Post::find()->readable()->all();
$this->assertPostCount(7);
$this->assertInPosts($this->publicSpacePublicPost);
$this->assertInPosts($this->publicSpacePrivatePost);
$this->assertInPosts($this->privateSpacePublicPost);
$this->assertInPosts($this->privateSpacePrivatePost);
$this->assertInPosts($this->globalPrivatePost);
$this->assertInPosts($this->globalPublicPost);
$this->assertInPosts($this->profilePublicPost);
}
public function testReadableOnlyAsUserProfileOwner()
{
$this->user->updateAttributes(['visibility' => User::VISIBILITY_ALL]);
$this->becomeUser('User2');
$this->posts = Post::find()->readable()->all();
$this->assertPostCount(6);
$this->assertInPosts($this->publicSpacePublicPost);
$this->assertInPosts($this->publicSpacePrivatePost);
$this->assertInPosts($this->globalPrivatePost);
$this->assertInPosts($this->globalPublicPost);
$this->assertInPosts($this->profilePublicPost);
$this->assertInPosts($this->profilePrivatePost);
}
public function testReadableOnlyAsUserProfileOwnerWithNonMemberSpacePost()
{
// Tests if the query includes posts a user created, but is not member of the related space anymore
$this->user->updateAttributes(['visibility' => User::VISIBILITY_ALL]);
$this->becomeUser('User2');
// This could be an old post, and the user was removed from the space
$privateSpacePost = new Post;
$privateSpacePost->message = "Profile Public Post";
$privateSpacePost->content->visibility = Content::VISIBILITY_PUBLIC;
$privateSpacePost->content->setContainer($this->user);
$privateSpacePost->save();
$this->posts = Post::find()->readable()->all();
$this->assertPostCount(7);
$this->assertInPosts($this->publicSpacePublicPost);
$this->assertInPosts($this->publicSpacePrivatePost);
$this->assertInPosts($this->globalPrivatePost);
$this->assertInPosts($this->globalPublicPost);
$this->assertInPosts($this->profilePublicPost);
$this->assertInPosts($this->profilePrivatePost);
$this->assertInPosts($privateSpacePost);
}
public function testReadableOnlyAsGuest()
{
$this->allowGuestAccess();
$this->user->updateAttributes(['visibility' => User::VISIBILITY_ALL]);
$this->logout();
$this->posts = Post::find()->readable()->all();
$this->assertPostCount(3);
$this->assertInPosts($this->publicSpacePublicPost);
$this->assertInPosts($this->globalPublicPost);
$this->assertInPosts($this->profilePublicPost);
}
private function assertPostCount($count)
{
$this->assertCount($count, $this->posts);
}
private function assertInPosts($post)
{
$found = false;
foreach ($this->posts as $postResult) {
if($postResult->id === $post->id) {
$found = true;
break;
}
}
$this->assertTrue($found, "Could not find {$post->id} in result");
}
}

View File

@ -1,12 +1,15 @@
<?php
use humhub\modules\ui\icon\widgets\Icon;
use yii\helpers\Html;
/* @var $modules [] */
?>
<div class="panel-body">
<?php if (count($modules) == 0): ?>
<?php if (empty($modules)): ?>
<br>
<div><?= Yii::t('MarketplaceModule.base', 'All modules are up to date!'); ?></div>
<div class="alert alert-success"><?= Icon::get('check')?> <?= Yii::t('MarketplaceModule.base', 'All modules are up to date!'); ?></div>
<?php endif; ?>
<?php foreach ($modules as $module): ?>

View File

@ -36,7 +36,8 @@ class CreatePost extends \humhub\libs\BasePermission
protected $fixedGroups = [
Space::USERGROUP_USER,
Space::USERGROUP_GUEST,
User::USERGROUP_SELF
User::USERGROUP_SELF,
User::USERGROUP_GUEST
];
/**

View File

@ -8,6 +8,7 @@
namespace humhub\modules\space\behaviors;
use humhub\modules\content\components\ContentContainerController;
use humhub\modules\user\helpers\AuthHelper;
use Yii;
use yii\base\Behavior;
@ -24,8 +25,8 @@ use humhub\components\Controller;
* In Space scopes, this behavior will automatically attached to a contentcontainer controller.
*
* @see Space::controllerBehavior
* @see \humhub\modules\contentcontainer\components\Controller
* @property \humhub\modules\contentcontainer\components\Controller $owner the controller
* @see ContentContainerController
* @property ContentContainerController $owner the controller
*/
class SpaceController extends Behavior
{
@ -59,6 +60,10 @@ class SpaceController extends Behavior
];
}
/**
* @param $action
* @throws HttpException
*/
public function beforeAction($action)
{
$this->updateLastVisit();
@ -71,7 +76,10 @@ class SpaceController extends Behavior
throw new HttpException(404, Yii::t('SpaceModule.base', 'Space is invisible!'));
}
$this->owner->subLayout = "@humhub/modules/space/views/space/_layout";
if(empty($this->owner->subLayout)) {
$this->owner->subLayout = "@humhub/modules/space/views/space/_layout";
}
$this->owner->prependPageTitle($this->space->name);
if (Yii::$app->request->isPjax || !Yii::$app->request->isAjax) {

View File

@ -21,5 +21,6 @@ return [
['id' => '1', 'guid' => '5396d499-20d6-4233-800b-c6c86e5fa34a', 'name' => 'Space 1', 'contentcontainer_id' => '4', 'description' => 'Space by Admin', 'join_policy' => '1', 'visibility' => '1', 'status' => '1', 'tags' => null, 'created_at' => '2014-08-08 05:36:04', 'created_by' => '1', 'updated_at' => '2014-08-08 05:36:04', 'updated_by' => '1', 'ldap_dn' => null, 'auto_add_new_members' => '0'],
['id' => '2', 'guid' => '5396d499-20d6-4233-800b-c6c86e5fa34b', 'name' => 'Space 2', 'contentcontainer_id' => '5', 'description' => 'User 1 Space', 'join_policy' => '2', 'visibility' => '2', 'status' => '1', 'tags' => null, 'created_at' => '2014-08-08 05:36:04', 'created_by' => '2', 'updated_at' => '2014-08-08 05:36:04', 'updated_by' => '2', 'ldap_dn' => null, 'auto_add_new_members' => '0'],
['id' => '3', 'guid' => '5396d499-20d6-4233-800b-c6c86e5fa34c', 'name' => 'Space 3', 'contentcontainer_id' => '6', 'description' => 'Another User 1 Space', 'join_policy' => '2', 'visibility' => '2', 'status' => '1', 'tags' => null, 'created_at' => '2014-08-08 05:36:04', 'created_by' => '1', 'updated_at' => '2014-08-08 05:36:04', 'updated_by' => '2', 'ldap_dn' => null, 'auto_add_new_members' => '1'],
['id' => '4', 'guid' => '5396d499-20d6-4233-800b-c6c86e5fa34d', 'name' => 'Space 4', 'contentcontainer_id' => '7', 'description' => 'User 1/2 Space', 'join_policy' => '2', 'visibility' => '2', 'status' => '1', 'tags' => null, 'created_at' => '2014-08-08 05:36:04', 'created_by' => '1', 'updated_at' => '2014-08-08 05:36:04', 'updated_by' => '2', 'ldap_dn' => null, 'auto_add_new_members' => '1']
['id' => '4', 'guid' => '5396d499-20d6-4233-800b-c6c86e5fa34d', 'name' => 'Space 4', 'contentcontainer_id' => '7', 'description' => 'User 1/2 Space', 'join_policy' => '2', 'visibility' => '2', 'status' => '1', 'tags' => null, 'created_at' => '2014-08-08 05:36:04', 'created_by' => '1', 'updated_at' => '2014-08-08 05:36:04', 'updated_by' => '2', 'ldap_dn' => null, 'auto_add_new_members' => '1'],
['id' => '5', 'guid' => '5396d499-20d6-4233-800b-c6c86e5fa34e', 'name' => 'Space 5', 'contentcontainer_id' => '12', 'description' => 'Private Space', 'join_policy' => '0', 'visibility' => '0', 'status' => '1', 'tags' => null, 'created_at' => '2014-08-08 05:36:04', 'created_by' => '1', 'updated_at' => '2014-08-08 05:36:04', 'updated_by' => '2', 'ldap_dn' => null, 'auto_add_new_members' => '1']
];

View File

@ -25,7 +25,7 @@ return [
// User 2 is Member/Admin of Space 2
['space_id' => '2', 'user_id' => '2', 'originator_user_id' => null, 'status' => '3', 'request_message' => null, 'last_visit' => '2014-08-08 06:49:57', 'group_id' => 'admin', 'created_at' => '2014-08-08 05:36:05', 'created_by' => '1', 'updated_at' => '2014-08-08 05:36:05', 'updated_by' => '1'],
// User 1 is admin of space 3 and user 2 & 3 are members
['space_id' => '3', 'user_id' => '1', 'originator_user_id' => null, 'status' => '3', 'request_message' => null, 'last_visit' => '2014-08-08 06:49:57', 'group_id' => 'admin', 'created_at' => '2014-08-08 05:36:05', 'created_by' => '1', 'updated_at' => '2014-08-08 05:36:05', 'updated_by' => '1'],
['space_id' => '3', 'user_id' => '2', 'originator_user_id' => null, 'status' => '3', 'send_notifications' => '1', 'request_message' => null, 'last_visit' => null, 'group_id' => 'member', 'created_at' => '2014-08-10 16:55:41', 'created_by' => null, 'updated_at' => null, 'updated_by' => null],
@ -36,4 +36,7 @@ return [
['space_id' => '4', 'user_id' => '2', 'originator_user_id' => null, 'status' => '3', 'request_message' => null, 'last_visit' => null, 'group_id' => 'admin', 'created_at' => '2014-08-10 16:55:41', 'created_by' => null, 'updated_at' => null, 'updated_by' => null],
['space_id' => '4', 'user_id' => '3', 'originator_user_id' => null, 'status' => '3', 'request_message' => null, 'last_visit' => '2014-08-08 06:49:57', 'group_id' => 'member', 'created_at' => '2014-08-08 05:36:05', 'created_by' => '1', 'updated_at' => '2014-08-08 05:36:05', 'updated_by' => '1'],
['space_id' => '5', 'user_id' => '1', 'originator_user_id' => null, 'status' => '3', 'request_message' => null, 'last_visit' => '2014-08-08 06:49:57', 'group_id' => 'admin', 'created_at' => '2014-08-08 05:36:05', 'created_by' => '1', 'updated_at' => '2014-08-08 05:36:05', 'updated_by' => '1'],
['space_id' => '5', 'user_id' => '2', 'originator_user_id' => null, 'status' => '3', 'request_message' => null, 'last_visit' => '2014-08-08 06:49:57', 'group_id' => 'member', 'created_at' => '2014-08-08 05:36:05', 'created_by' => '1', 'updated_at' => '2014-08-08 05:36:05', 'updated_by' => '1'],
];

View File

@ -11,6 +11,9 @@ namespace humhub\modules\topic;
use humhub\modules\content\components\ContentActiveRecord;
use humhub\modules\topic\models\Topic;
use humhub\modules\topic\widgets\ContentTopicButton;
use humhub\modules\ui\menu\MenuLink;
use humhub\modules\user\events\UserEvent;
use humhub\modules\user\widgets\AccountMenu;
use Yii;
use yii\base\BaseObject;
@ -26,6 +29,9 @@ class Events extends BaseObject
}
}
/**
* @param $event
*/
public static function onSpaceSettingMenuInit($event)
{
$space = $event->sender->space;
@ -34,9 +40,30 @@ class Events extends BaseObject
$event->sender->addItem([
'label' => Yii::t('TopicModule.base', 'Topics'),
'url' => $space->createUrl('/topic/manage'),
'isActive' => (Yii::$app->controller->module && Yii::$app->controller->module->id == 'topic' && Yii::$app->controller->id == 'manage'),
'isActive' => MenuLink::isActiveState('topic', 'manage'),
'sortOrder' => 250
]);
}
}
/**
* @param $event UserEvent
*/
public static function onProfileSettingMenuInit($event)
{
if(Yii::$app->user->isGuest) {
return;
}
$event->sender->addItem([
'label' => Yii::t('TopicModule.base', 'Topics'),
'url' => Yii::$app->user->identity->createUrl('/topic/manage'),
'isActive' => MenuLink::isActiveState('topic', 'manage'),
'sortOrder' => 250
]);
if(MenuLink::isActiveState('topic', 'manage')) {
AccountMenu::markAsActive('account-settings-settings');
}
}
}

View File

@ -8,7 +8,7 @@
*/
use humhub\modules\content\widgets\WallEntryControls;
use humhub\modules\space\widgets\HeaderControlsMenu;
use humhub\modules\user\widgets\AccountSettingsMenu;
use humhub\modules\topic\Events;
use humhub\modules\space\modules\manage\widgets\DefaultMenu;
@ -19,5 +19,6 @@ return [
'events' => [
['class' => WallEntryControls::class, 'event' => WallEntryControls::EVENT_INIT, 'callback' => [Events::class, 'onWallEntryControlsInit']],
['class' => DefaultMenu::class, 'event' => DefaultMenu::EVENT_INIT, 'callback' => [Events::class, 'onSpaceSettingMenuInit']],
['class' => AccountSettingsMenu::class, 'event' => AccountSettingsMenu::EVENT_INIT, 'callback' => [Events::class, 'onProfileSettingMenuInit']],
],
];

View File

@ -8,6 +8,7 @@
namespace humhub\modules\topic\controllers;
use humhub\modules\user\models\User;
use humhub\widgets\ModalClose;
use humhub\modules\content\components\ContentContainerController;
use humhub\modules\topic\models\Topic;
@ -21,11 +22,21 @@ class ManageController extends ContentContainerController
public function getAccessRules()
{
return [
['login'],
['permission' => ManageTopics::class],
['json' => ['delete']]
];
}
public function init()
{
parent::init();
if($this->contentContainer instanceof User) {
$this->subLayout = "@humhub/modules/user/views/account/_layout";
}
}
public function actionIndex()
{
$model = new Topic($this->contentContainer);

View File

@ -6,13 +6,15 @@
*
*/
use humhub\modules\space\models\Space;
use humhub\modules\space\modules\manage\widgets\DefaultMenu;
use humhub\widgets\Button;
use humhub\widgets\GridView;
use humhub\widgets\ModalButton;
use yii\bootstrap\ActiveForm;
use humhub\modules\user\models\User;
use humhub\modules\user\widgets\AccountSettingsMenu;
use yii\helpers\Html;
use yii\helpers\Url;
/* @var $this \humhub\components\View */
/* @var $dataProvider \yii\data\ActiveDataProvider */
@ -21,10 +23,16 @@ use yii\helpers\Url;
?>
<div class="panel panel-default">
<div class="panel-heading"><?= Yii::t('TopicModule.base', '<strong>Topic</strong> Overview'); ?></div>
<?= DefaultMenu::widget(['space' => $contentContainer]); ?>
<?php if($contentContainer instanceof Space) :?>
<?= DefaultMenu::widget(['space' => $contentContainer]); ?>
<?php elseif ($contentContainer instanceof User) : ?>
<?= AccountSettingsMenu::widget()?>
<?php endif; ?>
<div class="panel-body">

View File

@ -42,9 +42,7 @@ class TopicPicker extends ContentTagPicker
$this->url = $this->contentContainer->createUrl('/topic/topic/search');
}
if ($this->addOptions !== false) {
$this->addOptions = $this->contentContainer->can(AddTopic::class);
}
$this->addOptions = $this->contentContainer && $this->contentContainer->can(AddTopic::class);
parent::init();
}

View File

@ -8,9 +8,11 @@
namespace humhub\modules\user\behaviors;
use humhub\modules\content\components\ContentContainerController;
use humhub\modules\user\helpers\AuthHelper;
use Yii;
use yii\base\Behavior;
use yii\base\InvalidValueException;
use yii\web\HttpException;
use humhub\modules\user\models\User;
use humhub\components\Controller;
@ -21,8 +23,8 @@ use humhub\components\Controller;
* In User container scopes, this behavior will automatically attached to a contentcontainer controller.
*
* @see User::controllerBehavior
* @see \humhub\modules\contentcontainer\components\Controller
* @property \humhub\modules\contentcontainer\components\Controller $owner the controller
* @see ContentContainerController
* @property ContentContainerController $owner the controller
*/
class ProfileController extends Behavior
{
@ -50,7 +52,7 @@ class ProfileController extends Behavior
parent::attach($owner);
if (!$this->owner->contentContainer instanceof User) {
throw new \yii\base\InvalidValueException('Invalid contentcontainer type of controller.');
throw new InvalidValueException('Invalid contentcontainer type of controller.');
}
$this->user = $this->owner->contentContainer;
@ -58,13 +60,17 @@ class ProfileController extends Behavior
/**
*
* @return type
* @return User
*/
public function getUser()
{
return $this->user;
}
/**
* @param $action
* @throws HttpException
*/
public function beforeAction($action)
{
if ($this->user->status == User::STATUS_NEED_APPROVAL) {
@ -80,7 +86,10 @@ class ProfileController extends Behavior
}
$this->owner->prependPageTitle($this->user->displayName);
$this->owner->subLayout = "@humhub/modules/user/views/profile/_layout";
if(empty($this->owner->subLayout)) {
$this->owner->subLayout = "@humhub/modules/user/views/profile/_layout";
}
}
}

View File

@ -31,6 +31,7 @@ class AccountMenu extends LeftNavigation
$this->addEntry(new MenuLink([
'label' => Yii::t('UserModule.account', 'Profile'),
'id' => 'account-settings-profile',
'icon' => 'user',
'url' => ['/user/account/edit'],
'sortOrder' => 100,
@ -39,6 +40,7 @@ class AccountMenu extends LeftNavigation
$this->addEntry(new MenuLink([
'label' => Yii::t('UserModule.account', 'E-Mail Summaries'),
'id' => 'account-settings-emailsummary',
'icon' => 'envelope',
'url' => ['/activity/user'],
'sortOrder' => 105,
@ -47,6 +49,7 @@ class AccountMenu extends LeftNavigation
$this->addEntry(new MenuLink([
'label' => Yii::t('UserModule.account', 'Notifications'),
'id' => 'account-settings-notifications',
'icon' => 'bell',
'url' => ['/notification/user'],
'sortOrder' => 106,
@ -55,6 +58,7 @@ class AccountMenu extends LeftNavigation
$this->addEntry(new MenuLink([
'label' => Yii::t('UserModule.account', 'Settings'),
'id' => 'account-settings-settings',
'icon' => 'wrench',
'url' => ['/user/account/edit-settings'],
'sortOrder' => 110,
@ -63,6 +67,7 @@ class AccountMenu extends LeftNavigation
$this->addEntry(new MenuLink([
'label' => Yii::t('UserModule.account', 'Security'),
'id' => 'account-settings-security',
'icon' => 'lock',
'url' => ['/user/account/security'],
'sortOrder' => 115,
@ -71,6 +76,7 @@ class AccountMenu extends LeftNavigation
$this->addEntry(new MenuLink([
'label' => Yii::t('UserModule.account', 'Modules'),
'id' => 'account-settings-modules',
'icon' => 'rocket',
'url' => ['/user/account/edit-modules'],
'sortOrder' => 120,

View File

@ -1,6 +1,8 @@
<?php
use yii\helpers\Html;
use yii\helpers\Url;
use humhub\widgets\Button;
print Html::a(Yii::t("UserModule.profile", "Edit account"), Url::toRoute('/user/account/edit'), ['class' => 'btn btn-primary edit-account']);
?>
<?= Button::primary(Yii::t("UserModule.profile", "Edit account"))->link(Url::toRoute('/user/account/edit'))->cssClass('edit-account')?>

View File

@ -67,4 +67,17 @@ class FooterMenu extends Menu
return $params;
}
/**
* @inheritDoc
*/
public function run()
{
// Make sure Footer on login for powered by
if (empty($this->entries) && $this->location === static::LOCATION_LOGIN) {
return $this->render($this->template, $this->getViewParams());
}
return parent::run();
}
}

View File

@ -1,3 +0,0 @@
div.required label:after {
content: " *";
}

View File

@ -7,6 +7,16 @@
margin-bottom: 0;
}
div.required > label:after {
content: " *";
color: @info;
}
div.required.has-error > label:after {
content: " *";
color: @danger;
}
.radio label,
.checkbox label {
padding-left: 10px;

File diff suppressed because one or more lines are too long