Merge branch 'v1.3-dev' of github.com:humhub/humhub into v1.3-dev

This commit is contained in:
Lucas Bartholemy 2017-10-25 15:31:35 +02:00
commit 11d8ccd6c8
69 changed files with 827 additions and 438 deletions

View File

@ -61,7 +61,7 @@ script:
- curl http://127.0.0.1:8080/index-test.php
- |
cd protected/humhub/tests/
codecept run -d
codecept run
after_failure:
- cd ../modules/user/tests/codeception/_output/
- ls

View File

@ -9,6 +9,8 @@
namespace humhub\commands;
use Yii;
use yii\web\Application;
use yii\console\Exception;
/**
* Manages application migrations.
@ -134,7 +136,7 @@ class MigrateController extends \yii\console\controllers\MigrateController
}
}
throw new \yii\console\Exception("Could not find path for: " . $migration);
throw new Exception("Could not find path for: " . $migration);
}
/**
@ -191,6 +193,7 @@ class MigrateController extends \yii\console\controllers\MigrateController
$controller->migrationPath = $migrationPath;
$controller->color = false;
$controller->runAction('up');
return ob_get_clean();
}
@ -199,7 +202,7 @@ class MigrateController extends \yii\console\controllers\MigrateController
*/
public function stdout($string)
{
if (Yii::$app instanceof \yii\web\Application) {
if (Yii::$app instanceof Application) {
print $string;
} else {
return parent::stdout($string);
@ -211,7 +214,7 @@ class MigrateController extends \yii\console\controllers\MigrateController
*/
public function stderr($string)
{
if (Yii::$app instanceof \yii\web\Application) {
if (Yii::$app instanceof Application) {
print $string;
} else {
return parent::stderr($string);

View File

@ -41,8 +41,6 @@ use yii\base\Object;
* A Validator has an unique name which is used to detect related rules and can filter out non related rules by
* means of the `filterRelatedRules()` function.
*
* Subclasses have to overwrite the `run()` function, which holds the actual validation logic.
*
* AccessValidators have access to a ControllerAccess instance, which holds the ruleset and validation state.
*
* This abstract validator class furthermore provides some helper functions as:

View File

@ -23,43 +23,89 @@ use yii\base\Object;
use yii\web\Controller;
/**
* ControllerAccess contains the actual logic to verify if a user can access a given $action.
* ControllerAccess contains the actual logic to verify whether or not a user can access a controller action by means of
* a given set of access rules.
*
* By default the AccessCheck will set the current logged in user permission object, if $user is null, we assume a guest
* user.
* By default the AccessCheck will use the current logged in user as permission subject.
*
* The guest user access can be verified by calling the `reguiresLogin()` check.
* The actual permission rule verification is handled by the [[run()]] function.
*
* Inactive users are can be catched by calling `isInActiveUser()`.
* Subclasses can extend the set of available validators by calling [[registerValidator()]] and providing a validator setting array as:
*
* The actual permission rule verification is handled by the `verify()` check, subclasses may overwrite and extend this
* function with additional checks.
*
* Subclasses can extend available validators by calling `registerValidator` and providing a validator setting array as:
*
* ```
* ```php
* public function init()
* {
* parent::init();
* $this->registerValidator([
* self::RULE_MY_CUSTOM_RULE => 'validateCustomRule',
* 'reason' => Yii::t('error', 'Guest mode not active, please login first.'),
* 'code' => 401]);
* self::RULE_MY_RULE => 'validateMyRule',
* 'reason' => Yii::t('error', 'My validation rule could not be verified.'),
* 'code' => 401
* ]);
* }
* ```
*
* The previous example registered an new validator repsonsible for validating $rules with name self::RULE_MY_CUSTOM_RULE and validation
* handler function 'validateCustomRule' which defines an handler method within the subclass.
* The previous example registered a new validator responsible for validating rules with the name `validateMyRule` and validation
* handler function `validateMyRule` which defines an handler method within the subclass.
*
* The validator can be set the following additional settings:
* Custom Validators can also be added by means of a Validator class as in the following example:
*
* - **reason**: Reason set if the validaiton fails
* - **code**: Http Code e.g. 404, 403, 401
* - **actionType**: Defines how to determine if a rule is action related by default an action rule allows the following action settings:
* ['myCustomRule' => ['action1', 'action2']] and ['myCustomRule', 'actions' => ['action1', 'action2']] but can be restricted to the second definition only by setting ACTION_SETTING_TYPE_OPTION_ONLY
* - **actionFilter**: if set to false the validations handler is always executed even if the action settings do not match with the current action (default true)
* - **strict**: if set to false only one rule of a given validator has to pass otherwise all rules have to pass (default true)
* ```php
* $this->registerValidator(MyValidator::class);
* ```
*
* where `MyValidator` is a subclass of [[\humhub\components\access\AccessValidator]]
*
* A single rule is provided as a array. If not specified otherwise, a rule supports the following base format:
*
* ```php
* ['ruleName', 'actions' => ['action1', 'action2']]
* ```
* or
*
* ```php
* ['ruleName' => ['action1', action2]]
* ```
*
* > Note: the second format is not supported by all rules e.g. permission rule
*
* If no action array is provided, the rule is considered to be controller global and will be verified for all actions.
*
* If a rule for a given name could not be found, the ControllerAccess tries to determine a custom rule validator set by the controller itself:
*
* ```php
* ['validateMyCustomRule', 'someParameter' => $value]
* ```
*
* will search for controller validator function `validateMyCustomRule`:
*
* ```php
* public function validateTestRule($rule, $access)
* {
* if($rule['someParameter'] == 'valid') {
* $access->code = 401;
* $access->reason = 'Not authorized!';
* return false;
* }
*
* return true;
* }
* ```
*
* By defining the [[fixedRules]] array property a ControllerAccess can define rules which are always applied, this property (or [[getFixedRules()]] function
* may be overwritten by subclasses.
*
* The following rules are available by default:
*
* - **admin**: The user has to be system admin to access a action
* - **permission** Group Permission check
* - **login**: The user has to be logged in to access a action
* - **strict**: Will check for guest users against the guest users allowed setting
* - **post**: Will only accept post requests for the given actions
* - **json**: Will handle json result requests by setting `Yii::$app->response->format = 'json'`
* - **disabledUser**: Checks if the given user is a disabled user **(fixed)**
* - **unapprovedUser**: Checks if the given user is a unapproved user **(fixed)**
*
* @see AccessValidator
* @since 1.2.2
*/
class ControllerAccess extends Object
@ -74,14 +120,44 @@ class ControllerAccess extends Object
*/
const ACTION_SETTING_TYPE_BOTH = 1;
/**
* Only admins have access to the given set of actions e.g.: ['admin' => ['action1']]
*/
const RULE_ADMIN_ONLY = 'admin';
/**
* Validate against a given set of permissions e.g.: ['permission' => [MyPermission::class], 'actions' => ['action1']]
*/
const RULE_PERMISSION = 'permission';
/**
* Only logged in user have access e.g.: ['login' => ['action1', 'action2']]
*/
const RULE_LOGGED_IN_ONLY = 'login';
const RULE_GUEST_CUSTOM = 'custom';
/**
* Check guest mode e.g.: ['strict'] (mainly used as global)
*/
const RULE_STRICT = 'strict';
/**
* Check guest if user is disabled
*/
const RULE_DISABLED_USER = 'disabledUser';
/**
* Check guest if user is unnapproved
*/
const RULE_UNAPPROVED_USER = 'unapprovedUser';
/**
* Check guest if request method is post
*/
const RULE_POST = 'post';
/**
* Make sure response type is json
*/
const RULE_JSON = 'json';
/**
@ -152,11 +228,20 @@ class ControllerAccess extends Object
$this->registerValidator([self::RULE_JSON => 'validateJsonResponse']);
}
/**
* @return array set of rules
*/
public function getRules()
{
return $this->rules;
}
/**
* Sets the current set of rules.
* > Note: This will merge the given set of rules with the fixed rules.
*
* @param array $rules sets th
*/
public function setRules($rules = [])
{
$this->rules = array_merge($this->getFixedRules(), $rules);
@ -176,9 +261,7 @@ class ControllerAccess extends Object
protected function registerValidator($options)
{
if(is_string($options)) {
$options = [
'class' => $options,
];
$options = ['class' => $options];
}
$options['access'] = $this;
@ -264,7 +347,7 @@ class ControllerAccess extends Object
}
/**
* Extracts the ruleName from the given $array.
* Extracts the ruleName from a given rule option array.
*
* @param $arr
* @return mixed|null

View File

@ -14,38 +14,81 @@ use humhub\components\access\ControllerAccess;
use yii\web\HttpException;
/**
* AccessControl provides basic controller access protection
* Handles the AccessControl for a Controller.
*
* Here are some examples access control settings:
* Controller level AccessRules can be provided by either setting the [[rules]] array, or by implementing a `getAccessRules()` function
* within the controller itself (prefered).
*
* Allow guest access for action 'info'
* **Examples:**
*
* ```
* [
* 'acl' => [
* 'class' => \humhub\components\behaviors\AccessControl::className(),
* 'guestAllowedActions' => ['info']
* ]
* ]
* Disable guest access for all controller actions:
*
* ```php
* public function getAccessRules()
* {
* return [
* ['login']
* ];
* }
* ```
*
* Allow access by pemission rule:
* Disable guest access for specific controller actions:
*
* ```
* [
* 'acl' => [
* 'class' => \humhub\components\behaviors\AccessControl::className(),
* 'rules' => [
* [
* 'groups' => [
* 'humhub\modules\xy\permissions\MyAccessPermssion'
* ]
* ]
* ]
* ]
* ]
* ```php
* public function getAccessRules()
* {
* return [
* ['login' => ['action1', 'action2']]
* ];
* }
* ```
*
* All users have to be logged in + additional permission check for 'action1' and 'action2':
*
* ```php
* public function getAccessRules()
* {
* return [
* ['login'],
* ['permission' => MyPermission::class, 'actions' => ['action1', 'action2']]
* ];
* }
* ```
*
* Custom inline validator for action 'action1':
*
* ```php
* public function getAccessRules()
* {
* return [
* ['validateMyCustomRule', 'someParameter' => 'someValue', 'actions' => ['action1']]
* ];
* }
*
* public function validateMyCustomRule($rule, $access)
* {
* if($rule['someParameter'] !== 'someValue') {
* $access->code = 401;
* $access->reason = 'Not authorized!';
* return false;
* }
*
* return true;
* }
*
* ```
*
* The list of available rules is given by the [[\humhub\components\access\ControllerAccess]] class set by a controller. By
* default the base [[\humhub\components\access\ControllerAccess]] class will be used.
*
* The default ControllerAccess class can be overwritten by implementing the `getAccess()` function within a controller, which should return an instance
* of ControllerAccess.
*
* > Note: You can also use the [[\humhub\components\Controller::access]] property to define a ControllerAccess class string.
*
*
*
* @see ControllerAccess
* @author luke
*/
class AccessControl extends \yii\base\ActionFilter

View File

@ -2,7 +2,7 @@
/**
* This file is generated by the "yii asset" command.
* DO NOT MODIFY THIS FILE DIRECTLY.
* @version 2017-10-21 00:16:59
* @version 2017-10-23 13:26:02
*/
return [
'all' => [

View File

@ -48,7 +48,7 @@ class ErrorController extends Controller
/**
* Show special login required view for guests
*/
if (Yii::$app->user->isGuest && $exception instanceof HttpException && $exception->statusCode == "401" && Yii::$app->getModule('user')->settings->get('auth.allowGuestAccess')) {
if (Yii::$app->user->isGuest && $exception instanceof HttpException && $exception->statusCode == '401' && Yii::$app->getModule('user')->settings->get('auth.allowGuestAccess')) {
return $this->render('@humhub/views/error/401_guests', ['message' => $message]);
}

View File

@ -10,6 +10,8 @@ namespace humhub\controllers;
use Yii;
use humhub\components\Controller;
use humhub\components\behaviors\AccessControl;
use humhub\widgets\MarkdownView;
/**
* MarkdownController provides preview for MarkdownEditorWidget
@ -27,7 +29,7 @@ class MarkdownController extends Controller
{
return [
'acl' => [
'class' => \humhub\components\behaviors\AccessControl::className(),
'class' => AccessControl::className(),
]
];
}
@ -36,7 +38,7 @@ class MarkdownController extends Controller
{
$this->forcePostRequest();
return \humhub\widgets\MarkdownView::widget(['markdown' => Yii::$app->request->post('markdown')]);
return MarkdownView::widget(['markdown' => Yii::$app->request->post('markdown')]);
}
}

View File

@ -1,13 +1,13 @@
HumHub Change Log
=================
1.2.3 (Not released yet)
--------------------------------
1.2.3 (October 23, 2017)
-------------------------
Important note for LDAP users: There is a new setting "ID Attribute" which should be set to clearly identify users.
Important note for Git/Composer installations: http://www.yiiframework.com/news/148/important-note-about-bower-and-the-asset-plugin/
- Fix: Readonly markdown field issue.
- Enh: Added flag to control automatically created social activities at content creation.
- Enh: Fixed registration approval/denial mails and made their default value configurable.
- Enh: Updated primary auth client interface for more flexibility
- Enh: Added LDAP ID attribute to improve user mapping
@ -49,7 +49,11 @@ Important note for LDAP users: There is a new setting "ID Attribute" which shoul
- Fix #2613: Wrong username encoding with pretty url (githubjeka)
- Fix #2791, #2749: Force private join policy on private spaces + non changeable post visibility
- Fix wrong Comment date issue in notification mails
- Added `data-file-*` attributes to download links, for intercepting file downloads
- Enh: Added `data-file-*` attributes to download links, for beeing able to intercept file downloads
- Enh: Added `apple-mobile-web-app-*` and `mobile-web-app-capable` meta tags to `head.php`
- Fix #2783: E-Mail notification link broken when guest mode is enabled (Buliwyfa)
- Enh: Added `ContentActiveRecord::silentContentCreation` for disabling ContentCreated Activity/Notification on ContentActiveRecord level
- Enh: Now the `NewContent` live event is always fired with `sourceClass` and `sourceId` information and a `silent` flag for silent content creations
1.2.2 (August 2, 2017)
--------------------------------
@ -149,6 +153,8 @@ Important note for LDAP users: There is a new setting "ID Attribute" which shoul
- Fix: Show more suppression entries with sort order update + equal update_at not working.
- Fix #2627: Incorrect language used in group admin user approval e-mail
- Fix #2631: Module configuration link shown for disabled modules
- Fix #2785 #2172: Added iconv PHP extension to the requirement check (leuprechtroman)
1.2.0 (April 16, 2017)
--------------------------------

View File

@ -9,6 +9,8 @@
namespace humhub\libs;
use Yii;
use yii\base\Object;
use yii\base\Exception;
use humhub\modules\space\models\Space;
/**
@ -16,7 +18,7 @@ use humhub\modules\space\models\Space;
* @author luke
*/
class BasePermission extends \yii\base\Object
class BasePermission extends Object
{
/**
@ -34,17 +36,17 @@ class BasePermission extends \yii\base\Object
/**
* @var string title of the permission
*/
protected $title = "";
protected $title ='';
/**
* @var string description of the permission
*/
protected $description = "";
protected $description = '';
/**
* @var string module id which belongs to the permission
*/
protected $moduleId = "";
protected $moduleId = '';
/**
* A list of groupIds which allowed per default.
@ -203,7 +205,7 @@ class BasePermission extends \yii\base\Object
return Yii::t('base', 'Default');
}
throw new \yii\base\Exception('Invalid permission state');
throw new Exception('Invalid permission state');
}
}

View File

@ -10,6 +10,8 @@ namespace humhub\libs;
use Yii;
use yii\base\Component;
use yii\base\Exception;
use yii\helpers\Json;
/**
* Description of SettingManager
@ -41,7 +43,7 @@ abstract class BaseSettingsManager extends Component
public function init()
{
if ($this->moduleId === null) {
throw new \Exception('Could not determine module id');
throw new Exception('Could not determine module id');
}
$this->loadValues();
@ -74,7 +76,7 @@ abstract class BaseSettingsManager extends Component
$record->value = (string) $value;
if (!$record->save()) {
throw new \yii\base\Exception("Could not store setting! (" . print_r($record->getErrors(), 1) . ")");
throw new Exception("Could not store setting! (" . print_r($record->getErrors(), 1) . ")");
}
// Store to runtime
@ -92,7 +94,7 @@ abstract class BaseSettingsManager extends Component
*/
public function setSerialized($name, $value)
{
$this->set($name, \yii\helpers\Json::encode($value));
$this->set($name, Json::encode($value));
}
/**
@ -105,7 +107,7 @@ abstract class BaseSettingsManager extends Component
{
$value = $this->get($name, $default);
if(is_string($value)) {
$value = \yii\helpers\Json::decode($value);
$value = Json::decode($value);
}
return $value;
}

View File

@ -9,6 +9,7 @@
namespace humhub\libs;
use yii\base\InvalidParamException;
use yii\base\Exception;
/**
* This class contains a lot of html helpers for the views
@ -30,7 +31,7 @@ class Helpers
if (strlen($text) > $length) {
$text = preg_replace("/^(.{1,$length})(\s.*|$)/s", '\\1...', $text);
}
$text = str_replace("<br />", "", $text);
$text = str_replace('<br />', '', $text);
return($text);
}
@ -44,7 +45,7 @@ class Helpers
$text = self::substru($text, 0, $textlength - ($textlength - $length));
$text .= '...';
}
$text = str_replace("<br />", "", $text);
$text = str_replace('<br />', '', $text);
return($text);
}
@ -64,6 +65,7 @@ class Helpers
return false;
sort($a);
sort($b);
return $a == $b;
}
@ -178,9 +180,9 @@ class Helpers
* @param string $type
* @return boolean
*/
public static function CheckClassType($className, $type = "")
public static function CheckClassType($className, $type = '')
{
$className = preg_replace('/[^a-z0-9_\-\\\]/i', "", $className);
$className = preg_replace('/[^a-z0-9_\-\\\]/i', '', $className);
if (is_array($type)) {
foreach ($type as $t) {
@ -194,7 +196,7 @@ class Helpers
}
}
throw new \yii\base\Exception("Invalid class type! (" . $className . ")");
throw new Exception("Invalid class type! (" . $className . ")");
}
/**
@ -229,6 +231,7 @@ class Helpers
$check = 0;
for ($i = 0; $i < $length; $i += 1)
$check |= (ord($a[$i]) ^ ord($b[$i]));
return $check === 0;
}

View File

@ -170,6 +170,21 @@ class SelfTest
);
}
// Checks iconv Extension
$title = 'PHP - iconv Extension';
if (function_exists('iconv_strlen')) {
$checks[] = array(
'title' => Yii::t('base', $title),
'state' => 'OK'
);
} else {
$checks[] = array(
'title' => Yii::t('base', $title),
'state' => 'ERROR',
'hint' => 'Install PHP iconv Extension'
);
}
// Checks cURL Extension
$title = 'PHP - cURL Extension';

View File

@ -9,6 +9,8 @@
namespace humhub\models;
use Yii;
use yii\db\ActiveRecord;
use yii\base\Exception;
/**
* This is the model class for table "setting".
@ -18,7 +20,7 @@ use Yii;
* @property string $value
* @property string $module_id
*/
class Setting extends \yii\db\ActiveRecord
class Setting extends ActiveRecord
{
/**
@ -176,7 +178,7 @@ class Setting extends \yii\db\ActiveRecord
$module = Yii::$app->getModule($moduleId);
}
if ($module === null) {
throw new \yii\base\Exception("Could not find module: " . $moduleId);
throw new Exception("Could not find module: " . $moduleId);
}
return $module;

View File

@ -9,17 +9,19 @@
namespace humhub\modules\activity;
use Yii;
use yii\base\Object;
use humhub\modules\activity\components\MailSummary;
use humhub\modules\activity\jobs\SendMailSummary;
use humhub\modules\activity\models\Activity;
use yii\base\Event;
use yii\db\ActiveRecord;
/**
* Events provides callbacks to handle events.
*
* @author luke
*/
class Events extends \yii\base\Object
class Events extends Object
{
/**
@ -46,7 +48,7 @@ class Events extends \yii\base\Object
*/
public static function onActiveRecordDelete(Event $event)
{
if (!($event->sender instanceof \yii\db\ActiveRecord)) {
if (!($event->sender instanceof ActiveRecord)) {
throw new \LogicException('The handler can be applied only to the \yii\db\ActiveRecord.');
}
@ -74,28 +76,28 @@ class Events extends \yii\base\Object
public static function onIntegrityCheck($event)
{
$integrityController = $event->sender;
$integrityController->showTestHeadline("Activity Module (" . Activity::find()->count() . " entries)");
$integrityController->showTestHeadline('Activity Module (' . Activity::find()->count() . ' entries)');
// Loop over all comments
foreach (Activity::find()->all() as $a) {
// Check for object_model / object_id
if ($a->object_model != "" && $a->object_id != "" && $a->getSource() === null) {
if ($integrityController->showFix("Deleting activity id " . $a->id . " without existing target! (" . $a->object_model . ")")) {
if ($a->object_model != '' && $a->object_id != '' && $a->getSource() === null) {
if ($integrityController->showFix('Deleting activity id ' . $a->id . ' without existing target! (' . $a->object_model . ')')) {
$a->delete();
}
}
// Check for moduleId is set
if ($a->module == "") {
if ($integrityController->showFix("Deleting activity id " . $a->id . " without module_id!")) {
if ($a->module == '') {
if ($integrityController->showFix('Deleting activity id ' . $a->id . ' without module_id!')) {
$a->delete();
}
}
// Check Activity class exists
if (!class_exists($a->class)) {
if ($integrityController->showFix("Deleting activity id " . $a->id . " class not exists! (" . $a->class . ")")) {
if ($integrityController->showFix('Deleting activity id ' . $a->id . ' class not exists! (' . $a->class . ')')) {
$a->delete();
}
}

View File

@ -9,6 +9,7 @@
namespace humhub\modules\activity\components;
use Yii;
use humhub\components\rendering\LayoutRenderer;
use humhub\components\rendering\Viewable;
/**
@ -26,7 +27,7 @@ use humhub\components\rendering\Viewable;
* @author buddha
* @since 1.2
*/
class ActivityWebRenderer extends \humhub\components\rendering\LayoutRenderer
class ActivityWebRenderer extends LayoutRenderer
{
/**

View File

@ -8,6 +8,10 @@
namespace humhub\modules\activity\components;
use yii\base\InvalidConfigException;
use yii\base\Exception;
use yii\db\ActiveRecord;
use humhub\components\SocialActivity;
use humhub\modules\activity\models\Activity;
use humhub\modules\content\components\ContentActiveRecord;
use humhub\modules\content\components\ContentAddonActiveRecord;
@ -18,7 +22,7 @@ use humhub\modules\content\models\Content;
*
* @author luke
*/
abstract class BaseActivity extends \humhub\components\SocialActivity
abstract class BaseActivity extends SocialActivity
{
/**
@ -42,8 +46,8 @@ abstract class BaseActivity extends \humhub\components\SocialActivity
*/
public function init()
{
if ($this->viewName == "") {
throw new \yii\base\InvalidConfigException("Missing viewName!");
if ($this->viewName == '') {
throw new InvalidConfigException('Missing viewName!');
}
parent::init();
@ -76,12 +80,12 @@ abstract class BaseActivity extends \humhub\components\SocialActivity
*/
public function create()
{
if ($this->moduleId == "") {
throw new \yii\base\InvalidConfigException("No moduleId given!");
if ($this->moduleId == '') {
throw new InvalidConfigException('No moduleId given!');
}
if (!$this->source instanceof \yii\db\ActiveRecord) {
throw new \yii\base\InvalidConfigException("Invalid source object given!");
if (!$this->source instanceof ActiveRecord) {
throw new InvalidConfigException('Invalid source object given!');
}
$this->saveModelInstance();
@ -140,11 +144,11 @@ abstract class BaseActivity extends \humhub\components\SocialActivity
$this->record->content->created_by = $this->getOriginatorId();
if ($this->record->content->created_by == null) {
throw new \yii\base\InvalidConfigException("Could not determine originator for activity!");
throw new InvalidConfigException('Could not determine originator for activity!');
}
if (!$this->record->save()) {
throw new \yii\base\Exception("Could not save activity!" . $this->record->getErrors());
throw new Exception('Could not save activity!' . $this->record->getErrors());
}
}

View File

@ -11,9 +11,12 @@ namespace humhub\modules\activity\components;
use Yii;
use yii\base\Exception;
use yii\base\Component;
use yii\helpers\Url;
use yii\db\Expression;
use humhub\modules\dashboard\components\actions\DashboardStream;
use humhub\modules\content\models\ContentContainer;
use humhub\modules\activity\models\MailSummaryForm;
use humhub\modules\activity\models\Activity;
/**
* MailSummary is send to the user with a list of new activities
@ -83,7 +86,7 @@ class MailSummary extends Component
try {
Yii::$app->view->params['showUnsubscribe'] = true;
Yii::$app->view->params['unsubscribeUrl'] = \yii\helpers\Url::to(['/activity/user'], true);
Yii::$app->view->params['unsubscribeUrl'] = Url::to(['/activity/user'], true);
$mail = Yii::$app->mailer->compose([
'html' => $this->layout,
'text' => $this->layoutPlaintext
@ -113,14 +116,14 @@ class MailSummary extends Component
protected function getSubject()
{
if ($this->interval === self::INTERVAL_DAILY) {
return Yii::t('ActivityModule.base', "Your daily summary");
return Yii::t('ActivityModule.base', 'Your daily summary');
} elseif ($this->interval === self::INTERVAL_HOURY) {
return Yii::t('ActivityModule.base', "Latest news");
return Yii::t('ActivityModule.base', 'Latest news');
} elseif ($this->interval === self::INTERVAL_WEEKLY) {
return Yii::t('ActivityModule.base', "Your weekly summary");
return Yii::t('ActivityModule.base', 'Your weekly summary');
}
return "";
return '';
}
/**
@ -155,7 +158,7 @@ class MailSummary extends Component
foreach ($stream->activeQuery->all() as $content) {
try {
$activity = $content->getPolymorphicRelation();
if ($activity instanceof \humhub\modules\activity\models\Activity) {
if ($activity instanceof Activity) {
/**
* @var $activity \humhub\modules\activity\models\Activity
*/
@ -187,7 +190,7 @@ class MailSummary extends Component
{
$lastSent = (int) Yii::$app->getModule('activity')->settings->user($this->user)->get('mailSummaryLast');
if (empty($lastSent)) {
$lastSent = new \yii\db\Expression('NOW() - INTERVAL 24 HOUR');
$lastSent = new Expression('NOW() - INTERVAL 24 HOUR');
} else {
$lastSent = date('Y-m-d G:i:s', $lastSent);
}

View File

@ -10,10 +10,11 @@ use humhub\commands\CronController;
use humhub\modules\activity\Events;
use humhub\components\ActiveRecord;
use humhub\commands\IntegrityController;
use humhub\modules\activity\Module;
return [
'id' => 'activity',
'class' => humhub\modules\activity\Module::className(),
'class' => Module::className(),
'isCoreModule' => true,
'events' => [
['class' => ActiveRecord::className(), 'event' => ActiveRecord::EVENT_BEFORE_DELETE, 'callback' => [Events::className(), 'onActiveRecordDelete']],
@ -21,4 +22,4 @@ return [
['class' => CronController::className(), 'event' => CronController::EVENT_ON_HOURLY_RUN, 'callback' => [Events::className(), 'onCronRun']],
['class' => CronController::className(), 'event' => CronController::EVENT_ON_DAILY_RUN, 'callback' => [Events::className(), 'onCronRun']],
],
];
];

View File

@ -10,6 +10,7 @@ namespace humhub\modules\activity\controllers;
use Yii;
use humhub\modules\admin\components\Controller;
use humhub\modules\admin\permissions\ManageSettings;
use humhub\modules\activity\models\MailSummaryForm;
/**
@ -26,7 +27,7 @@ class AdminController extends Controller
public function getAccessRules()
{
return [
['permissions' => \humhub\modules\admin\permissions\ManageSettings::className()]
['permissions' => ManageSettings::className()]
];
}

View File

@ -11,6 +11,7 @@ namespace humhub\modules\activity\controllers;
use Yii;
use humhub\components\Controller;
use humhub\modules\activity\models\Activity;
use humhub\components\behaviors\AccessControl;
/**
* LinkController provides link informations about an Activity via JSON.
@ -27,7 +28,7 @@ class LinkController extends Controller
{
return [
'acl' => [
'class' => \humhub\components\behaviors\AccessControl::className(),
'class' => AccessControl::className(),
'guestAllowedActions' => ['info']
]
];

View File

@ -35,7 +35,7 @@ class SendMailSummary extends ActiveJob
if ($this->interval === MailSummary::INTERVAL_DAILY || $this->interval === MailSummary::INTERVAL_HOURY || $this->interval === MailSummary::INTERVAL_WEEKLY) {
MailSummaryProcessor::process($this->interval);
} else {
Yii::error('Invalid summary interval given'. $this->interval, 'activity.job');
Yii::error('Invalid summary interval given' . $this->interval, 'activity.job');
return;
}
}

View File

@ -12,6 +12,8 @@ use Yii;
use yii\base\Exception;
use humhub\modules\content\components\ContentActiveRecord;
use humhub\modules\activity\components\ActivityWebRenderer;
use humhub\components\behaviors\PolymorphicRelation;
use yii\db\ActiveRecord;
/**
* This is the model class for table "activity".
@ -27,7 +29,7 @@ class Activity extends ContentActiveRecord
/**
* @inheritdoc
*/
public $wallEntryClass = "humhub\modules\activity\widgets\Activity";
public $wallEntryClass = 'humhub\modules\activity\widgets\Activity';
/**
* @inheritdoc
@ -39,6 +41,11 @@ class Activity extends ContentActiveRecord
*/
protected $streamChannel = 'activity';
/**
* @inheritdoc
*/
public $silentContentCreation = true;
/**
* @inheritdoc
*/
@ -46,9 +53,9 @@ class Activity extends ContentActiveRecord
{
return [
[
'class' => \humhub\components\behaviors\PolymorphicRelation::className(),
'class' => PolymorphicRelation::className(),
'mustBeInstanceOf' => [
\yii\db\ActiveRecord::className(),
ActiveRecord::className(),
]
]
];
@ -90,7 +97,7 @@ class Activity extends ContentActiveRecord
$result->record = $this; // If we include the record in createObject, it somehow loses activerecord data (id etc...)
return $result;
} else {
throw new Exception("Could not find BaseActivity " . $this->class . " for Activity Record.");
throw new Exception('Could not find BaseActivity ' . $this->class . ' for Activity Record.');
}
}

View File

@ -133,7 +133,6 @@ class MailSummaryForm extends Model
$contents = [];
foreach (Module::getConfigurableActivities() as $activity) {
#$contents[$activity->className()] = Html::tag('strong', $activity->getTitle()) . "<br />" . $activity->getDescription()."<br />";
$contents[$activity->className()] = $activity->getTitle() . ' - ' . $activity->getDescription();
}
@ -191,7 +190,7 @@ class MailSummaryForm extends Model
}
$settingsManager->set('mailSummaryInterval', $this->interval);
$settingsManager->set('mailSummaryLimitSpaces', implode(",", $this->limitSpaces));
$settingsManager->set('mailSummaryLimitSpaces', implode(',', $this->limitSpaces));
$settingsManager->set('mailSummaryLimitSpacesMode', $this->limitSpacesMode);
// We got a list of enabled activities, but we store only disabled activity class names
@ -209,7 +208,7 @@ class MailSummaryForm extends Model
public function resetUserSettings()
{
if ($this->user === null) {
throw new Exception("Could not reset settings when no user is set!");
throw new Exception('Could not reset settings when no user is set!');
}
$settingsManager = Yii::$app->getModule('activity')->settings->user($this->user);

View File

@ -5,9 +5,15 @@
* @copyright Copyright (c) 2017 HumHub GmbH & Co. KG
* @license https://www.humhub.com/licences
*/
use humhub\modules\content\components\ContentContainerController;
use humhub\modules\space\models\Space;
use humhub\modules\space\widgets\Image;
use humhub\widgets\TimeAgo;
?>
<?php if ($clickable): ?>
<?php if ($clickable) : ?>
<a href="<?= \yii\helpers\Url::to(['/activity/link', 'id' => $record->id])?>">
<?php endif; ?>
<li class="activity-entry" data-stream-entry data-action-component="activity.ActivityStreamEntry" data-content-key="<?= $record->content->id ?>">
@ -20,10 +26,10 @@
<?php endif; ?>
<!-- Show space image, if you are outside from a space -->
<?php if (!Yii::$app->controller instanceof \humhub\modules\content\components\ContentContainerController): ?>
<?php if ($record->content->container instanceof humhub\modules\space\models\Space): ?>
<?php if (!Yii::$app->controller instanceof ContentContainerController) : ?>
<?php if ($record->content->container instanceof Space) : ?>
<?=
\humhub\modules\space\widgets\Image::widget([
Image::widget([
'space' => $record->content->container,
'width' => 20,
'htmlOptions' => [
@ -38,12 +44,12 @@
<div class="media-body text-break">
<!-- Show content -->
<?= $content; ?><br/>
<?= $content; ?><br>
<!-- show time -->
<?= \humhub\widgets\TimeAgo::widget(['timestamp' => $record->content->created_at]); ?>
<?= TimeAgo::widget(['timestamp' => $record->content->created_at]); ?>
</div>
</div>
</li>
<?php if ($clickable): ?></a>
<?php if ($clickable) : ?></a>
<?php endif; ?>

View File

@ -8,8 +8,8 @@
namespace humhub\modules\activity\widgets;
use humhub\modules\content\widgets\WallEntry;
use Yii;
use humhub\modules\content\widgets\WallEntry;
use humhub\modules\content\components\ContentActiveRecord;
use humhub\modules\content\components\ContentAddonActiveRecord;
@ -56,7 +56,7 @@ class Activity extends WallEntry
// When element is assigned to a workspace, assign variable
$space = null;
if ($this->activity->content->space_id != "") {
if ($this->activity->content->space_id != '') {
$space = $this->activity->content->space;
}
@ -64,13 +64,13 @@ class Activity extends WallEntry
$user = $this->activity->content->user;
if ($user == null) {
Yii::warning("Skipping activity without valid user", "warning");
Yii::warning('Skipping activity without valid user', 'warning');
return;
}
// Dertermine View
if ($this->activity->module == "") {
if ($this->activity->module == '') {
$view = '@humhub/modules/activity/views/activities/' . $this->activity->type;
} else {
$module = Yii::$app->getModule($this->activity->module, true);
@ -83,13 +83,13 @@ class Activity extends WallEntry
// Activity Layout can access it
$this->wallEntryId = $wallEntryId;
return $this->render($view, array(
return $this->render($view, [
'activity' => $this->activity,
'wallEntryId' => $wallEntryId,
'user' => $user,
'target' => $source,
'space' => $space,
));
]);
}
}

View File

@ -8,7 +8,10 @@
namespace humhub\modules\activity\widgets;
use yii\base\Widget;
use yii\web\HttpException;
use yii\helpers\Url;
use humhub\modules\stream\actions\Stream;
/**
* ActivityStreamWidget shows an stream/wall of activities inside a sidebar.
@ -17,7 +20,7 @@ use yii\web\HttpException;
* @package humhub.modules_core.activity
* @since 0.5
*/
class Stream extends \yii\base\Widget
class Stream extends Widget
{
/**
* Optional content container if this stream belongs to one
@ -50,7 +53,7 @@ class Stream extends \yii\base\Widget
public function run()
{
$streamUrl = $this->getStreamUrl();
$infoUrl = \yii\helpers\Url::to(['/activity/link/info', 'id' => '-id-']);
$infoUrl = Url::to(['/activity/link/info', 'id' => '-id-']);
return $this->render('activityStream', [
'streamUrl' => $streamUrl,
@ -61,14 +64,14 @@ class Stream extends \yii\base\Widget
protected function getStreamUrl()
{
$params = [
'mode' => \humhub\modules\stream\actions\Stream::MODE_ACTIVITY,
'mode' => Stream::MODE_ACTIVITY,
];
if ($this->contentContainer) {
return $this->contentContainer->createUrl($this->streamAction, $params);
}
return \yii\helpers\Url::to(array_merge([$this->streamAction], $params));
return Url::to(array_merge([$this->streamAction], $params));
}
}

View File

@ -2,13 +2,15 @@
/**
* @link https://www.humhub.org/
* @copyright Copyright (c) 2016 HumHub GmbH & Co. KG
* @copyright Copyright (c) 2017 HumHub GmbH & Co. KG
* @license https://www.humhub.com/licences
*/
namespace humhub\modules\admin\controllers;
use Yii;
use yii\web\HttpException;
use yii\db\Query;
use humhub\modules\admin\components\Controller;
use humhub\modules\user\models\Group;
use humhub\modules\user\models\GroupUser;
@ -16,6 +18,9 @@ use humhub\modules\user\models\forms\EditGroupForm;
use humhub\modules\user\models\UserPicker;
use humhub\modules\user\models\User;
use humhub\modules\admin\models\forms\AddGroupMemberForm;
use humhub\modules\admin\permissions\ManageGroups;
use humhub\modules\admin\models\GroupSearch;
use humhub\modules\admin\models\UserSearch;
/**
* Group Administration Controller
@ -44,7 +49,7 @@ class GroupController extends Controller
public function getAccessRules()
{
return [
['permissions' => \humhub\modules\admin\permissions\ManageGroups::className()]
['permissions' => ManageGroups::className()]
];
}
@ -53,7 +58,7 @@ class GroupController extends Controller
*/
public function actionIndex()
{
$searchModel = new \humhub\modules\admin\models\GroupSearch();
$searchModel = new GroupSearch();
$dataProvider = $searchModel->search(Yii::$app->request->queryParams);
return $this->render('index', [
@ -104,7 +109,7 @@ class GroupController extends Controller
Yii::$app->response->format = 'json';
$permission = Yii::$app->user->permissionManager->getById(Yii::$app->request->post('permissionId'), Yii::$app->request->post('moduleId'));
if ($permission === null) {
throw new \yii\web\HttpException(500, 'Could not find permission!');
throw new HttpException(500, 'Could not find permission!');
}
Yii::$app->user->permissionManager->setGroupState($group->id, $permission, Yii::$app->request->post('state'));
return [];
@ -116,7 +121,7 @@ class GroupController extends Controller
public function actionManageGroupUsers()
{
$group = Group::findOne(['id' => Yii::$app->request->get('id')]);
$searchModel = new \humhub\modules\admin\models\UserSearch();
$searchModel = new UserSearch();
$searchModel->query = $group->getUsers();
$dataProvider = $searchModel->search(Yii::$app->request->queryParams);
return $this->render('members', [
@ -156,7 +161,7 @@ class GroupController extends Controller
$group = Group::findOne(['id' => Yii::$app->request->get('id')]);
if ($group == null) {
throw new \yii\web\HttpException(404, Yii::t('AdminModule.controllers_GroupController', 'Group not found!'));
throw new HttpException(404, Yii::t('AdminModule.controllers_GroupController', 'Group not found!'));
}
//Double check to get sure we don't remove the admin group
@ -175,18 +180,17 @@ class GroupController extends Controller
$value = Yii::$app->request->post('value');
if ($group == null) {
throw new \yii\web\HttpException(404, Yii::t('AdminModule.controllers_GroupController', 'Group not found!'));
throw new HttpException(404, Yii::t('AdminModule.controllers_GroupController', 'Group not found!'));
} else if ($value == null) {
throw new \yii\web\HttpException(400, Yii::t('AdminModule.controllers_GroupController', 'No value found!'));
throw new HttpException(400, Yii::t('AdminModule.controllers_GroupController', 'No value found!'));
}
$groupUser = $group->getGroupUser(User::findOne(Yii::$app->request->post('userId')));
if ($groupUser == null) {
throw new \yii\web\HttpException(404, Yii::t('AdminModule.controllers_GroupController', 'Group user not found!'));
throw new HttpException(404, Yii::t('AdminModule.controllers_GroupController', 'Group user not found!'));
}
$groupUser->is_group_manager = ($value) ? true : false;
$groupUser->save();
@ -214,7 +218,7 @@ class GroupController extends Controller
$keyword = Yii::$app->request->get('keyword');
$group = Group::findOne(Yii::$app->request->get('id'));
$subQuery = (new \yii\db\Query())->select('*')->from(GroupUser::tableName(). ' g')->where([
$subQuery = (new Query())->select('*')->from(GroupUser::tableName(). ' g')->where([
'and', 'g.user_id=user.id', ['g.group_id' => $group->id]]);
$query = User::find()->where(['not exists', $subQuery]);

View File

@ -19,6 +19,7 @@ use humhub\modules\admin\models\forms\UserEditForm;
use humhub\modules\admin\permissions\ManageUsers;
use humhub\modules\admin\permissions\ManageGroups;
use humhub\modules\admin\permissions\ManageSettings;
use humhub\modules\space\models\Membership;
/**
* User management
@ -90,7 +91,7 @@ class UserController extends Controller
$user->initGroupSelection();
if ($user == null) {
throw new \yii\web\HttpException(404, Yii::t('AdminModule.controllers_UserController', 'User not found!'));
throw new HttpException(404, Yii::t('AdminModule.controllers_UserController', 'User not found!'));
}
$user->scenario = 'editAdmin';
@ -123,7 +124,7 @@ class UserController extends Controller
'data-placeholder' => Yii::t('AdminModule.controllers_UserController', 'Select Groups'),
'data-placeholder-more' => Yii::t('AdminModule.controllers_UserController', 'Add Groups...')
],
'isVisible' => Yii::$app->user->can(new \humhub\modules\admin\permissions\ManageGroups())
'isVisible' => Yii::$app->user->can(new ManageGroups())
],
'status' => [
'type' => 'dropdownlist',
@ -224,7 +225,7 @@ class UserController extends Controller
if ($doit == 2) {
$this->forcePostRequest();
foreach (\humhub\modules\space\models\Membership::GetUserSpaces($user->id) as $space) {
foreach (Membership::GetUserSpaces($user->id) as $space) {
if ($space->isSpaceOwner($user->id)) {
$space->addMember(Yii::$app->user->id);
$space->setSpaceOwner(Yii::$app->user->id);

View File

@ -8,14 +8,17 @@
namespace humhub\modules\admin\models\forms;
use yii\base\Model;
use yii\web\HttpException;
use humhub\modules\user\models\User;
use humhub\modules\user\models\Group;
/**
* Description of UserGroupForm
*
* @author buddha
*/
class AddGroupMemberForm extends \yii\base\Model
class AddGroupMemberForm extends Model
{
/**
@ -69,7 +72,7 @@ class AddGroupMemberForm extends \yii\base\Model
$group = $this->getGroup();
if($group == null) {
throw new \yii\web\HttpException(404, Yii::t('AdminModule.models_form_AddGroupMemberForm', 'Group not found!'));
throw new HttpException(404, Yii::t('AdminModule.models_form_AddGroupMemberForm', 'Group not found!'));
}
foreach ($this->userGuids as $userGuid) {
@ -84,6 +87,6 @@ class AddGroupMemberForm extends \yii\base\Model
public function getGroup()
{
return \humhub\modules\user\models\Group::findOne($this->groupId);
return Group::findOne($this->groupId);
}
}

View File

@ -8,21 +8,25 @@
namespace humhub\modules\admin\widgets;
use humhub\modules\admin\models\UserApprovalSearch;
use humhub\modules\user\models\Invite;
use Yii;
use yii\helpers\Url;
use humhub\modules\admin\models\UserApprovalSearch;
use humhub\modules\admin\permissions\ManageUsers;
use humhub\modules\admin\permissions\ManageGroups;
use humhub\modules\admin\permissions\ManageSettings;
use humhub\modules\user\models\Invite;
use humhub\widgets\BaseMenu;
/**
* User Administration Menu
*
* @author Basti
*/
class UserMenu extends \humhub\widgets\BaseMenu
class UserMenu extends BaseMenu
{
public $template = "@humhub/widgets/views/tabMenu";
public $type = "adminUserSubNavigation";
public $template = '@humhub/widgets/views/tabMenu';
public $type = 'adminUserSubNavigation';
public function init()
{
@ -32,8 +36,8 @@ class UserMenu extends \humhub\widgets\BaseMenu
'sortOrder' => 100,
'isActive' => (Yii::$app->controller->module && Yii::$app->controller->module->id == 'admin' && (Yii::$app->controller->id == 'user' || Yii::$app->controller->id == 'pending-registrations')),
'isVisible' => Yii::$app->user->can([
new \humhub\modules\admin\permissions\ManageUsers(),
new \humhub\modules\admin\permissions\ManageGroups(),
new ManageUsers(),
new ManageGroups(),
])
]);
@ -43,7 +47,7 @@ class UserMenu extends \humhub\widgets\BaseMenu
'sortOrder' => 200,
'isActive' => (Yii::$app->controller->module && Yii::$app->controller->module->id == 'admin' && Yii::$app->controller->id == 'authentication'),
'isVisible' => Yii::$app->user->can([
new \humhub\modules\admin\permissions\ManageSettings()
new ManageSettings()
])
]);
@ -55,8 +59,8 @@ class UserMenu extends \humhub\widgets\BaseMenu
'sortOrder' => 300,
'isActive' => (Yii::$app->controller->module && Yii::$app->controller->module->id == 'admin' && Yii::$app->controller->id == 'approval'),
'isVisible' => Yii::$app->user->can([
new \humhub\modules\admin\permissions\ManageUsers(),
new \humhub\modules\admin\permissions\ManageGroups()
new ManageUsers(),
new ManageGroups()
])
]);
}
@ -67,7 +71,7 @@ class UserMenu extends \humhub\widgets\BaseMenu
'sortOrder' => 400,
'isActive' => (Yii::$app->controller->module && Yii::$app->controller->module->id == 'admin' && Yii::$app->controller->id == 'user-profile'),
'isVisible' => Yii::$app->user->can([
new \humhub\modules\admin\permissions\ManageUsers()
new ManageUsers()
])
]);
@ -77,7 +81,7 @@ class UserMenu extends \humhub\widgets\BaseMenu
'sortOrder' => 500,
'isActive' => (Yii::$app->controller->module && Yii::$app->controller->module->id == 'admin' && Yii::$app->controller->id == 'group'),
'isVisible' => Yii::$app->user->can(
new \humhub\modules\admin\permissions\ManageGroups()
new ManageGroups()
)
]);

View File

@ -2,16 +2,20 @@
/**
* @link https://www.humhub.org/
* @copyright Copyright (c) 2015 HumHub GmbH & Co. KG
* @copyright Copyright (c) 2017 HumHub GmbH & Co. KG
* @license https://www.humhub.com/licences
*/
namespace humhub\modules\comment\controllers;
use Yii;
use humhub\modules\comment\models\Comment;
use \humhub\modules\comment\widgets\ShowMore;
use yii\data\Pagination;
use yii\web\HttpException;
use humhub\modules\content\components\ContentAddonController;
use humhub\components\behaviors\AccessControl;
use humhub\modules\comment\models\Comment;
use humhub\modules\comment\widgets\Comment as CommentWidget;
use humhub\modules\comment\widgets\ShowMore;
/**
* CommentController provides all comment related actions.
@ -19,7 +23,7 @@ use yii\web\HttpException;
* @package humhub.modules_core.comment.controllers
* @since 0.5
*/
class CommentController extends \humhub\modules\content\components\ContentAddonController
class CommentController extends ContentAddonController
{
/**
@ -29,7 +33,7 @@ class CommentController extends \humhub\modules\content\components\ContentAddonC
{
return [
'acl' => [
'class' => \humhub\components\behaviors\AccessControl::className(),
'class' => AccessControl::className(),
'guestAllowedActions' => ['show']
]
];
@ -49,7 +53,7 @@ class CommentController extends \humhub\modules\content\components\ContentAddonC
'object_id' => $content->getPrimaryKey(),
]);
$pagination = new \yii\data\Pagination([
$pagination = new Pagination([
'totalCount' => Comment::GetCommentCount($content->className(), $content->getPrimaryKey()),
'pageSize' => $this->module->commentsBlockLoadSize
]);
@ -59,7 +63,7 @@ class CommentController extends \humhub\modules\content\components\ContentAddonC
$output = ShowMore::widget(['pagination' => $pagination, 'object' => $content]);
foreach ($comments as $comment) {
$output .= \humhub\modules\comment\widgets\Comment::widget(['comment' => $comment]);
$output .= CommentWidget::widget(['comment' => $comment]);
}
if (Yii::$app->request->get('mode') == 'popup') {
@ -87,7 +91,6 @@ class CommentController extends \humhub\modules\content\components\ContentAddonC
$message = Yii::$app->request->post('message');
$files = Yii::$app->request->post('fileList');
if (empty(trim($message)) && empty($files)) {
// do not create empty comments
return '';
@ -101,7 +104,7 @@ class CommentController extends \humhub\modules\content\components\ContentAddonC
// Reload comment to get populated created_at field
$comment->refresh();
return $this->renderAjaxContent(\humhub\modules\comment\widgets\Comment::widget(['comment' => $comment]));
return $this->renderAjaxContent(CommentWidget::widget(['comment' => $comment]));
}
public function actionEdit()
@ -117,17 +120,17 @@ class CommentController extends \humhub\modules\content\components\ContentAddonC
// Reload comment to get populated updated_at field
$this->contentAddon = Comment::findOne(['id' => $this->contentAddon->id]);
return $this->renderAjaxContent(\humhub\modules\comment\widgets\Comment::widget([
return $this->renderAjaxContent(CommentWidget::widget([
'comment' => $this->contentAddon,
'justEdited' => true
]));
}
return $this->renderAjax('edit', array(
return $this->renderAjax('edit', [
'comment' => $this->contentAddon,
'contentModel' => $this->contentAddon->object_model,
'contentId' => $this->contentAddon->object_id
));
]);
}
public function actionLoad()
@ -138,7 +141,7 @@ class CommentController extends \humhub\modules\content\components\ContentAddonC
throw new HttpException(403, Yii::t('CommentModule.controllers_CommentController', 'Access denied!'));
}
return $this->renderAjaxContent(\humhub\modules\comment\widgets\Comment::widget(['comment' => $this->contentAddon]));
return $this->renderAjaxContent(CommentWidget::widget(['comment' => $this->contentAddon]));
}
/**

View File

@ -18,4 +18,5 @@ return array (
',
'{displayName} just commented your {contentTitle} in space {space}' => '{displayName} kommentierte gerade deinen {contentTitle} im Space {space}
',
'[Deleted]' => '[Gelöscht]'
);

View File

@ -156,6 +156,10 @@ class NewComment extends \humhub\modules\notification\components\BaseNotificatio
{
$contentInfo = $this->getContentInfo($this->getCommentedRecord());
if (!$contentInfo) {
$contentInfo = Yii::t('CommentModule.notification', "[Deleted]");
}
if ($this->groupCount > 1) {
return Yii::t('CommentModule.notification', "{displayNames} commented {contentTitle}.", [
'displayNames' => $this->getGroupUserDisplayNames(),
@ -175,7 +179,12 @@ class NewComment extends \humhub\modules\notification\components\BaseNotificatio
*/
public function getCommentedRecord()
{
return $this->source->getCommentedRecord();
$source = $this->source;
if (is_null($source)) {
//This prevents the error, but we need to clean the database
return null;
} else {
return $source->getCommentedRecord();
}
}
}

View File

@ -8,16 +8,15 @@
namespace humhub\modules\content\components;
use Yii;
use yii\base\Exception;
use humhub\modules\content\widgets\WallEntry;
use humhub\widgets\Label;
use Yii;
use humhub\libs\BasePermission;
use humhub\modules\content\permissions\ManageContent;
use yii\base\Exception;
use humhub\components\ActiveRecord;
use humhub\modules\content\models\Content;
use humhub\modules\content\interfaces\ContentOwner;
use yii\base\Widget;
/**
* ContentActiveRecord is the base ActiveRecord [[\yii\db\ActiveRecord]] for Content.
@ -84,6 +83,15 @@ class ContentActiveRecord extends ActiveRecord implements ContentOwner
*/
protected $managePermission = ManageContent::class;
/**
* If set to true this flag will prevent default ContentCreated Notifications and Activities.
* This can be used e.g. for sub content entries, whose creation is not worth mentioning.
*
* @var bool
* @since 1.2.3
*/
public $silentContentCreation = false;
/**
* ContentActiveRecord constructor accepts either an configuration array as first argument or an ContentContainerActiveRecord
* and visibility settings.
@ -99,6 +107,7 @@ class ContentActiveRecord extends ActiveRecord implements ContentOwner
* or
*
* `$model = new MyContent($space1, ['myField' => 'value']);`
*
* @param array|ContentContainerActiveRecord $contentContainer either the configuration or contentcontainer
* @param int $visibility
* @param array $config

View File

@ -9,7 +9,10 @@
namespace humhub\modules\content\components;
use Yii;
use humhub\components\Controller;
use yii\web\HttpException;
use yii\base\Exception;
use humhub\libs\Helpers;
/**
@ -23,7 +26,7 @@ use yii\web\HttpException;
* @author luke
* @version 0.11
*/
class ContentAddonController extends \humhub\components\Controller
class ContentAddonController extends Controller
{
/**
@ -83,7 +86,7 @@ class ContentAddonController extends \humhub\components\Controller
throw new HttpException(500, 'Model & ID parameter required!');
}
\humhub\libs\Helpers::CheckClassType($modelClass, array(ContentAddonActiveRecord::className(), ContentActiveRecord::className()));
Helpers::CheckClassType($modelClass, [ContentAddonActiveRecord::className(), ContentActiveRecord::className()]);
$target = $modelClass::findOne(['id' => $pk]);
if ($target === null) {
@ -116,8 +119,8 @@ class ContentAddonController extends \humhub\components\Controller
*/
public function loadContentAddon($className, $pk)
{
if (!\humhub\libs\Helpers::CheckClassType($className, ContentAddonActiveRecord::className())) {
throw new \yii\base\Exception("Given className is not a content addon model!");
if (!Helpers::CheckClassType($className, ContentAddonActiveRecord::className())) {
throw new Exception("Given className is not a content addon model!");
}
$target = $className::findOne(['id' => $pk]);

View File

@ -10,6 +10,7 @@ namespace humhub\modules\content\components\behaviors;
use Yii;
use yii\base\Behavior;
use yii\base\Exception;
/**
* Settings is a helper for deprecated methods getSetting/setSetting of Space/User Model
@ -30,7 +31,7 @@ class SettingsBehavior extends Behavior
* @param String $default value when no setting exists
* @return String
*/
public function getSetting($name, $moduleId = "core", $default = "")
public function getSetting($name, $moduleId = 'core', $default = '')
{
$value = $this->getModule($moduleId)->settings->contentContainer($this->owner)->get($name);
if ($value === null) {
@ -68,7 +69,7 @@ class SettingsBehavior extends Behavior
}
if ($app === null) {
throw new \Exception('Could not find module for setting manager: ' . $moduleId);
throw new Exception('Could not find module for setting manager: ' . $moduleId);
}
return $app;

View File

@ -38,4 +38,19 @@ class NewContent extends LiveEvent
*/
public $originator;
/**
* @var string class of the ContentActiveRecord
*/
public $sourceClass;
/**
* @var int id of the ContentActiveRecord
*/
public $sourceId;
/**
* @var boolean if true it's meant to be a silent content creation
*/
public $silent;
}

View File

@ -76,6 +76,7 @@ class Content extends ContentDeprecated
/**
* @var bool flag to disable the creation of default social activities like activity and notifications in afterSave() at content creation.
* @deprecated since v1.2.3 use ContentActiveRecord::silentContentCreation instead.
*/
public $muteDefaultSocialActivities = false;
@ -173,41 +174,61 @@ class Content extends ContentDeprecated
*/
public function afterSave($insert, $changedAttributes)
{
/* @var $contentSource ContentActiveRecord */
$contentSource = $this->getPolymorphicRelation();
foreach ($this->notifyUsersOfNewContent as $user) {
$contentSource->follow($user->id);
}
if ($insert && !$contentSource instanceof \humhub\modules\activity\models\Activity) {
// TODO: handle ContentCreated notifications and live events for global content
if ($insert && !$this->isMuted()) {
$this->notifyContentCreated();
}
if (!$this->muteDefaultSocialActivities && $this->container !== null) {
$notifyUsers = array_merge($this->notifyUsersOfNewContent, Yii::$app->notification->getFollowers($this));
\humhub\modules\content\notifications\ContentCreated::instance()
->from($this->user)
->about($contentSource)
->sendBulk($notifyUsers);
\humhub\modules\content\activities\ContentCreated::instance()
->from($this->user)
->about($contentSource)->save();
Yii::$app->live->send(new \humhub\modules\content\live\NewContent([
'sguid' => ($this->container instanceof Space) ? $this->container->guid : null,
'uguid' => ($this->container instanceof User) ? $this->container->guid : null,
'originator' => $this->user->guid,
'contentContainerId' => $this->container->contentContainerRecord->id,
'visibility' => $this->visibility,
'contentId' => $this->id
]));
}
if($this->container) {
Yii::$app->live->send(new \humhub\modules\content\live\NewContent([
'sguid' => ($this->container instanceof Space) ? $this->container->guid : null,
'uguid' => ($this->container instanceof User) ? $this->container->guid : null,
'originator' => $this->user->guid,
'contentContainerId' => $this->container->contentContainerRecord->id,
'visibility' => $this->visibility,
'sourceClass' => $contentSource->className(),
'sourceId' => $contentSource->getPrimaryKey(),
'silent' => $this->isMuted(),
'contentId' => $this->id
]));
}
return parent::afterSave($insert, $changedAttributes);
}
/**
* @return bool checks if the given content allows content creation notifications and activities
*/
private function isMuted()
{
return $this->getPolymorphicRelation()->silentContentCreation || $this->muteDefaultSocialActivities || !$this->container;
}
/**
* Notifies all followers and manually set $notifyUsersOfNewContent of the creation of this content and creates an activity.
*/
private function notifyContentCreated()
{
$contentSource = $this->getPolymorphicRelation();
$notifyUsers = array_merge($this->notifyUsersOfNewContent, Yii::$app->notification->getFollowers($this));
\humhub\modules\content\notifications\ContentCreated::instance()
->from($this->user)
->about($contentSource)
->sendBulk($notifyUsers);
\humhub\modules\content\activities\ContentCreated::instance()
->from($this->user)
->about($contentSource)->save();
}
/**
* @inheritdoc
*/
@ -268,7 +289,7 @@ class Content extends ContentDeprecated
public function pin()
{
$this->pinned = 1;
//This prevents the call of beforesave, and the setting of update_at
//This prevents the call of beforeSave, and the setting of update_at
$this->updateAttributes(['pinned']);
}

View File

@ -31,6 +31,34 @@ class ContentCreatedTest extends HumHubDbTestCase
$this->assertMailSent(1, 'ContentCreated Notification Mail sent');
}
public function testSilentContentCreation()
{
$this->becomeUser('User2');
$post = new Post(['message' => 'MyTestContent']);
$post->silentContentCreation = true;
$post->content->setContainer(Space::findOne(['id' => 2]));
$post->content->visibility = Content::VISIBILITY_PUBLIC;
$post->save();
// Note Admin is following Space2 so we expect one notification mail.
$this->assertMailSent(0, 'ContentCreated Notification Mail not sent');
}
public function testMuteContentNotifications()
{
$this->becomeUser('User2');
$post = new Post(['message' => 'MyTestContent']);
$post->content->setContainer(Space::findOne(['id' => 2]));
$post->content->visibility = Content::VISIBILITY_PUBLIC;
$post->content->muteDefaultSocialActivities = true;
$post->save();
// Note Admin is following Space2 so we expect one notification mail.
$this->assertMailSent(0, 'ContentCreated Notification Mail not sent');
}
/**
* Disable mail notifications for a follower.
*/

View File

@ -2,13 +2,14 @@
/**
* @link https://www.humhub.org/
* @copyright Copyright (c) 2016 HumHub GmbH & Co. KG
* @copyright Copyright (c) 2017 HumHub GmbH & Co. KG
* @license https://www.humhub.com/licences
*/
namespace humhub\modules\file\components;
use Yii;
use yii\base\Component;
use humhub\modules\file\models\File;
use humhub\modules\file\libs\ImageConverter;
use humhub\modules\file\libs\FileHelper;
@ -19,7 +20,7 @@ use humhub\modules\file\libs\FileHelper;
* @since 1.2
* @author Luke
*/
class StorageManager extends \yii\base\Component implements StorageManagerInterface
class StorageManager extends Component implements StorageManagerInterface
{
/**
@ -65,6 +66,7 @@ class StorageManager extends \yii\base\Component implements StorageManagerInterf
$variants[] = $file;
}
}
return $variants;
}

View File

@ -9,6 +9,7 @@
namespace humhub\modules\friendship\controllers;
use Yii;
use yii\web\HttpException;
use humhub\modules\user\models\User;
use humhub\modules\friendship\models\Friendship;
use humhub\components\Controller;
@ -30,12 +31,13 @@ class ListController extends Controller
{
$user = User::findOne(['id' => Yii::$app->request->get('userId')]);
if ($user === null) {
throw new \yii\web\HttpException(404, 'Could not find user!');
throw new HttpException(404, 'Could not find user!');
}
$query = Friendship::getFriendsQuery($user);
$title = '<strong>' . Yii::t('FriendshipModule.base', "Friends") . '</strong>';
$title = '<strong>' . Yii::t('FriendshipModule.base', 'Friends') . '</strong>';
return $this->renderAjaxContent(UserListBox::widget(['query' => $query, 'title' => $title]));
}

View File

@ -9,6 +9,7 @@
namespace humhub\modules\friendship\controllers;
use Yii;
use yii\web\HttpException;
use humhub\modules\user\models\User;
use humhub\components\Controller;
use humhub\modules\friendship\models\Friendship;
@ -31,7 +32,7 @@ class RequestController extends Controller
$friend = User::findOne(['id' => Yii::$app->request->get('userId')]);
if ($friend === null) {
throw new \yii\web\HttpException(404, 'User not found!');
throw new HttpException(404, 'User not found!');
}
Friendship::add(Yii::$app->user->getIdentity(), $friend);
@ -49,7 +50,7 @@ class RequestController extends Controller
$friend = User::findOne(['id' => Yii::$app->request->get('userId')]);
if ($friend === null) {
throw new \yii\web\HttpException(404, 'User not found!');
throw new HttpException(404, 'User not found!');
}
Friendship::cancel(Yii::$app->user->getIdentity(), $friend);

View File

@ -2,7 +2,7 @@
/**
* @link https://www.humhub.org/
* @copyright Copyright (c) 2015 HumHub GmbH & Co. KG
* @copyright Copyright (c) 2017 HumHub GmbH & Co. KG
* @license https://www.humhub.com/licences
*/
@ -11,6 +11,9 @@ namespace humhub\modules\installer;
use Yii;
use yii\helpers\Url;
use yii\base\Exception;
use yii\web\HttpException;
use yii\console\Application;
use humhub\libs\DynamicConfig;
/**
* InstallerModule provides an web installation interface for the applcation
@ -44,7 +47,7 @@ class Module extends \humhub\components\Module
{
parent::init();
if (Yii::$app instanceof \yii\console\Application) {
if (Yii::$app instanceof Application) {
return;
}
@ -61,10 +64,11 @@ class Module extends \humhub\components\Module
// Block installer, when it's marked as installed
if (Yii::$app->params['installed']) {
throw new \yii\web\HttpException(500, 'HumHub is already installed!');
throw new HttpException(500, 'HumHub is already installed!');
}
Yii::$app->controller->enableCsrfValidation = false;
return parent::beforeAction($action);
}
@ -83,11 +87,12 @@ class Module extends \humhub\components\Module
return Yii::$app->db->getIsActive();
} catch (Exception $e) {
} catch (\yii\base\Exception $e) {
} catch (Exception $e) {
} catch (\PDOException $e) {
}
return false;
}
@ -99,6 +104,7 @@ class Module extends \humhub\components\Module
if (Yii::$app->settings->get('secret') != "") {
return true;
}
return false;
}
@ -107,9 +113,9 @@ class Module extends \humhub\components\Module
*/
public function setInstalled()
{
$config = \humhub\libs\DynamicConfig::load();
$config = DynamicConfig::load();
$config['params']['installed'] = true;
\humhub\libs\DynamicConfig::save($config);
DynamicConfig::save($config);
}
/**
@ -117,9 +123,9 @@ class Module extends \humhub\components\Module
*/
public function setDatabaseInstalled()
{
$config = \humhub\libs\DynamicConfig::load();
$config = DynamicConfig::load();
$config['params']['databaseInstalled'] = true;
\humhub\libs\DynamicConfig::save($config);
DynamicConfig::save($config);
}
protected function initConfigSteps()

View File

@ -2,7 +2,7 @@
/**
* @link https://www.humhub.org/
* @copyright Copyright (c) 2016 HumHub GmbH & Co. KG
* @copyright Copyright (c) 2017 HumHub GmbH & Co. KG
* @license https://www.humhub.com/licences
*/
@ -11,11 +11,12 @@ namespace humhub\modules\installer\commands;
use Yii;
use yii\console\Controller;
use yii\helpers\Console;
use yii\base\Exception;
use humhub\modules\user\models\User;
use humhub\modules\user\models\Password;
use humhub\modules\user\models\Group;
use humhub\modules\installer\libs\InitialData;
use humhub\libs\UUID;
/**
* Console Install
@ -29,26 +30,26 @@ class InstallController extends Controller
{
$this->stdout("Install:\n\n", Console::FG_YELLOW);
\humhub\modules\installer\libs\InitialData::bootstrap();
InitialData::bootstrap();
Yii::$app->settings->set('name', "HumHub Test");
Yii::$app->settings->set('mailer.systemEmailName', "humhub@example.com");
Yii::$app->settings->set('mailer.systemEmailName', "humhub@example.com");
Yii::$app->settings->set('secret', \humhub\libs\UUID::v4());
Yii::$app->settings->set('name', 'HumHub Test');
Yii::$app->settings->set('mailer.systemEmailName', 'humhub@example.com');
Yii::$app->settings->set('mailer.systemEmailName', 'humhub@example.com');
Yii::$app->settings->set('secret', UUID::v4());
$user = new User();
//$user->group_id = 1;
$user->username = "Admin";
$user->username = 'Admin';
$user->email = 'humhub@example.com';
$user->status = User::STATUS_ENABLED;
$user->language = '';
if (!$user->save()) {
throw new \yii\base\Exception("Could not save user");
throw new Exception("Could not save user");
}
$user->profile->title = "System Administration";
$user->profile->firstname = "John";
$user->profile->lastname = "Doe";
$user->profile->title = 'System Administration';
$user->profile->firstname = 'John';
$user->profile->lastname = 'Doe';
$user->profile->save();
$password = new Password();
@ -59,7 +60,6 @@ class InstallController extends Controller
// Assign to system admin group
Group::getAdminGroup()->addUser($user);
return self::EXIT_CODE_NORMAL;
}

View File

@ -2,7 +2,7 @@
/**
* @link https://www.humhub.org/
* @copyright Copyright (c) 2016 HumHub GmbH & Co. KG
* @copyright Copyright (c) 2017 HumHub GmbH & Co. KG
* @license https://www.humhub.com/licences
*/
@ -11,7 +11,12 @@ namespace humhub\modules\notification\components;
use humhub\components\SocialActivity;
use Yii;
use yii\helpers\Url;
use yii\helpers\ArrayHelper;
use yii\bootstrap\Html;
use yii\db\Expression;
use yii\db\ActiveQuery;
use yii\base\InvalidConfigException;
use humhub\components\SocialActivity;
use humhub\modules\notification\models\Notification;
use humhub\modules\notification\jobs\SendNotification;
use humhub\modules\notification\jobs\SendBulkNotification;
@ -114,7 +119,7 @@ abstract class BaseNotification extends SocialActivity
*/
public function getViewParams($params = [])
{
if ($this->hasContent() && $this->getContent()->updated_at instanceof \yii\db\Expression) {
if ($this->hasContent() && $this->getContent()->updated_at instanceof Expression) {
$this->getContent()->refresh();
$date = $this->getContent()->updated_at;
} else if ($this->hasContent()) {
@ -129,7 +134,7 @@ abstract class BaseNotification extends SocialActivity
'isNew' => !$this->record->seen,
];
return \yii\helpers\ArrayHelper::merge(parent::getViewParams($result), $params);
return ArrayHelper::merge(parent::getViewParams($result), $params);
}
/**
@ -143,10 +148,10 @@ abstract class BaseNotification extends SocialActivity
public function sendBulk($users)
{
if (empty($this->moduleId)) {
throw new \yii\base\InvalidConfigException('No moduleId given for "' . $this->className() . '"');
throw new InvalidConfigException('No moduleId given for "' . $this->className() . '"');
}
if ($users instanceof \yii\db\ActiveQuery) {
if ($users instanceof ActiveQuery) {
$users = $users->all();
}
@ -166,7 +171,7 @@ abstract class BaseNotification extends SocialActivity
public function send(User $user)
{
if (empty($this->moduleId)) {
throw new \yii\base\InvalidConfigException('No moduleId given for "' . $this->className() . '"');
throw new InvalidConfigException('No moduleId given for "' . $this->className() . '"');
}
if ($this->isOriginator($user)) {
@ -188,7 +193,7 @@ abstract class BaseNotification extends SocialActivity
*/
public function getMailSubject()
{
return "New notification";
return 'New notification';
}
/**
@ -243,6 +248,7 @@ abstract class BaseNotification extends SocialActivity
}
parent::about($source);
$this->record->space_id = $this->getSpaceId();
return $this;
}
@ -256,6 +262,7 @@ abstract class BaseNotification extends SocialActivity
}
$this->originator = $originator;
$this->record->originator_user_id = $originator->id;
return $this;
}
@ -360,6 +367,7 @@ abstract class BaseNotification extends SocialActivity
}
list($user1, $user2) = $this->getGroupLastUsers(2);
return Yii::t('NotificationModule.base', '{displayName} and {displayName2}', [
'displayName' => Html::tag('strong', Html::encode($user1->displayName)),
'displayName2' => Html::tag('strong', Html::encode($user2->displayName)),
@ -402,6 +410,7 @@ abstract class BaseNotification extends SocialActivity
{
$result = parent::asArray($user);
$result['mailSubject'] = $this->getMailSubject($user);
return $result;
}

View File

@ -2,15 +2,18 @@
/**
* @link https://www.humhub.org/
* @copyright Copyright (c) 2015 HumHub GmbH & Co. KG
* @copyright Copyright (c) 2017 HumHub GmbH & Co. KG
* @license https://www.humhub.com/licences
*/
namespace humhub\modules\notification\controllers;
use Yii;
use yii\web\HttpException;
use humhub\components\Controller;
use humhub\components\behaviors\AccessControl;
use humhub\modules\notification\models\Notification;
use humhub\components\access\ControllerAccess;
/**
* EntryController
@ -23,12 +26,10 @@ class EntryController extends Controller
/**
* @inheritdoc
*/
public function behaviors()
public function getAccessRules()
{
return [
'acl' => [
'class' => \humhub\components\behaviors\AccessControl::className(),
]
[ControllerAccess::RULE_LOGGED_IN_ONLY]
];
}
@ -40,7 +41,7 @@ class EntryController extends Controller
$notificationModel = Notification::findOne(['id' => Yii::$app->request->get('id'), 'user_id' => Yii::$app->user->id]);
if ($notificationModel === null) {
throw new \yii\web\HttpException(404, Yii::t('NotificationModule.error','The requested content is not valid or was removed!'));
throw new HttpException(404, Yii::t('NotificationModule.error','The requested content is not valid or was removed!'));
}
$notification = $notificationModel->getClass();
@ -48,7 +49,7 @@ class EntryController extends Controller
if ($notification->markAsSeenOnClick) {
$notification->markAsSeen();
}
// Redirect to notification URL
return $this->redirect($notification->getUrl());
}

View File

@ -1,17 +1,26 @@
<?php
/**
* @link https://www.humhub.org/
* @copyright Copyright (c) 2017 HumHub GmbH & Co. KG
* @license https://www.humhub.com/licences
*/
namespace humhub\modules\notification\models\forms;
use humhub\modules\notification\components\NotificationCategory;
use Yii;
use yii\base\Model;
use yii\web\HttpException;
use humhub\modules\notification\targets\BaseTarget;
use humhub\modules\admin\permissions\ManageSettings;
/**
* Description of NotificationSettings
*
* @author buddha
*/
class NotificationSettings extends \yii\base\Model
class NotificationSettings extends Model
{
/**
@ -60,6 +69,7 @@ class NotificationSettings extends \yii\base\Model
$this->desktopNotifications = Yii::$app->notification->getDesktopNoficationSettings($this->user);
$module = Yii::$app->getModule('notification');
return ($this->user) ? $module->settings->user($this->user) : $module->settings;
}
@ -99,6 +109,7 @@ class NotificationSettings extends \yii\base\Model
if ($this->user) {
return $this->getSettings()->get('notification.like_email') !== null;
}
return false;
}
@ -143,7 +154,7 @@ class NotificationSettings extends \yii\base\Model
public function save()
{
if (!$this->checkPermission()) {
throw new \yii\web\HttpException(403);
throw new HttpException(403);
}
if (!$this->validate()) {
@ -208,12 +219,13 @@ class NotificationSettings extends \yii\base\Model
public function getSettings()
{
$module = Yii::$app->getModule('notification');
return ($this->user) ? $module->settings->user($this->user) : $module->settings;
}
public function checkPermission()
{
if (Yii::$app->user->can(new \humhub\modules\admin\permissions\ManageSettings())) {
if (Yii::$app->user->can(new ManageSettings())) {
return true;
} else if (!$this->user) {
return false; // Only ManageSettings user can set global notification settings
@ -235,6 +247,7 @@ class NotificationSettings extends \yii\base\Model
}
}
Yii::$app->notification->setSpaces([], $this->user);
return true;
}

View File

@ -9,8 +9,10 @@
namespace humhub\modules\notification\targets;
use Yii;
use yii\base\Exception;
use humhub\modules\user\models\User;
use humhub\modules\notification\components\BaseNotification;
use humhub\modules\notification\live\NewNotification;
/**
* Web Target
@ -37,13 +39,13 @@ class WebTarget extends BaseTarget
public function handle(BaseNotification $notification, User $user)
{
if (!$notification->record) {
throw new \yii\base\Exception('Notification record not found for BaseNotification "' . $notification->className() . '"');
throw new Exception('Notification record not found for BaseNotification "' . $notification->className() . '"');
}
$notification->record->send_web_notifications = true;
$notification->record->save();
Yii::$app->live->send(new \humhub\modules\notification\live\NewNotification([
Yii::$app->live->send(new NewNotification([
'notificationId' => $notification->record->id,
'contentContainerId' => $user->contentcontainer_id,
'ts' => time(),

View File

@ -2,7 +2,7 @@
/**
* @link https://www.humhub.org/
* @copyright Copyright (c) 2015 HumHub GmbH & Co. KG
* @copyright Copyright (c) 2017 HumHub GmbH & Co. KG
* @license https://www.humhub.com/licences
*/
@ -10,14 +10,22 @@ namespace humhub\modules\space\behaviors;
use Yii;
use yii\base\Behavior;
use yii\base\Exception;
use yii\validators\EmailValidator;;
use humhub\modules\user\models\User;
use humhub\modules\space\models\Space;
use humhub\modules\space\models\Membership;
use humhub\modules\user\models\Invite;
use humhub\modules\space\notifications\Invite as InviteNotification;
use humhub\modules\admin\permissions\ManageSpaces;
use humhub\modules\space\notifications\ApprovalRequestAccepted;
use humhub\modules\space\notifications\ApprovalRequestDeclined;
use humhub\modules\space\notifications\ApprovalRequest;
use humhub\modules\space\notifications\InviteAccepted;
use humhub\modules\space\notifications\InviteDeclined;
use humhub\modules\space\MemberEvent;
use humhub\modules\space\activities\MemberAdded;
use humhub\modules\space\activities\MemberRemoved;
/**
* SpaceModelMemberBehavior bundles all membership related methods of the Space model.
@ -35,13 +43,13 @@ class SpaceModelMembership extends Behavior
* @param integer $userId
* @return boolean
*/
public function isMember($userId = "")
public function isMember($userId = '')
{
// Take current userid if none is given
if ($userId == "" && !Yii::$app->user->isGuest) {
if ($userId == '' && !Yii::$app->user->isGuest) {
$userId = Yii::$app->user->id;
} elseif ($userId == "" && Yii::$app->user->isGuest) {
} elseif ($userId == '' && Yii::$app->user->isGuest) {
return false;
}
@ -61,11 +69,11 @@ class SpaceModelMembership extends Behavior
* @param number $userId, if empty hte currently logged in user is taken.
* @return bool
*/
public function canLeave($userId = "")
public function canLeave($userId = '')
{
// Take current userid if none is given
if ($userId == "") {
if ($userId == '') {
$userId = Yii::$app->user->id;
}
@ -129,6 +137,7 @@ class SpaceModelMembership extends Behavior
$this->owner->update(false, ['created_by']);
$this->_spaceOwner = null;
return true;
}
@ -144,6 +153,7 @@ class SpaceModelMembership extends Behavior
}
$this->_spaceOwner = User::findOne(['id' => $this->owner->created_by]);
return $this->_spaceOwner;
}
@ -185,6 +195,7 @@ class SpaceModelMembership extends Behavior
$membership->save();
return true;
}
return false;
}
@ -214,7 +225,7 @@ class SpaceModelMembership extends Behavior
{
// Invalid E-Mail
$validator = new \yii\validators\EmailValidator;
$validator = new EmailValidator;
if (!$validator->validate($email))
return false;
@ -255,7 +266,7 @@ class SpaceModelMembership extends Behavior
* @param integer $userId
* @param string $message
*/
public function requestMembership($userId, $message = "")
public function requestMembership($userId, $message = '')
{
$user = ($userId instanceof User) ? $userId : User::findOne(['id' => $userId]);
@ -271,7 +282,7 @@ class SpaceModelMembership extends Behavior
$membership->save();
\humhub\modules\space\notifications\ApprovalRequest::instance()
ApprovalRequest::instance()
->from($user)->about($this->owner)->withMessage($message)->sendBulk($this->getAdmins());
}
@ -313,7 +324,7 @@ class SpaceModelMembership extends Behavior
return;
case Membership::STATUS_INVITED:
// If user is already invited, remove old invite notification and retrigger
$oldNotification = new \humhub\modules\space\notifications\Invite(['source' => $this->owner]);
$oldNotification = new InviteNotification(['source' => $this->owner]);
$oldNotification->delete(User::findOne(['id' => $userId]));
break;
}
@ -332,7 +343,7 @@ class SpaceModelMembership extends Behavior
if ($membership->save()) {
$this->sendInviteNotification($userId, $originatorId);
} else {
throw new \yii\base\Exception("Could not save membership!" . print_r($membership->getErrors(), 1));
throw new Exception('Could not save membership!' . print_r($membership->getErrors(), 1));
}
}
@ -344,7 +355,7 @@ class SpaceModelMembership extends Behavior
*/
protected function sendInviteNotification($userId, $originatorId)
{
$notification = new \humhub\modules\space\notifications\Invite([
$notification = new InviteNotification([
'source' => $this->owner,
'originator' => User::findOne(['id' => $originatorId])
]);
@ -413,16 +424,16 @@ class SpaceModelMembership extends Behavior
// Create Activity
\humhub\modules\space\activities\MemberAdded::instance()->from($user)->about($this->owner)->save();
MemberAdded::instance()->from($user)->about($this->owner)->save();
// Members can't also follow the space
$this->owner->unfollow($userId);
// Delete invite notification for this user
\humhub\modules\space\notifications\Invite::instance()->about($this->owner)->delete($user);
InviteNotification::instance()->about($this->owner)->delete($user);
// Delete pending approval request notifications for this user
\humhub\modules\space\notifications\ApprovalRequest::instance()->from($user)->about($this->owner)->delete();
ApprovalRequest::instance()->from($user)->about($this->owner)->delete();
}
/**
@ -450,7 +461,7 @@ class SpaceModelMembership extends Behavior
// If was member, create a activity for that
if ($membership->status == Membership::STATUS_MEMBER) {
$activity = new \humhub\modules\space\activities\MemberRemoved();
$activity = new MemberRemoved();
$activity->source = $this->owner;
$activity->originator = $user;
$activity->create();
@ -460,10 +471,10 @@ class SpaceModelMembership extends Behavior
]));
} elseif ($membership->status == Membership::STATUS_INVITED && $membership->originator !== null) {
// Was invited, but declined the request - inform originator
\humhub\modules\space\notifications\InviteDeclined::instance()
InviteDeclined::instance()
->from($user)->about($this->owner)->send($membership->originator);
} elseif ($membership->status == Membership::STATUS_APPLICANT) {
\humhub\modules\space\notifications\ApprovalRequestDeclined::instance()
ApprovalRequestDeclined::instance()
->from(Yii::$app->user->getIdentity())->about($this->owner)->send($user);
}
@ -471,9 +482,9 @@ class SpaceModelMembership extends Behavior
$membership->delete();
}
\humhub\modules\space\notifications\ApprovalRequest::instance()->from($user)->about($this->owner)->delete();
ApprovalRequest::instance()->from($user)->about($this->owner)->delete();
\humhub\modules\space\notifications\Invite::instance()->from($this->owner)->delete($user);
InviteNotification::instance()->from($this->owner)->delete($user);
}
}

View File

@ -2,17 +2,23 @@
/**
* @link https://www.humhub.org/
* @copyright Copyright (c) 2016 HumHub GmbH & Co. KG
* @copyright Copyright (c) 2017 HumHub GmbH & Co. KG
* @license https://www.humhub.com/licences
*/
namespace humhub\modules\space\controllers;
use Yii;
use yii\web\HttpException;
use yii\db\Expression;
use humhub\modules\content\components\ContentContainerController;
use humhub\components\behaviors\AccessControl;
use humhub\modules\space\models\Space;
use humhub\modules\user\models\User;
use humhub\modules\user\widgets\UserListBox;
use humhub\modules\stream\actions\ContentContainerStream;
use humhub\modules\space\widgets\Menu;
use humhub\modules\post\permissions\CreatePost;
/**
* SpaceController is the main controller for spaces.
@ -24,7 +30,7 @@ use humhub\modules\stream\actions\ContentContainerStream;
* @package humhub.modules_core.space.controllers
* @since 0.5
*/
class SpaceController extends \humhub\modules\content\components\ContentContainerController
class SpaceController extends ContentContainerController
{
/**
@ -34,7 +40,7 @@ class SpaceController extends \humhub\modules\content\components\ContentContaine
{
return [
'acl' => [
'class' => \humhub\components\behaviors\AccessControl::className(),
'class' => AccessControl::className(),
'guestAllowedActions' => ['index', 'stream'],
]
];
@ -65,13 +71,13 @@ class SpaceController extends \humhub\modules\content\components\ContentContaine
}
if (!$space->isMember()) {
$defaultPageUrl = \humhub\modules\space\widgets\Menu::getGuestsDefaultPageUrl($space);
$defaultPageUrl = Menu::getGuestsDefaultPageUrl($space);
if ($defaultPageUrl != null) {
return $this->redirect($defaultPageUrl);
}
}
$defaultPageUrl = \humhub\modules\space\widgets\Menu::getDefaultPageUrl($space);
$defaultPageUrl = Menu::getDefaultPageUrl($space);
if ($defaultPageUrl != null) {
return $this->redirect($defaultPageUrl);
}
@ -87,7 +93,7 @@ class SpaceController extends \humhub\modules\content\components\ContentContaine
public function actionHome()
{
$space = $this->contentContainer;
$canCreatePosts = $space->permissionManager->can(new \humhub\modules\post\permissions\CreatePost());
$canCreatePosts = $space->permissionManager->can(new CreatePost());
$isMember = $space->isMember();
return $this->render('home', [
@ -103,7 +109,7 @@ class SpaceController extends \humhub\modules\content\components\ContentContaine
public function actionFollow()
{
if(Yii::$app->getModule('space')->disableFollow) {
throw new \yii\web\HttpException(403, Yii::t('ContentModule.controllers_ContentController', 'This action is disabled!'));
throw new HttpException(403, Yii::t('ContentModule.controllers_ContentController', 'This action is disabled!'));
}
$this->forcePostRequest();
@ -148,15 +154,14 @@ class SpaceController extends \humhub\modules\content\components\ContentContaine
public function actionFollowerList()
{
$query = User::find();
$query->leftJoin('user_follow', 'user.id=user_follow.user_id and object_model=:userClass and user_follow.object_id=:spaceId', [':userClass' => Space::className(), ':spaceId' => $this->getSpace()->id]);
$query->leftJoin('user_follow', 'user.id=user_follow.user_id AND object_model=:userClass AND user_follow.object_id=:spaceId', [':userClass' => Space::className(), ':spaceId' => $this->getSpace()->id]);
$query->orderBy(['user_follow.id' => SORT_DESC]);
$query->andWhere(['IS NOT', 'user_follow.id', new \yii\db\Expression('NULL')]);
$query->andWhere(['IS NOT', 'user_follow.id', new Expression('NULL')]);
$query->visible();
$title = Yii::t('SpaceModule.base', '<strong>Space</strong> followers');
return $this->renderAjaxContent(UserListBox::widget(['query' => $query, 'title' => $title]));
}
}
?>

View File

@ -8,9 +8,9 @@
namespace humhub\modules\space\modules\manage\controllers;
use humhub\modules\space\models\Space;
use Yii;
use yii\web\HttpException;
use humhub\modules\space\models\Space;
use humhub\modules\space\modules\manage\components\Controller;
use humhub\modules\space\modules\manage\models\MembershipSearch;
use humhub\modules\user\models\User;
@ -52,7 +52,7 @@ class MemberController extends Controller
Yii::$app->response->format = 'json';
$membership = Membership::findOne(['space_id' => $space->id, 'user_id' => Yii::$app->request->post('user_id')]);
if ($membership === null) {
throw new \yii\web\HttpException(404, 'Could not find membership!');
throw new HttpException(404, 'Could not find membership!');
}
if ($membership->load(Yii::$app->request->post()) && $membership->validate() && $membership->save()) {
@ -189,5 +189,3 @@ class MemberController extends Controller
}
}
?>

View File

@ -2,7 +2,7 @@
/**
* @link https://www.humhub.org/
* @copyright Copyright (c) 2016 HumHub GmbH & Co. KG
* @copyright Copyright (c) 2017 HumHub GmbH & Co. KG
* @license https://www.humhub.com/licences
*/
@ -31,6 +31,7 @@ class SecurityController extends Controller
$this->view->saved();
return $this->redirect($space->createUrl('index'));
}
return $this->render('index', ['model' => $space]);
}
@ -52,19 +53,17 @@ class SecurityController extends Controller
Yii::$app->response->format = 'json';
$permission = $space->permissionManager->getById(Yii::$app->request->post('permissionId'), Yii::$app->request->post('moduleId'));
if ($permission === null) {
throw new \yii\web\HttpException(500, 'Could not find permission!');
throw new HttpException(500, 'Could not find permission!');
}
$space->permissionManager->setGroupState($groupId, $permission, Yii::$app->request->post('state'));
return [];
}
return $this->render('permissions', array(
return $this->render('permissions', [
'space' => $space,
'groups' => $groups,
'groupId' => $groupId
));
]);
}
}
?>

View File

@ -100,9 +100,11 @@ humhub.module('space.chooser', function (module, require, $) {
var increments = {};
liveEvents.forEach(function (event) {
if (event.data.uguid || event.data.originator === user.guid()) {
if (event.data.uguid || event.data.originator === user.guid() || event.data.silent) {
return;
} else if (increments[event.data.sguid]) {
}
if (increments[event.data.sguid]) {
increments[event.data.sguid]++;
} else {
increments[event.data.sguid] = 1;

View File

@ -1,9 +1,15 @@
<?php
/**
* @link https://www.humhub.org/
* @copyright Copyright (c) 2017 HumHub GmbH & Co. KG
* @license https://www.humhub.com/licences
*/
namespace humhub\modules\space\widgets;
use Yii;
use yii\base\Exception;
use humhub\modules\content\components\ContentContainerController;
use humhub\modules\space\models\Space;
@ -27,7 +33,7 @@ class Menu extends \humhub\widgets\BaseMenu
}
if ($this->space === null) {
throw new \yii\base\Exception("Could not instance space menu without space!");
throw new Exception("Could not instance space menu without space!");
}
$this->id = 'navigation-menu-space-' . $this->space->getUniqueId();
@ -44,7 +50,7 @@ class Menu extends \humhub\widgets\BaseMenu
'url' => $this->space->createUrl('/space/space/home'),
'icon' => '<i class="fa fa-bars"></i>',
'sortOrder' => 100,
'isActive' => (Yii::$app->controller->id == "space" && (Yii::$app->controller->action->id == "index" || Yii::$app->controller->action->id == 'home') && Yii::$app->controller->module->id == "space"),
'isActive' => (Yii::$app->controller->id == 'space' && (Yii::$app->controller->action->id == 'index' || Yii::$app->controller->action->id == 'home') && Yii::$app->controller->module->id == 'space'),
));
parent::init();
@ -66,6 +72,7 @@ class Menu extends \humhub\widgets\BaseMenu
foreach ($moduleItems as $moduleItem) {
$result[$moduleItem['url']] = $moduleItem['label'];
}
return $result;
}
@ -88,6 +95,7 @@ class Menu extends \humhub\widgets\BaseMenu
$settings->contentContainer($space)->delete('indexUrl');
}
}
return null;
}
@ -110,9 +118,8 @@ class Menu extends \humhub\widgets\BaseMenu
$settings->contentContainer($space)->delete('indexGuestUrl');
}
}
return null;
}
}
?>

View File

@ -1,9 +1,16 @@
<?php
/**
* @link https://www.humhub.org/
* @copyright Copyright (c) 2017 HumHub GmbH & Co. KG
* @license https://www.humhub.com/licences
*/
namespace humhub\modules\stream\models;
use humhub\modules\content\models\Content;
use Yii;
use yii\base\Exception;
/**
* StreamSuppressQuery detects same content types in a row and trims the output.
@ -205,7 +212,7 @@ class StreamSuppressQuery extends StreamQuery
public function getSuppressions()
{
if (!$this->isQueryExecuted) {
throw new \yii\base\Exception("Execute query first via all() method before reading suppressed items.");
throw new Exception('Execute query first via all() method before reading suppressed items.');
}
$results = [];

View File

@ -99,7 +99,7 @@ humhub.module('stream', function (module, require, $) {
var that = this;
var stream = this.stream();
promise.then(function ($confirm) {
if ($confirm) {
that.remove(); // Make sure to remove the wallentry node.
@ -262,7 +262,6 @@ humhub.module('stream', function (module, require, $) {
that.remove().then(function () {
stream.loadEntry(that.getKey(), {'prepend': true});
});
module.log.success('success.pin');
} else if (data.info) {
module.log.info(data.info, true);
} else {
@ -298,9 +297,8 @@ humhub.module('stream', function (module, require, $) {
StreamEntry.prototype.unpin = function (evt) {
var that = this;
this.loader();
client.post(evt.url).then(function (data) {
client.post(evt.url).then(function () {
that.stream().init();
module.log.success('success.unpin');
}).catch(function (e) {
module.log.error(e, true);
that.loader(false);
@ -897,7 +895,7 @@ humhub.module('stream', function (module, require, $) {
/**
* Simple stream component can be used for static streams without load logic (only reload single content).
*
*
* @param {type} container
* @param {type} cfg
* @returns {humhub.streamL#5.SimpleStream}
@ -924,7 +922,7 @@ humhub.module('stream', function (module, require, $) {
return client.get(contentModule.config.reloadUrl, {data: {id: contentId}}).then(function (response) {
if (response.output) {
entry.replace(response.output);
}
}
return response;
}).catch(function (err) {
module.log.error(err, true);
@ -995,11 +993,11 @@ humhub.module('stream', function (module, require, $) {
/*
This can be used to trace the currently visible entries
var lastKey;
// Defines our base y position for changing the current entry
var yLimit = scrollTop + (windowHeight / 2);
// Get id of current scroll item
//TODO: chache the entry nodes !
var matchingNodes = stream.$entryCache.map(function () {
@ -1008,11 +1006,11 @@ humhub.module('stream', function (module, require, $) {
return $this;
}
});
// Get the id of the current element
var $current = matchingNodes[matchingNodes.length - 1];
var currentKey = $current && $current.length ? $current.data('content-key') : "";
if (lastKey !== currentKey) {
lastKey = currentKey;
// Set/remove active class
@ -1082,4 +1080,4 @@ humhub.module('stream', function (module, require, $) {
getStream: getStream,
getEntry: getEntry
});
});
});

View File

@ -2396,7 +2396,7 @@ trait AcceptanceTesterActions
*
* Wait for $timeout seconds.
*
* @param int $timeout secs
* @param int|float $timeout secs
* @throws \Codeception\Exception\TestRuntimeException
* @see \Codeception\Module\WebDriver::wait()
*/

View File

@ -107,23 +107,21 @@ class StreamCest
$newEntrySelector2 = '[data-content-key="14"]';
$I->waitForElementVisible($newEntrySelector2);
$I->expectTo('my new post beeing the latest entry');
$I->see('This is my second stream test post', '.s2_streamContent div:nth-child(1)');
$I->waitForText('This is my second stream test post',null, '.s2_streamContent div:nth-child(1)');
$I->amGoingTo('pin my first entry');
$I->click('.preferences .dropdown-toggle', $newEntrySelector);
$I->waitForText('Pin', 10);
$I->click('Pin', $newEntrySelector);
$I->seeSuccess('The content has been pinned.');
$I->see('This is my first stream test post!', '.s2_streamContent div:nth-child(1)');
$I->waitForText('This is my first stream test post!',null, '.s2_streamContent div:nth-child(1)');
$I->see('Pinned', $newEntrySelector);
$I->amGoingTo('unpin my first entry');
$I->click('.preferences .dropdown-toggle', $newEntrySelector);
$I->waitForText('Unpin', 10);
$I->click('Unpin', $newEntrySelector);
$I->seeSuccess('The content has been unpinned.');
$I->see('This is my second stream test post!', '.s2_streamContent div:nth-child(1)');
$I->waitForText('This is my second stream test post!',null, '.s2_streamContent div:nth-child(1)');
$I->dontSee('Pinned', $newEntrySelector);
}
@ -145,7 +143,7 @@ class StreamCest
$I->click('.preferences .dropdown-toggle', $newEntrySelector);
$I->waitForText('Edit', 10);
$I->click('Edit', $newEntrySelector);
$I->waitForElementVisible($newEntrySelector . ' .content_edit', 20);
$I->amGoingTo('cancel my edit');
$I->click('.preferences .dropdown-toggle', $newEntrySelector);
@ -154,43 +152,43 @@ class StreamCest
$I->waitForElementNotVisible($newEntrySelector . ' .content_edit', 20);
$I->waitForElementVisible($newEntrySelector . ' .content', 20);
$I->see('This is my first stream test post!', $newEntrySelector);
$I->amGoingTo('edit my new post');
$I->click('.preferences .dropdown-toggle', $newEntrySelector);
$I->waitForText('Edit', 10);
$I->click('Edit', $newEntrySelector);
$I->waitForElementVisible($newEntrySelector . ' .content_edit', 20);
$I->fillField($newEntrySelector . ' [contenteditable]', 'This is my edited post!');
$I->click('Save', $newEntrySelector);
$I->seeSuccess('Saved');
$I->seeElement($newEntrySelector);
$I->see('This is my edited post!', $newEntrySelector);
}
public function testEmptyStream(AcceptanceTester $I)
{
$I->amUser();
$I->amOnSpace3();
$I->wantToTest('the empty stream message and filter');
$I->waitForText('This space is still empty!');
$I->dontSeeElement('#filter');
$I->amGoingTo('create a new post and delete it afterwards');
$I->createPost('This is my first stream test post!');
$I->wait(1);
$I->wait(1);
$I->amGoingTo('Delete my new post again.');
$I->dontSee('This space is still empty!');
$I->seeElement('#filter');
$I->click('.preferences .dropdown-toggle', '[data-stream-entry]:nth-of-type(1)');
$I->wait(1);
$I->click('Delete');
$I->waitForElementVisible('#globalModalConfirm', 5);
$I->see('Confirm post deletion');
$I->click('Delete', '#globalModalConfirm');
@ -199,7 +197,7 @@ class StreamCest
$I->see('This space is still empty!');
$I->dontSeeElement('#filter');
}
public function testFilterInvolved(AcceptanceTester $I)
{
$I->amUser();
@ -209,25 +207,26 @@ class StreamCest
$I->waitForElementVisible('#filter_entry_userinvolved');
$I->click('#filter_entry_userinvolved');
$I->waitForText('No matches with your selected filters!');
$I->createPost('Involved Post.');
$I->wait(1);
$I->dontSee('No matches with your selected filters!');
$I->amGoingTo('Reset filter');
$I->click('.stream-filter', '#filter');
$I->waitForElementVisible('#filter_entry_userinvolved');
$I->click('#filter_entry_userinvolved');
$I->waitForElementVisible('[data-content-key="10"]');
$I->click('Comment', '[data-content-key="10"]');
$I->waitForElementVisible('#newCommentForm_humhubmodulespostmodelsPost_10');
$I->fillField('#newCommentForm_humhubmodulespostmodelsPost_10', 'My Comment');
$I->click('Send', '#comment_create_form_humhubmodulespostmodelsPost_10');
$I->waitForText('My Comment', 30, '#comment_humhubmodulespostmodelsPost_10 .comment');
$I->click('Like', '[data-content-key="11"]');
$I->click('.stream-filter', '#filter');
$I->waitForElementVisible('#filter_entry_userinvolved');
$I->click('#filter_entry_userinvolved');
@ -267,15 +266,15 @@ class StreamCest
$I->click('Comment', $post4Selector);
$I->fillField($post4Selector . ' [contenteditable]', 'My Comment!');
$I->click('Send', $post4Selector . ' .comment-buttons');
$I->scrollTop();
$I->click('.stream-sorting', '#filter');
$I->waitForElementVisible('#sorting_u');
$I->click('#sorting_u');
$I->wait(2);
$I->waitForElementVisible($post4Selector);
$I->see('POST4', '.s2_streamContent > [data-stream-entry]:nth-of-type(1)');
$I->see('POST5', '.s2_streamContent > [data-stream-entry]:nth-of-type(2)');
$I->see('POST3', '.s2_streamContent > [data-stream-entry]:nth-of-type(3)');

View File

@ -2,17 +2,21 @@
/**
* @link https://www.humhub.org/
* @copyright Copyright (c) 2016 HumHub GmbH & Co. KG
* @copyright Copyright (c) 2017 HumHub GmbH & Co. KG
* @license https://www.humhub.com/licences
*/
namespace humhub\modules\user\controllers;
use humhub\modules\admin\permissions\ManageGroups;
use humhub\modules\admin\permissions\ManageUsers;
use Yii;
use yii\web\Controller;
use yii\web\HttpException;
use humhub\components\behaviors\AccessControl;
use humhub\modules\admin\permissions\ManageGroups;
use humhub\modules\admin\permissions\ManageUsers;
use humhub\modules\user\models\Invite;
use humhub\modules\user\models\forms\Invite as InviteForm;
use humhub\widgets\ModalClose;
/**
* InviteController for new user invites
@ -29,7 +33,7 @@ class InviteController extends Controller
{
return [
'acl' => [
'class' => \humhub\components\behaviors\AccessControl::className(),
'class' => AccessControl::className(),
]
];
}
@ -43,22 +47,22 @@ class InviteController extends Controller
public function actionIndex()
{
if (!$this->canInvite()) {
throw new \yii\web\HttpException(403, 'Invite denied!');
throw new HttpException(403, 'Invite denied!');
}
$model = new \humhub\modules\user\models\forms\Invite;
$model = new InviteForm;
if ($model->load(Yii::$app->request->post()) && $model->validate()) {
foreach ($model->getEmails() as $email) {
$this->createInvite($email);
}
return \humhub\widgets\ModalClose::widget([
return ModalClose::widget([
'success' => Yii::t('UserModule.user', 'User has been invited.')
]);
}
return $this->renderAjax('index', array('model' => $model));
return $this->renderAjax('index', ['model' => $model]);
}
/**
@ -94,5 +98,3 @@ class InviteController extends Controller
}
}
?>

View File

@ -2,17 +2,24 @@
/**
* @link https://www.humhub.org/
* @copyright Copyright (c) 2016 HumHub GmbH & Co. KG
* @copyright Copyright (c) 2017 HumHub GmbH & Co. KG
* @license https://www.humhub.com/licences
*/
namespace humhub\modules\user\controllers;
use Yii;
use yii\web\HttpException;
use yii\db\Expression;
use humhub\modules\content\components\ContentContainerController;
use humhub\modules\stream\actions\ContentContainerStream;
use humhub\modules\user\models\User;
use humhub\modules\user\widgets\UserListBox;
use humhub\modules\space\widgets\ListBox;
use humhub\components\behaviors\AccessControl;
use humhub\modules\user\permissions\ViewAboutPage;
use humhub\modules\space\models\Membership;
use humhub\modules\space\models\Space;
/**
* ProfileController is responsible for all user profiles.
@ -32,7 +39,7 @@ class ProfileController extends ContentContainerController
{
return [
'acl' => [
'class' => \humhub\components\behaviors\AccessControl::className(),
'class' => AccessControl::className(),
'guestAllowedActions' => ['index', 'stream', 'about']
]
];
@ -43,13 +50,13 @@ class ProfileController extends ContentContainerController
*/
public function actions()
{
return array(
'stream' => array(
return [
'stream' => [
'class' => ContentContainerStream::className(),
'mode' => ContentContainerStream::MODE_NORMAL,
'contentContainer' => $this->contentContainer
),
);
],
];
}
/**
@ -74,8 +81,8 @@ class ProfileController extends ContentContainerController
public function actionAbout()
{
if (!$this->contentContainer->permissionManager->can(new \humhub\modules\user\permissions\ViewAboutPage())) {
throw new \yii\web\HttpException(403, 'Forbidden');
if (!$this->contentContainer->permissionManager->can(new ViewAboutPage())) {
throw new HttpException(403, 'Forbidden');
}
return $this->render('about', ['user' => $this->contentContainer]);
@ -84,7 +91,7 @@ class ProfileController extends ContentContainerController
public function actionFollow()
{
if(Yii::$app->getModule('user')->disableFollow) {
throw new \yii\web\HttpException(403, Yii::t('ContentModule.controllers_ContentController', 'This action is disabled!'));
throw new HttpException(403, Yii::t('ContentModule.controllers_ContentController', 'This action is disabled!'));
}
$this->forcePostRequest();
@ -114,21 +121,22 @@ class ProfileController extends ContentContainerController
public function actionFollowerList()
{
$query = User::find();
$query->leftJoin('user_follow', 'user.id=user_follow.user_id and object_model=:userClass and user_follow.object_id=:userId', [':userClass' => User::className(), ':userId' => $this->getUser()->id]);
$query->leftJoin('user_follow', 'user.id=user_follow.user_id AND object_model=:userClass AND user_follow.object_id=:userId', [':userClass' => User::className(), ':userId' => $this->getUser()->id]);
$query->orderBy(['user_follow.id' => SORT_DESC]);
$query->andWhere(['IS NOT', 'user_follow.id', new \yii\db\Expression('NULL')]);
$query->andWhere(['IS NOT', 'user_follow.id', new Expression('NULL')]);
$query->active();
$title = Yii::t('UserModule.widgets_views_userFollower', '<strong>User</strong> followers');
return $this->renderAjaxContent(UserListBox::widget(['query' => $query, 'title' => $title]));
}
public function actionFollowedUsersList()
{
$query = User::find();
$query->leftJoin('user_follow', 'user.id=user_follow.object_id and object_model=:userClass and user_follow.user_id=:userId', [':userClass' => User::className(), ':userId' => $this->getUser()->id]);
$query->leftJoin('user_follow', 'user.id=user_follow.object_id AND object_model=:userClass AND user_follow.user_id=:userId', [':userClass' => User::className(), ':userId' => $this->getUser()->id]);
$query->orderBy(['user_follow.id' => SORT_DESC]);
$query->andWhere(['IS NOT', 'user_follow.id', new \yii\db\Expression('NULL')]);
$query->andWhere(['IS NOT', 'user_follow.id', new Expression('NULL')]);
$query->active();
$title = Yii::t('UserModule.widgets_views_userFollower', '<strong>Following</strong> user');
@ -137,16 +145,14 @@ class ProfileController extends ContentContainerController
public function actionSpaceMembershipList()
{
$query = \humhub\modules\space\models\Membership::getUserSpaceQuery($this->getUser());
$query = Membership::getUserSpaceQuery($this->getUser());
if (!$this->getUser()->isCurrentUser()) {
$query->andWhere(['!=', 'space.visibility', \humhub\modules\space\models\Space::VISIBILITY_NONE]);
$query->andWhere(['!=', 'space.visibility', Space::VISIBILITY_NONE]);
}
$title = Yii::t('UserModule.widgets_views_userSpaces', '<strong>Member</strong> in these spaces');
return $this->renderAjaxContent(\humhub\modules\space\widgets\ListBox::widget(['query' => $query, 'title' => $title]));
return $this->renderAjaxContent(ListBox::widget(['query' => $query, 'title' => $title]));
}
}
?>

View File

@ -1,12 +1,15 @@
<?php
use yii\db\Schema;
use yii\db\Query;
use yii\db\Expression;
use humhub\components\Migration;
class m160229_162959_multiusergroups extends \humhub\components\Migration
class m160229_162959_multiusergroups extends Migration
{
public function up()
{
$this->createTable('group_user', array(
$this->createTable('group_user', [
'id' => 'pk',
'user_id' => 'int(11) NOT NULL',
'group_id' => 'int(11) NOT NULL',
@ -15,53 +18,53 @@ class m160229_162959_multiusergroups extends \humhub\components\Migration
'created_by' => 'int(11) DEFAULT NULL',
'updated_at' => 'datetime DEFAULT NULL',
'updated_by' => 'int(11) DEFAULT NULL',
), '');
//Add indexes and foreign keys
], '');
// Add indexes and foreign keys
$this->createIndex('idx-group_user', 'group_user', ['user_id', 'group_id'], true);
$this->addForeignKey('fk-user-group', 'group_user', 'user_id', 'user', 'id', 'CASCADE');
$this->addForeignKey('fk-group-group', 'group_user', 'group_id', '`group`', 'id', 'CASCADE');
//Merge old group user and group admins
// Merge old group user and group admins
$this->execute('INSERT INTO group_user (user_id, group_id) SELECT DISTINCT user.id, user.group_id FROM user LEFT JOIN `group` ON user.group_id=group.id WHERE group.id IS NOT NULL');
$this->execute('UPDATE group_user u SET is_group_admin = :value WHERE EXISTS (Select 1 FROM group_admin a WHERE u.user_id = a.user_id);', [':value' => 1]);
//Add group columns
// Add group columns
$this->addColumn('group', 'is_admin_group', Schema::TYPE_BOOLEAN. ' NOT NULL DEFAULT 0');
$this->addColumn('group', 'show_at_registration', Schema::TYPE_BOOLEAN. ' NOT NULL DEFAULT 1');
$this->addColumn('group', 'show_at_directory', Schema::TYPE_BOOLEAN. ' NOT NULL DEFAULT 1');
//Create initial administration group
// Create initial administration group
$this->insertSilent('group', [
'name' => 'Administrator',
'description' => 'Administrator Group',
'is_admin_group' => '1',
'show_at_registration' => '0',
'show_at_directory' => '0',
'created_at' => new \yii\db\Expression('NOW()')
'created_at' => new Expression('NOW()')
]);
//Determine administration group id
$adminGroupId = (new \yii\db\Query())
// Determine administration group id
$adminGroupId = (new Query())
->select('id')
->from('group')
->where(['is_admin_group' => '1'])
->scalar();
//Load current super_admin user
$rows = (new \yii\db\Query())
// Load current super_admin user
$rows = (new Query())
->select("id")
->from('user')
->where(['super_admin' => '1'])
->all();
//Insert group_user for administartion groups for all current super_admins
foreach($rows as $adminUserRow) {
// Insert group_user for administration groups for all current super_admins
foreach ($rows as $adminUserRow) {
$this->insertSilent('group_user', ['user_id' => $adminUserRow['id'], 'group_id' => $adminGroupId, 'is_group_admin' => '1']);
}
//$this->insertSilent('group_permission', ['permission_id' => 'user_admin', 'group_id' => $adminGroupId, 'module_id' => 'user', 'class' => 'humhub\modules\user\permissions']);
$this->dropTable('group_admin');
$this->dropColumn('user', 'super_admin');
$this->dropColumn('user', 'group_id');

View File

@ -2,13 +2,17 @@
/**
* @link https://www.humhub.org/
* @copyright Copyright (c) 2016 HumHub GmbH & Co. KG
* @copyright Copyright (c) 2017 HumHub GmbH & Co. KG
* @license https://www.humhub.com/licences
*/
namespace humhub\modules\user\models;
use Yii;
use yii\db\ActiveRecord;
use yii\base\Exception;
use yii\db\Expression;
use humhub\libs\UUID;
use humhub\modules\user\components\CheckPasswordValidator;
/**
@ -21,7 +25,7 @@ use humhub\modules\user\components\CheckPasswordValidator;
* @property string $salt
* @property string $created_at
*/
class Password extends \yii\db\ActiveRecord
class Password extends ActiveRecord
{
/**
@ -30,13 +34,13 @@ class Password extends \yii\db\ActiveRecord
public $currentPassword;
public $newPassword;
public $newPasswordConfirm;
public $defaultAlgorithm = "";
public $defaultAlgorithm = '';
public function init()
{
parent::init();
$this->defaultAlgorithm = "sha1md5";
$this->defaultAlgorithm = 'sha1md5';
if (function_exists('hash_algos')) {
$algos = hash_algos();
@ -50,7 +54,8 @@ class Password extends \yii\db\ActiveRecord
public function beforeSave($insert)
{
$this->created_at = new \yii\db\Expression("NOW()");
$this->created_at = new Expression('NOW()');
return parent::beforeSave($insert);
}
@ -92,7 +97,7 @@ class Password extends \yii\db\ActiveRecord
public function unequalsCurrentPassword($attribute, $params)
{
if($this->newPassword === $this->currentPassword) {
$this->addError($attribute, Yii::t('UserModule.base', 'Your new password must not equal your current password!'));
$this->addError($attribute, Yii::t('UserModule.base', 'Your new password must not be equal your current password!'));
}
}
@ -106,6 +111,7 @@ class Password extends \yii\db\ActiveRecord
}
$scenarios['registration'] = ['newPassword', 'newPasswordConfirm'];
return $scenarios;
}
@ -162,7 +168,7 @@ class Password extends \yii\db\ActiveRecord
} elseif ($this->algorithm == 'sha512') {
return hash('sha512', $password);
} else {
throw new \yii\base\Exception("Invalid Hashing Algorithm!");
throw new Exception('Invalid Hashing Algorithm!');
}
}
@ -173,7 +179,7 @@ class Password extends \yii\db\ActiveRecord
*/
public function setPassword($newPassword)
{
$this->salt = \humhub\libs\UUID::v4();
$this->salt = UUID::v4();
$this->algorithm = $this->defaultAlgorithm;
$this->password = $this->hashPassword($newPassword);
}

View File

@ -2,13 +2,18 @@
/**
* @link https://www.humhub.org/
* @copyright Copyright (c) 2015 HumHub GmbH & Co. KG
* @copyright Copyright (c) 2017 HumHub GmbH & Co. KG
* @license https://www.humhub.com/licences
*/
namespace humhub\modules\user\models\fieldtype;
use Yii;
use yii\base\Model;
use yii\base\Exception;
use yii\helpers\Json;
use yii\helpers\Html;
use humhub\libs\Helpers;
use humhub\modules\user\models\Profile;
/**
@ -17,7 +22,7 @@ use humhub\modules\user\models\Profile;
* @package humhub.modules_core.user.models
* @since 0.5
*/
class BaseType extends \yii\base\Model
class BaseType extends Model
{
/**
@ -28,7 +33,7 @@ class BaseType extends \yii\base\Model
*
* @var Array
*/
public $fieldTypes = array();
public $fieldTypes = [];
/**
* Corresponding ProfileField Model
@ -73,7 +78,7 @@ class BaseType extends \yii\base\Model
*/
public function getFieldTypes()
{
$fieldTypes = array_merge(array(
$fieldTypes = array_merge([
Number::className() => Yii::t('UserModule.models_ProfileFieldType', 'Number'),
Text::className() => Yii::t('UserModule.models_ProfileFieldType', 'Text'),
TextArea::className() => Yii::t('UserModule.models_ProfileFieldType', 'Text Area'),
@ -85,7 +90,8 @@ class BaseType extends \yii\base\Model
MarkdownEditor::className() => Yii::t('UserModule.models_ProfileFieldType', 'Markdown'),
Checkbox::className() => Yii::t('UserModule.models_ProfileFieldType', 'Checkbox'),
CheckboxList::className() => Yii::t('UserModule.models_ProfileFieldType', 'Checkbox List'),
), $this->fieldTypes);
], $this->fieldTypes);
return $fieldTypes;
}
@ -97,14 +103,13 @@ class BaseType extends \yii\base\Model
public function getTypeInstances($profileField = null)
{
$types = array();
$types = [];
foreach ($this->getFieldTypes() as $className => $title) {
if (\humhub\libs\Helpers::CheckClassType($className, self::className())) {
if (Helpers::CheckClassType($className, self::className())) {
$instance = new $className;
if ($profileField != null) {
$instance->profileField = $profileField;
// Seems current type, so try load data
if ($profileField->field_type_class == $className) {
$instance->loadFieldConfig();
@ -113,6 +118,7 @@ class BaseType extends \yii\base\Model
$types[] = $instance;
}
}
return $types;
}
@ -122,11 +128,11 @@ class BaseType extends \yii\base\Model
public function getFieldFormDefinition()
{
$definition = array($this->profileField->internal_name => [
$definition = [$this->profileField->internal_name => [
'type' => 'text',
'class' => 'form-control',
'readonly' => (!$this->profileField->editable)
]);
]];
return $definition;
}
@ -139,10 +145,11 @@ class BaseType extends \yii\base\Model
* @param type $definition
* @return Array of Form Definition
*/
public function getFormDefinition($definition = array())
public function getFormDefinition($definition = [])
{
$definition[get_class($this)]['class'] = "fieldTypeSettings " . str_replace("\\", "_", get_class($this));
return $definition;
}
@ -179,7 +186,7 @@ class BaseType extends \yii\base\Model
public function save()
{
$data = array();
$data = [];
foreach ($this->attributes as $attributeName => $value) {
// Dont save profile field attribute
@ -188,13 +195,13 @@ class BaseType extends \yii\base\Model
$data[$attributeName] = $this->$attributeName;
}
$this->profileField->field_type_config = \yii\helpers\Json::encode($data);
$this->profileField->field_type_config = Json::encode($data);
if (!$this->profileField->save()) {
throw new \yii\base\Exception("Could not save profile field!");
throw new Exception("Could not save profile field!");
}
// Clear Database Schema
Yii::$app->getDb()->getSchema()->getTableSchema(\humhub\modules\user\models\Profile::tableName(), true);
Yii::$app->getDb()->getSchema()->getTableSchema(Profile::tableName(), true);
return true;
}
@ -210,7 +217,7 @@ class BaseType extends \yii\base\Model
return;
}
$config = \yii\helpers\Json::decode($this->profileField->field_type_config);
$config = Json::decode($this->profileField->field_type_config);
if (is_array($config)) {
foreach ($config as $key => $value) {
if (property_exists($this, $key))
@ -225,8 +232,8 @@ class BaseType extends \yii\base\Model
public function delete()
{
$columnName = $this->profileField->internal_name;
if (\humhub\modules\user\models\Profile::columnExists($columnName)) {
$query = Yii::$app->db->getQueryBuilder()->dropColumn(\humhub\modules\user\models\Profile::tableName(), $this->profileField->internal_name);
if (Profile::columnExists($columnName)) {
$query = Yii::$app->db->getQueryBuilder()->dropColumn(Profile::tableName(), $this->profileField->internal_name);
Yii::$app->db->createCommand($query)->execute();
} else {
Yii::error('Could not delete profile column - not exists!');
@ -250,12 +257,11 @@ class BaseType extends \yii\base\Model
* @param type $rules
* @return Array rules
*/
public function getFieldRules($rules = array())
public function getFieldRules($rules = [])
{
if ($this->profileField->required)
$rules[] = array($this->profileField->internal_name, 'required');
$rules[] = [$this->profileField->internal_name, 'required'];
return $rules;
}
@ -274,14 +280,15 @@ class BaseType extends \yii\base\Model
if ($raw) {
return $user->profile->$internalName;
} else {
return \yii\helpers\Html::encode($user->profile->$internalName);
return Html::encode($user->profile->$internalName);
}
}
public function getLabels()
{
$labels = array();
$labels = [];
$labels[$this->profileField->internal_name] = Yii::t($this->profileField->getTranslationCategory(), $this->profileField->title);
return $labels;
}
@ -298,7 +305,7 @@ class BaseType extends \yii\base\Model
*/
public function beforeProfileSave($value)
{
if ($value == "") {
if ($value == '') {
return null;
}
@ -312,7 +319,6 @@ class BaseType extends \yii\base\Model
*/
public function loadDefaults(Profile $profile)
{
}
}

View File

@ -23,7 +23,7 @@ use humhub\components\access\StrictAccess;
use tests\codeception\_support\HumHubDbTestCase;
use Yii;
class ControllerAccessTest extends HumHubDbTestCase
class TestControllerAccess extends HumHubDbTestCase
{
public $fixtureConfig = ['default'];

View File

@ -178,8 +178,6 @@ class CoreJsConfig extends Widget
'text' => [
'success.archive' => Yii::t('ContentModule.widgets_views_stream', 'The content has been archived.'),
'success.unarchive' => Yii::t('ContentModule.widgets_views_stream', 'The content has been unarchived.'),
'success.pin' => Yii::t('ContentModule.widgets_views_stream', 'The content has been pinned.'),
'success.unpin' => Yii::t('ContentModule.widgets_views_stream', 'The content has been unpinned.'),
'success.delete' => Yii::t('ContentModule.widgets_views_stream', 'The content has been deleted.'),
'info.editCancel' => Yii::t('ContentModule.widgets_views_stream', 'Your last edit state has been saved!'),
]

View File

@ -100,9 +100,11 @@ humhub.module('space.chooser', function (module, require, $) {
var increments = {};
liveEvents.forEach(function (event) {
if (event.data.uguid || event.data.originator === user.guid()) {
if (event.data.uguid || event.data.originator === user.guid() || event.data.silent) {
return;
} else if (increments[event.data.sguid]) {
}
if (increments[event.data.sguid]) {
increments[event.data.sguid]++;
} else {
increments[event.data.sguid] = 1;

View File

@ -1,5 +1,4 @@
{
"name": "App",
"icons": [
{
"src": "\/android-icon-36x36.png",

View File

@ -1,6 +1,11 @@
<link href="<?= $this->theme->getBaseUrl(); ?>/css/theme.css" rel="stylesheet">
<link href="<?= $this->theme->getBaseUrl(); ?>/font/open_sans/open-sans.css" rel="stylesheet">
<!-- start: Web App Data-->
<link rel="manifest" href="<?= $this->theme->getBaseUrl(); ?>/ico/manifest.json">
<meta name="application-name" content="<?= \yii\helpers\Html::encode(Yii::$app->name) ?>">
<!-- end: Web App Data-->
<!-- start: Favicon and Touch Icons -->
<link rel="apple-touch-icon" sizes="57x57" href="<?= $this->theme->getBaseUrl(); ?>/ico/apple-icon-57x57.png">
<link rel="apple-touch-icon" sizes="60x60" href="<?= $this->theme->getBaseUrl(); ?>/ico/apple-icon-60x60.png">
@ -15,8 +20,19 @@
<link rel="icon" type="image/png" sizes="32x32" href="<?= $this->theme->getBaseUrl(); ?>/ico/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="96x96" href="<?= $this->theme->getBaseUrl(); ?>/ico/favicon-96x96.png">
<link rel="icon" type="image/png" sizes="16x16" href="<?= $this->theme->getBaseUrl(); ?>/ico/favicon-16x16.png">
<link rel="manifest" href="<?= $this->theme->getBaseUrl(); ?>/ico/manifest.json">
<meta name="msapplication-TileColor" content="#ffffff">
<meta name="msapplication-TileImage" content="<?= $this->theme->getBaseUrl(); ?>/ico/ms-icon-144x144.png">
<meta name="theme-color" content="#ffffff">
<!-- end: Favicon and Touch Icons -->
<!-- start: Apple Fullscreen and Webapp Title -->
<meta name="apple-mobile-web-app-title" content="<?= \yii\helpers\Html::encode(Yii::$app->name) ?>" />
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="black" />
<!-- end: Apple Fullscreen and Webapp Title -->
<!-- start: Android Fullscreen -->
<meta name="mobile-web-app-capable" content="yes">
<!-- end: Android Fullscreen -->