mirror of
https://github.com/humhub/humhub.git
synced 2025-01-16 21:58:17 +01:00
Initial Notification Rewrite + Markdown posts (experimental).
This commit is contained in:
parent
52d19d5c1d
commit
4d5bc8708e
@ -51,7 +51,8 @@
|
||||
"yiisoft/yii2-debug": "~2.0.0",
|
||||
"yiisoft/yii2-gii": "~2.0.0",
|
||||
"yiisoft/yii2-faker": "~2.0.0",
|
||||
"yiisoft/yii2-apidoc": "~2.0.0"
|
||||
"yiisoft/yii2-apidoc": "~2.0.0",
|
||||
"googlecode/google-api-php-client": "0.6.*"
|
||||
},
|
||||
"config": {
|
||||
"process-timeout": 1800,
|
||||
|
@ -30,7 +30,12 @@ humhub.module('client', function(module, require, $) {
|
||||
};
|
||||
|
||||
Response.prototype.setError = function(errorThrown) {
|
||||
this.error = errorThrown;
|
||||
try {
|
||||
this.error = JSON.parse(this.response);
|
||||
} catch(e) {/* Nothing todo... */}
|
||||
|
||||
this.error = this.error || {};
|
||||
this.errorThrown = errorThrown;
|
||||
this.validationError = (this.status === 400);
|
||||
return this;
|
||||
};
|
||||
|
@ -95,7 +95,10 @@ humhub.module('log', function (module, require, $) {
|
||||
if(msg instanceof Error && level >= TRACE_WARN) {
|
||||
details = msg;
|
||||
msg = this.getMessage(details.message, level, true);
|
||||
} else if(msg.status && level >= TRACE_WARN) {
|
||||
} else if(msg.error && msg.error.message) { // client.Response
|
||||
details = msg;
|
||||
msg = msg.error.message;
|
||||
} else if(msg.status && level >= TRACE_WARN) { // client.Response.status
|
||||
details = msg;
|
||||
msg = this.getMessage(msg.status, level, true);
|
||||
} else if(object.isString(msg) || object.isNumber(msg)) {
|
||||
|
@ -10,6 +10,8 @@ humhub.module('ui.additions', function(module, require, $) {
|
||||
var event = require('event');
|
||||
var object = require('util.object');
|
||||
|
||||
var richtext = require('ui.richtext', true);
|
||||
|
||||
var _additions = {};
|
||||
|
||||
/**
|
||||
@ -23,7 +25,7 @@ humhub.module('ui.additions', function(module, require, $) {
|
||||
*/
|
||||
var register = function(id, selector, handler, options) {
|
||||
options = options || {};
|
||||
|
||||
|
||||
if(!_additions[id] || options.overwrite) {
|
||||
_additions[id] = {
|
||||
'selector': selector,
|
||||
@ -46,8 +48,8 @@ humhub.module('ui.additions', function(module, require, $) {
|
||||
* @returns {undefined}
|
||||
*/
|
||||
var applyTo = function(element, options) {
|
||||
options = options || {};
|
||||
|
||||
options = options || {};
|
||||
|
||||
var $element = (element instanceof $) ? element : $(element);
|
||||
$.each(_additions, function(id) {
|
||||
if(options.filter && !options.filter.indexOf(id)) {
|
||||
@ -106,6 +108,38 @@ humhub.module('ui.additions', function(module, require, $) {
|
||||
});
|
||||
});
|
||||
|
||||
module.register('markdown', '[data-ui-markdown]', function($match) {
|
||||
var converter = new Markdown.Converter();
|
||||
Markdown.Extra.init(converter);
|
||||
$match.each(function() {
|
||||
var $this = $(this);
|
||||
|
||||
if($this.data('markdownProcessed')) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Export all richtext features
|
||||
var features = {};
|
||||
$this.find('[data-richtext-feature]').each(function() {
|
||||
var $this = $(this);
|
||||
features[$this.data('guid')] = $this.clone();
|
||||
$this.replaceWith($this.data('guid'));
|
||||
});
|
||||
|
||||
var text = richtext.Richtext.plainText($this.clone());
|
||||
var result = converter.makeHtml(text);
|
||||
|
||||
// Rewrite richtext feature
|
||||
$.each(features, function(guid, $element) {
|
||||
result = result.replace(guid.trim(), $('<div></div>').html($element).html());
|
||||
});
|
||||
|
||||
|
||||
$this.html(result).data('markdownProcessed', true);
|
||||
});
|
||||
});
|
||||
|
||||
$(document).on('click.humhub-ui-tooltip', function() {
|
||||
$('.tooltip').remove();
|
||||
});
|
||||
@ -117,8 +151,8 @@ humhub.module('ui.additions', function(module, require, $) {
|
||||
|
||||
// Activate placeholder text for older browsers (specially IE)
|
||||
/*this.register('placeholder','input, textarea', function($match) {
|
||||
$match.placeholder();
|
||||
});*/
|
||||
$match.placeholder();
|
||||
});*/
|
||||
|
||||
// Replace the standard checkbox and radio buttons
|
||||
module.register('forms', ':checkbox, :radio', function($match) {
|
||||
@ -130,10 +164,10 @@ humhub.module('ui.additions', function(module, require, $) {
|
||||
$match.loader();
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
var extend = function(id, handler, options) {
|
||||
options = options || {};
|
||||
|
||||
|
||||
if(_additions[id]) {
|
||||
var addition = _additions[id];
|
||||
if(options.prepend) {
|
||||
@ -141,21 +175,21 @@ humhub.module('ui.additions', function(module, require, $) {
|
||||
} else {
|
||||
addition.handler = object.chain(addition.handler, addition.handler, handler);
|
||||
}
|
||||
|
||||
|
||||
if(options.selector && options.selector !== addition.selector) {
|
||||
addition.selector += ','+options.selector;
|
||||
addition.selector += ',' + options.selector;
|
||||
}
|
||||
|
||||
|
||||
if(options.applyOnInit) {
|
||||
module.apply('body', id);
|
||||
}
|
||||
|
||||
} else if(options.selector){
|
||||
|
||||
} else if(options.selector) {
|
||||
options.extend = false; // Make sure we don't get caught in a loop somehow.
|
||||
module.register(id, options.selector, handler, options);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//TODO: additions.extend('id', handler); for extending existing additions.
|
||||
|
||||
/**
|
||||
@ -201,7 +235,7 @@ humhub.module('ui.additions', function(module, require, $) {
|
||||
} else if(!options) {
|
||||
options = {};
|
||||
}
|
||||
|
||||
|
||||
node = (node instanceof $) ? node[0] : node;
|
||||
|
||||
var observer = new MutationObserver(function(mutations) {
|
||||
|
@ -114,7 +114,7 @@ humhub.module('ui.richtext', function(module, require, $) {
|
||||
sel.addRange(range);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Empty spans prevent text deletions in some browsers, so we have to get sure there are no empty spans present.
|
||||
* @param {type} $node
|
||||
@ -259,17 +259,17 @@ humhub.module('ui.richtext', function(module, require, $) {
|
||||
tooltip = tooltip || this.options.disabledText;
|
||||
this.$.removeAttr('contenteditable').attr({
|
||||
disabled: 'disabled',
|
||||
title : tooltip,
|
||||
title: tooltip,
|
||||
}).tooltip({
|
||||
placement : 'bottom'
|
||||
placement: 'bottom'
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
Richtext.prototype.clear = function() {
|
||||
this.$.html('');
|
||||
this.checkPlaceholder();
|
||||
};
|
||||
|
||||
|
||||
Richtext.prototype.focus = function() {
|
||||
this.$.trigger('focus');
|
||||
};
|
||||
@ -294,7 +294,17 @@ humhub.module('ui.richtext', function(module, require, $) {
|
||||
}
|
||||
});
|
||||
|
||||
var html = $clone.html();
|
||||
return Richtext.plainText($clone);
|
||||
};
|
||||
|
||||
Richtext.plainText = function(element, options) {
|
||||
options = options || {};
|
||||
var $element = element instanceof $ ? element : $(element);
|
||||
|
||||
var html = $element.html();
|
||||
|
||||
// remove all line breaks
|
||||
html = html.replace(/(?:\r\n|\r|\n)/g, "");
|
||||
|
||||
// replace html space
|
||||
html = html.replace(/\ /g, ' ');
|
||||
@ -309,18 +319,17 @@ humhub.module('ui.richtext', function(module, require, $) {
|
||||
html = html.replace(/\<p>\<br\s*\\*>\<\/p>/g, '<br>');
|
||||
html = html.replace(/\<\/p>/g, '<br>');
|
||||
|
||||
// remove all line breaks
|
||||
html = html.replace(/(?:\r\n|\r|\n)/g, "");
|
||||
|
||||
// At.js adds a zwj at the end of each mentioning
|
||||
html = html.replace(/\u200d/g,'');
|
||||
html = html.replace(/\u200d/g, '');
|
||||
|
||||
// replace all <br> with new line break
|
||||
$clone.html(html.replace(/\<br\s*\>/g, '\n'));
|
||||
html = html.replace(/\<br\s*\>/g, '\n');
|
||||
|
||||
// return plain text without html tags
|
||||
var $clone = (options.clone) ? $element.clone() : $element;
|
||||
$clone.html(html);
|
||||
return $clone.text().trim();
|
||||
};
|
||||
}
|
||||
|
||||
Richtext.features = {};
|
||||
|
||||
|
@ -110,8 +110,10 @@
|
||||
// assign label to checkbox
|
||||
$this.parent().attr('for', $this.attr('id'));
|
||||
|
||||
var $checkbox = $('<div class="regular-checkbox-box"></div>').attr('style', $this.attr('style'));
|
||||
|
||||
// add new checkbox element
|
||||
$this.parent().append('<div class="regular-checkbox-box"></div>');
|
||||
$this.parent().append($checkbox);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,78 +1,323 @@
|
||||
// Markdown
|
||||
.markdown-render {
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4,
|
||||
h5,
|
||||
h6 {
|
||||
font-weight: bold !important;
|
||||
}
|
||||
h1 {
|
||||
font-size: 28px !important;
|
||||
}
|
||||
h2 {
|
||||
font-size: 24px !important;
|
||||
}
|
||||
h3 {
|
||||
font-size: 18px !important;
|
||||
}
|
||||
h4 {
|
||||
font-size: 16px !important;
|
||||
}
|
||||
h5 {
|
||||
font-size: 14px !important;
|
||||
}
|
||||
h6 {
|
||||
color: #999;
|
||||
font-size: 14px !important;
|
||||
}
|
||||
pre {
|
||||
padding: 0;
|
||||
border: none;
|
||||
border-radius: 3px;
|
||||
code {
|
||||
padding: 10px;
|
||||
border-radius: 3px;
|
||||
font-size: 12px !important;
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4,
|
||||
h5,
|
||||
h6 {
|
||||
font-weight: bold !important;
|
||||
}
|
||||
}
|
||||
a,
|
||||
a:visited {
|
||||
background-color: inherit;
|
||||
text-decoration: none;
|
||||
color: @info !important;
|
||||
}
|
||||
img {
|
||||
max-width: 100%;
|
||||
display: table-cell !important;
|
||||
}
|
||||
|
||||
table {
|
||||
width: 100%;
|
||||
th {
|
||||
font-size: 13px;
|
||||
font-weight: 700;
|
||||
color: @font3;
|
||||
h1 {
|
||||
font-size: 28px !important;
|
||||
}
|
||||
h2 {
|
||||
font-size: 24px !important;
|
||||
}
|
||||
h3 {
|
||||
font-size: 18px !important;
|
||||
}
|
||||
h4 {
|
||||
font-size: 16px !important;
|
||||
}
|
||||
h5 {
|
||||
font-size: 14px !important;
|
||||
}
|
||||
h6 {
|
||||
color: #999;
|
||||
font-size: 14px !important;
|
||||
}
|
||||
pre {
|
||||
padding: 0;
|
||||
border: none;
|
||||
border-radius: 3px;
|
||||
code {
|
||||
padding: 10px;
|
||||
border-radius: 3px;
|
||||
font-size: 12px !important;
|
||||
}
|
||||
}
|
||||
a,
|
||||
a:visited {
|
||||
background-color: inherit;
|
||||
text-decoration: none;
|
||||
color: @info !important;
|
||||
}
|
||||
img {
|
||||
max-width: 100%;
|
||||
display: table-cell !important;
|
||||
}
|
||||
|
||||
thead {
|
||||
tr {
|
||||
border-bottom: 1px solid @background3;
|
||||
}
|
||||
}
|
||||
table {
|
||||
width: 100%;
|
||||
th {
|
||||
font-size: 13px;
|
||||
font-weight: 700;
|
||||
color: @font3;
|
||||
}
|
||||
|
||||
tbody tr td, thead tr th {
|
||||
border: 1px solid @background3 !important;
|
||||
padding: 4px;
|
||||
thead {
|
||||
tr {
|
||||
border-bottom: 1px solid @background3;
|
||||
}
|
||||
}
|
||||
|
||||
tbody tr td, thead tr th {
|
||||
border: 1px solid @background3 !important;
|
||||
padding: 4px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.md-editor.active {
|
||||
border: 2px solid @info !important;
|
||||
border: 2px solid @info !important;
|
||||
}
|
||||
|
||||
.md-editor textarea {
|
||||
padding: 10px !important;
|
||||
}
|
||||
padding: 10px !important;
|
||||
}
|
||||
|
||||
[data-ui-markdown] {
|
||||
|
||||
word-break: break-all;
|
||||
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
margin: 0 0 1em 0;
|
||||
text-align: start;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 2.6em !important;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 2.15em !important;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: 1.7em !important;
|
||||
}
|
||||
|
||||
h4 {
|
||||
font-size: 1.25em !important;
|
||||
}
|
||||
|
||||
h5 {
|
||||
font-size: 1em !important;
|
||||
}
|
||||
|
||||
h6 {
|
||||
font-size: .85em !important;
|
||||
}
|
||||
|
||||
p, pre, blockquote {
|
||||
margin: 0 0 1.1em;
|
||||
}
|
||||
|
||||
blockquote {
|
||||
border-left-width: 10px;
|
||||
background-color: rgba(128,128,128,0.05);
|
||||
border-top-right-radius: 5px;
|
||||
border-bottom-right-radius: 5px;
|
||||
padding: 15px 20px;
|
||||
font-size: 1em;
|
||||
border-left: 5px solid #888888;
|
||||
|
||||
}
|
||||
|
||||
table {
|
||||
margin-bottom: 20px;
|
||||
max-width: 100%;
|
||||
background-color: transparent;
|
||||
border-collapse: collapse;
|
||||
border-spacing: 0px;
|
||||
}
|
||||
|
||||
table caption+thead tr:first-child th,
|
||||
table caption+thead tr:first-child td,
|
||||
table colgroup+thead tr:first-child th,
|
||||
table colgroup+thead tr:first-child td,
|
||||
table thead:first-child tr:first-child th,
|
||||
table thead:first-child tr:first-child td {
|
||||
border-top: 0px;
|
||||
}
|
||||
|
||||
table thead th {
|
||||
vertical-align: bottom;
|
||||
}
|
||||
|
||||
table th {
|
||||
font-weight: bold;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
table th, table td {
|
||||
padding: 8px;
|
||||
line-height: 20px;
|
||||
vertical-align: top;
|
||||
border-top: 1px solid #ddd;
|
||||
}
|
||||
|
||||
dt, dd {
|
||||
margin-top: 5px;
|
||||
margin-bottom: 5px;
|
||||
line-height: 1.45;
|
||||
}
|
||||
|
||||
dt {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
dd {
|
||||
margin-left: 40px;
|
||||
}
|
||||
|
||||
pre {
|
||||
text-align: start;
|
||||
border: 0;
|
||||
padding: 10px 20px;
|
||||
border-radius: 5px;
|
||||
code {
|
||||
white-space: pre !important;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
blockquote ul:last-child, blockquote ol:last-child {
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
|
||||
ul, ol {
|
||||
margin-top: 0;
|
||||
margin-bottom: 10.5px;
|
||||
}
|
||||
|
||||
.footnote {
|
||||
vertical-align: top;
|
||||
position: relative;
|
||||
top: -0.5em;
|
||||
font-size: .8em;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
blockquote {
|
||||
border-left: 2px dotted #888;
|
||||
padding-left: 5px;
|
||||
background: #d0f0ff;
|
||||
}
|
||||
|
||||
.wmd-panel
|
||||
{
|
||||
//margin-left: 25%;
|
||||
//margin-right: 25%;
|
||||
//width: 50%;
|
||||
min-width: 500px;
|
||||
}
|
||||
|
||||
.wmd-button-bar
|
||||
{
|
||||
width: 100%;
|
||||
background-color: Silver;
|
||||
}
|
||||
|
||||
.wmd-input
|
||||
{
|
||||
height: 300px;
|
||||
width: 100%;
|
||||
background-color: Gainsboro;
|
||||
border: 1px solid DarkGray;
|
||||
}
|
||||
|
||||
.wmd-preview
|
||||
{
|
||||
//background-color: #c0e0ff;
|
||||
}
|
||||
|
||||
.wmd-button-row
|
||||
{
|
||||
position: relative;
|
||||
margin-left: 5px;
|
||||
margin-right: 5px;
|
||||
margin-bottom: 5px;
|
||||
margin-top: 10px;
|
||||
padding: 0px;
|
||||
height: 20px;
|
||||
}
|
||||
|
||||
.wmd-spacer
|
||||
{
|
||||
width: 1px;
|
||||
height: 20px;
|
||||
margin-left: 14px;
|
||||
|
||||
position: absolute;
|
||||
background-color: Silver;
|
||||
display: inline-block;
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
.wmd-button {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
padding-left: 2px;
|
||||
padding-right: 3px;
|
||||
position: absolute;
|
||||
display: inline-block;
|
||||
list-style: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.wmd-button > span {
|
||||
background-image: url(../img/wmd-buttons.png);
|
||||
background-repeat: no-repeat;
|
||||
background-position: 0px 0px;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.wmd-spacer1
|
||||
{
|
||||
left: 50px;
|
||||
}
|
||||
.wmd-spacer2
|
||||
{
|
||||
left: 175px;
|
||||
}
|
||||
.wmd-spacer3
|
||||
{
|
||||
left: 300px;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
.wmd-prompt-background
|
||||
{
|
||||
background-color: Black;
|
||||
}
|
||||
|
||||
.wmd-prompt-dialog
|
||||
{
|
||||
border: 1px solid #999999;
|
||||
background-color: #F5F5F5;
|
||||
}
|
||||
|
||||
.wmd-prompt-dialog > div {
|
||||
font-size: 0.8em;
|
||||
font-family: arial, helvetica, sans-serif;
|
||||
}
|
||||
|
||||
|
||||
.wmd-prompt-dialog > form > input[type="text"] {
|
||||
border: 1px solid #999999;
|
||||
color: black;
|
||||
}
|
||||
|
||||
.wmd-prompt-dialog > form > input[type="button"]{
|
||||
border: 1px solid #888888;
|
||||
font-family: trebuchet MS, helvetica, sans-serif;
|
||||
font-size: 0.8em;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
@ -5,7 +5,7 @@ return [
|
||||
'modules' => [
|
||||
'debug' => [
|
||||
'class' => 'yii\debug\Module',
|
||||
//'allowedIPs' => ['*'],
|
||||
'allowedIPs' => ['*'],
|
||||
],
|
||||
],
|
||||
];
|
||||
|
@ -92,6 +92,7 @@ class AppAsset extends AssetBundle
|
||||
'humhub\assets\NProgressAsset',
|
||||
'humhub\assets\IE9FixesAsset',
|
||||
'humhub\assets\IEFixesAsset',
|
||||
'humhub\assets\PagedownConverterAsset',
|
||||
];
|
||||
|
||||
}
|
||||
|
40
protected/humhub/assets/PagedownConverterAsset.php
Normal file
40
protected/humhub/assets/PagedownConverterAsset.php
Normal file
@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @link https://www.humhub.org/
|
||||
* @copyright Copyright (c) 2015 HumHub GmbH & Co. KG
|
||||
* @license https://www.humhub.com/licences
|
||||
*/
|
||||
|
||||
namespace humhub\assets;
|
||||
|
||||
use yii\web\AssetBundle;
|
||||
|
||||
/**
|
||||
* jquery-highlight
|
||||
*
|
||||
* @author buddha
|
||||
*/
|
||||
class PagedownConverterAsset extends AssetBundle
|
||||
{
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public $basePath = '@webroot';
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public $baseUrl = '@web';
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public $js = [
|
||||
'resources/js/pagedown/Markdown.Converter.js',
|
||||
'resources/js/pagedown/Markdown.Editor.js',
|
||||
'resources/js/pagedown/Markdown.Extra.js',
|
||||
];
|
||||
|
||||
}
|
@ -327,5 +327,10 @@ class Module extends \yii\base\Module
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
public function hasNotifications()
|
||||
{
|
||||
return !empty($this->getNotifications());
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -48,21 +48,27 @@ class SettingsManager extends BaseSettingsManager
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns ContentContainerSettingsManager for current logged in user
|
||||
* Returns ContentContainerSettingsManager for the given $user or current logged in user
|
||||
* @return ContentContainerSettingsManager
|
||||
*/
|
||||
public function user()
|
||||
public function user($user = null)
|
||||
{
|
||||
return $this->contentContainer(Yii::$app->user->getIdentity());
|
||||
if(!$user) {
|
||||
$user = Yii::$app->user->getIdentity();
|
||||
}
|
||||
|
||||
return $this->contentContainer($user);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns ContentContainerSettingsManager for current logged in user
|
||||
* Returns ContentContainerSettingsManager for the given $space or current controller space
|
||||
* @return ContentContainerSettingsManager
|
||||
*/
|
||||
public function space()
|
||||
public function space($space = null)
|
||||
{
|
||||
if (Yii::$app->controller instanceof \humhub\modules\content\components\ContentContainerController) {
|
||||
if($space != null) {
|
||||
return $this->contentContainer($space);
|
||||
} elseif (Yii::$app->controller instanceof \humhub\modules\content\components\ContentContainerController) {
|
||||
if (Yii::$app->controller->contentContainer instanceof \humhub\modules\space\models\Space) {
|
||||
return $this->contentContainer(Yii::$app->controller->contentContainer);
|
||||
}
|
||||
|
@ -8,25 +8,27 @@
|
||||
|
||||
namespace humhub\components;
|
||||
|
||||
use humhub\modules\notification\models\Notification;
|
||||
use humhub\modules\content\components\ContentActiveRecord;
|
||||
use Yii;
|
||||
use yii\helpers\Html;
|
||||
use humhub\modules\content\components\ContentContainerActiveRecord;
|
||||
use humhub\modules\content\components\ContentAddonActiveRecord;
|
||||
use humhub\libs\Viewable;
|
||||
use humhub\modules\space\models\Space;
|
||||
use humhub\modules\content\interfaces\ContentOwner;
|
||||
use humhub\widgets\RichText;
|
||||
|
||||
/**
|
||||
* Name (SocialEvent/NetworkEvent/SocialActivity/BaseEvent)
|
||||
*
|
||||
* This class represents an social activity triggered within the network.
|
||||
* An activity instance can be linked to an $originator user, which performed the activity.
|
||||
* This class represents a social Activity triggered within the network.
|
||||
*
|
||||
* The activity mainly provides functions for rendering the output for different channels as
|
||||
* web, mail or plain-text.
|
||||
* A SocialActivity can be assigned with an originator User, which triggered the activity and a source ActiveRecord.
|
||||
* The source is used to connect the SocialActivity to a related Content, ContentContainerActiveRecord or any other
|
||||
* ActiveRecord.
|
||||
*
|
||||
* Since SocialActivities need to be rendered in most cases it implements the humhub\components\rendering\Viewable interface and provides
|
||||
* a default implementation of the getViewParams function.
|
||||
*
|
||||
* @since 1.1
|
||||
* @author buddha
|
||||
*/
|
||||
abstract class SocialActivity extends Viewable
|
||||
abstract class SocialActivity extends \yii\base\Object implements rendering\Viewable
|
||||
{
|
||||
|
||||
/**
|
||||
@ -43,42 +45,168 @@ abstract class SocialActivity extends Viewable
|
||||
*/
|
||||
public $source;
|
||||
|
||||
/**
|
||||
* The content container this activity belongs to.
|
||||
*
|
||||
* If the source object is a type of Content/ContentAddon or ContentContainer the container
|
||||
* will be automatically set.
|
||||
*
|
||||
* @var ContentContainerActiveRecord
|
||||
*/
|
||||
public $container = null;
|
||||
|
||||
/**
|
||||
* @var string the module id which this activity belongs to (required)
|
||||
*/
|
||||
public $moduleId = "";
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* The notification record this notification belongs to
|
||||
*
|
||||
* @var Notification
|
||||
* An SocialActivity can be represented in the database as ActiveRecord.
|
||||
* By defining the $recordClass an ActiveRecord will be created automatically within the
|
||||
* init function.
|
||||
*
|
||||
* @var \yii\db\ActiveRecord The related record for this activitiy
|
||||
*/
|
||||
public $record;
|
||||
|
||||
/**
|
||||
* @var string Record class used for instantiation.
|
||||
*/
|
||||
public $recordClass;
|
||||
|
||||
/**
|
||||
* @var string view name used for rendering the activity
|
||||
*/
|
||||
public $viewName = 'default.php';
|
||||
|
||||
public function init()
|
||||
{
|
||||
parent::init();
|
||||
if($this->recordClass) {
|
||||
$this->record = Yii::createObject($this->recordClass, [
|
||||
'class' => $this->className()
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Static initializer should be prefered over new initialization, since it makes use
|
||||
* of Yii::createObject dependency injection/configuration.
|
||||
*
|
||||
* @return \humhub\components\SocialActivity
|
||||
*/
|
||||
public static function instance($options = [])
|
||||
{
|
||||
return Yii::createObject(static::class, $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Builder function for the originator.
|
||||
*
|
||||
* @param type $originator
|
||||
* @return \humhub\components\SocialActivity
|
||||
*/
|
||||
public function from($originator)
|
||||
{
|
||||
$this->originator = $originator;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builder function for the source.
|
||||
* @param type $source
|
||||
* @return \humhub\components\SocialActivity
|
||||
*/
|
||||
public function about($source)
|
||||
{
|
||||
$this->source = $source;
|
||||
$this->record->source_pk = $this->source->getPrimaryKey();
|
||||
$this->record->source_class = $this->source->className();
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getViewName()
|
||||
{
|
||||
// If no suffix is given, we assume a php file.
|
||||
if(!strpos($this->viewName, '.')) {
|
||||
return $this->viewName. '.php';
|
||||
} else {
|
||||
return $this->viewName;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
protected function getViewParams($params = [])
|
||||
public function getViewParams($params = [])
|
||||
{
|
||||
$params['originator'] = $this->originator;
|
||||
$params['source'] = $this->source;
|
||||
$params['contentContainer'] = $this->container;
|
||||
$params['record'] = $this->record;
|
||||
if (!isset($params['url'])) {
|
||||
$params['url'] = $this->getUrl();
|
||||
$result = [
|
||||
'originator' => $this->originator,
|
||||
'source' => $this->source,
|
||||
'contentContainer' => $this->getContentContainer(),
|
||||
'space' => $this->getSpace(),
|
||||
'record' => $this->record,
|
||||
'url' => $this->getUrl(),
|
||||
'viewable' => $this,
|
||||
'html' => $this->html(),
|
||||
'text' => $this->text()
|
||||
];
|
||||
|
||||
return \yii\helpers\ArrayHelper::merge($result, $params);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the related content instance in case the source is of type ContentOwner.
|
||||
*
|
||||
* @return \humhub\modules\content\models\Content Content ActiveRecord or null if not related to a ContentOwner source
|
||||
*/
|
||||
public function getContent()
|
||||
{
|
||||
if ($this->hasContent()) {
|
||||
return $this->source->content;
|
||||
}
|
||||
|
||||
return $params;
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Space related space instance in case the activity source is an related contentcontainer of type space, otherwise null
|
||||
*/
|
||||
public function getSpace()
|
||||
{
|
||||
$container = $this->getContentContainer();
|
||||
return ($container instanceof Space) ? $container : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return integer related space id in case the activity source is an related contentcontainer of type space, otherwise null
|
||||
*/
|
||||
public function getSpaceId()
|
||||
{
|
||||
$space = $this->getSpace();
|
||||
return ($space) ? $space->id : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if this activity is related to a content. This is the case if the activitiy source
|
||||
* is of type ContentOwner.
|
||||
*
|
||||
* @return boolean true if this activity is related to a ContentOwner else false
|
||||
*/
|
||||
public function hasContent()
|
||||
{
|
||||
return $this->source instanceof ContentOwner;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if the activity source is related to an ContentContainer.
|
||||
* This is the case if the source is either a ContentContainerActiveRecord itself or a ContentOwner.
|
||||
*
|
||||
* @return ContentContainerActiveRecord
|
||||
*/
|
||||
public function getContentContainer()
|
||||
{
|
||||
if ($this->source instanceof ContentContainerActiveRecord) {
|
||||
return $this->source;
|
||||
} else if ($this->hasContent()) {
|
||||
return $this->getContent()->getContainer();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -91,8 +219,8 @@ abstract class SocialActivity extends Viewable
|
||||
{
|
||||
$url = '#';
|
||||
|
||||
if ($this->source instanceof ContentActiveRecord || $this->source instanceof ContentAddonActiveRecord) {
|
||||
$url = $this->source->content->getUrl();
|
||||
if ($this->hasContent()) {
|
||||
$url = $this->getContent()->getUrl();
|
||||
} elseif ($this->source instanceof ContentContainerActiveRecord) {
|
||||
$url = $this->source->getUrl();
|
||||
}
|
||||
@ -105,6 +233,55 @@ abstract class SocialActivity extends Viewable
|
||||
return $url;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function text()
|
||||
{
|
||||
$html = $this->html();
|
||||
return !empty($html) ? strip_tags($html) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function html()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function json()
|
||||
{
|
||||
return \yii\helpers\Json::encode($this->asArray());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array representation of this notification.
|
||||
*/
|
||||
public function asArray()
|
||||
{
|
||||
$result = [
|
||||
'class' => $this->className(),
|
||||
'text' => $this->text(),
|
||||
'html' => $this->html()
|
||||
];
|
||||
|
||||
if($this->originator) {
|
||||
$result['originator_id'] = $this->originator->id;
|
||||
}
|
||||
|
||||
if ($this->source) {
|
||||
$result['source_class'] = $this->source->className();
|
||||
$result['source_pk'] = $this->source->getPrimaryKey();
|
||||
$result['space_id'] = $this->source->getSpaceId();
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build info text about a content
|
||||
*
|
||||
@ -114,11 +291,11 @@ abstract class SocialActivity extends Viewable
|
||||
* @param Content $content
|
||||
* @return string
|
||||
*/
|
||||
public function getContentInfo(\humhub\modules\content\interfaces\ContentTitlePreview $content)
|
||||
public function getContentInfo(ContentOwner $content)
|
||||
{
|
||||
return \yii\helpers\Html::encode($content->getContentName()) .
|
||||
return Html::encode($content->getContentName()) .
|
||||
' "' .
|
||||
\humhub\widgets\RichText::widget(['text' => $content->getContentDescription(), 'minimal' => true, 'maxLength' => 60]) . '"';
|
||||
RichText::widget(['text' => $content->getContentDescription(), 'minimal' => true, 'maxLength' => 60]) . '"';
|
||||
}
|
||||
|
||||
}
|
||||
|
59
protected/humhub/components/rendering/LayoutRenderer.php
Normal file
59
protected/humhub/components/rendering/LayoutRenderer.php
Normal file
@ -0,0 +1,59 @@
|
||||
<?php
|
||||
|
||||
namespace humhub\components\rendering;
|
||||
|
||||
use Yii;
|
||||
|
||||
/**
|
||||
* A LayoutRenderer subclass can be used to render layout based views by setting the $viewPath and $layout properties.
|
||||
*
|
||||
* The $viewPath defines the path where the target view file resides.
|
||||
* For a viewable with the viewName 'myView.php' the renderer will render the view:
|
||||
*
|
||||
* '<viewPath>/myView.php'
|
||||
*
|
||||
* where viewPath can also be provided as a Yii alias.
|
||||
*
|
||||
* The rendered view will be embeded into the given $layout which should point to the layout file
|
||||
* and can also be provided as a Yii alias e.g:
|
||||
*
|
||||
* '@myModule/views/layouts/myLayout.php'
|
||||
*
|
||||
* @author buddha
|
||||
*/
|
||||
class LayoutRenderer extends ViewPathRenderer
|
||||
{
|
||||
|
||||
/**
|
||||
* @var string layout file path
|
||||
*/
|
||||
public $layout;
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function render(Viewable $viewable, $params = [])
|
||||
{
|
||||
// Render the view itself
|
||||
$viewParams = $viewable->getViewParams($params);
|
||||
|
||||
if(!isset($viewParams['content'])) {
|
||||
$viewParams['content'] = parent::renderView($viewable, $viewParams);
|
||||
}
|
||||
|
||||
$layout = $this->getLayout($viewable);
|
||||
|
||||
// Embed view into layout if provided
|
||||
if ($layout) {
|
||||
return Yii::$app->getView()->renderFile($layout, $viewParams, $viewable);
|
||||
} else {
|
||||
return $viewParams['content'];
|
||||
}
|
||||
}
|
||||
|
||||
protected function getLayout(Viewable $viewable)
|
||||
{
|
||||
return $this->layout;
|
||||
}
|
||||
|
||||
}
|
42
protected/humhub/components/rendering/MailLayoutRenderer.php
Normal file
42
protected/humhub/components/rendering/MailLayoutRenderer.php
Normal file
@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
namespace humhub\components\rendering;
|
||||
|
||||
use Yii;
|
||||
|
||||
/**
|
||||
* Description of MailLayoutRenderer
|
||||
*
|
||||
* @author buddha
|
||||
*/
|
||||
class MailLayoutRenderer extends LayoutRenderer
|
||||
{
|
||||
/**
|
||||
* Layout for text rendering.
|
||||
* @var type
|
||||
*/
|
||||
public $textLayout;
|
||||
|
||||
/**
|
||||
* Used for rendering text mail content, by embedding the rendered view into
|
||||
* a $textLayout and removing all html elemtns.
|
||||
*
|
||||
* @param \humhub\components\rendering\Viewable $viewable
|
||||
* @return type
|
||||
*/
|
||||
public function renderText(Viewable $viewable , $params = [])
|
||||
{
|
||||
$textRenderer = new LayoutRenderer([
|
||||
'layout' => $this->getTextLayout($viewable)
|
||||
]);
|
||||
|
||||
$params['content'] = $viewable->text();
|
||||
|
||||
return strip_tags($textRenderer->render($viewable, $params));
|
||||
}
|
||||
|
||||
public function getTextLayout(Viewable $viewable )
|
||||
{
|
||||
return $this->textLayout;
|
||||
}
|
||||
}
|
25
protected/humhub/components/rendering/Renderer.php
Normal file
25
protected/humhub/components/rendering/Renderer.php
Normal file
@ -0,0 +1,25 @@
|
||||
<?php
|
||||
namespace humhub\components\rendering;
|
||||
|
||||
/**
|
||||
* Renderer interface used by render components to render Viewable instances.
|
||||
*
|
||||
* A Renderer implementation is responsible for rendering the viewable either by using it's viewName or
|
||||
* by converting it's data into a specific format.
|
||||
*
|
||||
* @author buddha
|
||||
*/
|
||||
interface Renderer
|
||||
{
|
||||
/**
|
||||
* Renders the given $viewable.
|
||||
*
|
||||
* The renderer will usually use the $viewable->viewName to determine the target view and
|
||||
* forward the given $params to $viewable->getViewParams($params). By doing so, the
|
||||
* $params can be used to overwrite the default view parameter of $viewable.
|
||||
*
|
||||
* @param \humhub\components\rendering\Viewable $viewable
|
||||
* @param type $params
|
||||
*/
|
||||
public function render(Viewable $viewable, $params = []);
|
||||
}
|
77
protected/humhub/components/rendering/ViewPathRenderer.php
Normal file
77
protected/humhub/components/rendering/ViewPathRenderer.php
Normal file
@ -0,0 +1,77 @@
|
||||
<?php
|
||||
|
||||
namespace humhub\components\rendering;
|
||||
|
||||
use Yii;
|
||||
|
||||
/**
|
||||
* A ViewPathRender is a simple Renderer implementation for rendering Viewable
|
||||
* instances by searching for the Viewable viewName within the given $viewPath.
|
||||
*
|
||||
* If no $viewPath is given, we'll determine the view path of the viewable as following:
|
||||
*
|
||||
* ViewableClassPath/../views
|
||||
*
|
||||
* @author buddha
|
||||
*/
|
||||
class ViewPathRenderer extends \yii\base\Object implements Renderer
|
||||
{
|
||||
|
||||
/**
|
||||
* @var string view path
|
||||
*/
|
||||
public $viewPath;
|
||||
|
||||
/**
|
||||
* Renders the viewable by searching the viewable's viewName within the given viewPath.
|
||||
*
|
||||
* If no viewPath is given this function uses '../views/viewName' as view file path.
|
||||
*
|
||||
* @param \humhub\components\rendering\Viewable $viewable
|
||||
* @return type
|
||||
*/
|
||||
public function render(Viewable $viewable, $params = [])
|
||||
{
|
||||
return $this->renderView($viewable, $viewable->getViewParams($params));
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function for rendering a Viewable with the given viewParams.
|
||||
*
|
||||
* @param \humhub\components\rendering\Viewable $viewable
|
||||
* @param type $viewParams
|
||||
* @return type
|
||||
*/
|
||||
public function renderView(Viewable $viewable, $viewParams)
|
||||
{
|
||||
$viewFile = $this->getViewFile($viewable);
|
||||
return Yii::$app->getView()->renderFile($viewFile, $viewParams, $viewable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returnes the viewFile of the given Viewable.
|
||||
*
|
||||
* @param \humhub\components\rendering\Viewable $viewable
|
||||
* @return type
|
||||
*/
|
||||
public function getViewFile(Viewable $viewable)
|
||||
{
|
||||
return $this->getViewPath($viewable) . '/' . $viewable->getViewName();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the directory containing the view files for this event.
|
||||
* The default implementation returns the 'views' subdirectory under the directory containing the notification class file.
|
||||
* @return string the directory containing the view files for this notification.
|
||||
*/
|
||||
public function getViewPath(Viewable $viewable)
|
||||
{
|
||||
if ($this->viewPath !== null) {
|
||||
return Yii::getAlias($this->viewPath);
|
||||
}
|
||||
|
||||
$class = new \ReflectionClass($viewable);
|
||||
return dirname(dirname($class->getFileName())) . DIRECTORY_SEPARATOR . 'views';
|
||||
}
|
||||
|
||||
}
|
39
protected/humhub/components/rendering/Viewable.php
Normal file
39
protected/humhub/components/rendering/Viewable.php
Normal file
@ -0,0 +1,39 @@
|
||||
<?php
|
||||
namespace humhub\components\rendering;
|
||||
|
||||
/**
|
||||
* The Viewable interface is used for Classes that can be rendered by Renderer components.
|
||||
* A Renderer can make use of the html, json or text represenation when rendering a viewable.
|
||||
*
|
||||
* @author buddha
|
||||
*/
|
||||
interface Viewable
|
||||
{
|
||||
/**
|
||||
* Returns an array of view parameter, required for rendering.
|
||||
*
|
||||
* @param array $params
|
||||
*/
|
||||
public function getViewParams($params = []);
|
||||
|
||||
|
||||
/**
|
||||
* @return string viewname of this viewable
|
||||
*/
|
||||
public function getViewName();
|
||||
|
||||
/**
|
||||
* @return string html content representation of this viewable.
|
||||
*/
|
||||
public function html();
|
||||
|
||||
/**
|
||||
* @return string json content representation of this viewable.
|
||||
*/
|
||||
public function json();
|
||||
|
||||
/**
|
||||
* @return string text content representation of this viewable.
|
||||
*/
|
||||
public function text();
|
||||
}
|
@ -1,11 +1,4 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
|
||||
namespace humhub\components\validators;
|
||||
|
||||
use yii\validators\Validator;
|
||||
|
@ -1,11 +1,4 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
|
||||
namespace humhub\components\validators;
|
||||
|
||||
use Yii;
|
||||
|
@ -16,6 +16,20 @@ $config = [
|
||||
'moduleManager' => [
|
||||
'class' => '\humhub\components\ModuleManager'
|
||||
],
|
||||
'notification' => [
|
||||
'class' => 'humhub\modules\notification\components\NotificationManager',
|
||||
'targets' => [
|
||||
[
|
||||
'class' => 'humhub\modules\notification\components\WebNotificationTarget',
|
||||
'renderer' => ['class' => 'humhub\modules\notification\components\WebTargetRenderer']
|
||||
],
|
||||
[
|
||||
'class' => 'humhub\modules\notification\components\MailNotificationTarget',
|
||||
'renderer' => ['class' => 'humhub\modules\notification\components\MailTargetRenderer']
|
||||
],
|
||||
//['class' => '\humhub\modules\notification\components\MobileNotificationTarget']
|
||||
]
|
||||
],
|
||||
'log' => [
|
||||
'traceLevel' => YII_DEBUG ? 3 : 0,
|
||||
'targets' => [
|
||||
|
@ -28,4 +28,5 @@ HumHub Change Log
|
||||
- Enh: Picker widgets rewrite (UserPicker/SpacePicker/MultiselectDropdown). (buddha)
|
||||
- Enh: Richtext widget rewrite. (buddha)
|
||||
- Enh: Removed almost all inline JS blocks. (buddha)
|
||||
- Enh: StreamAction now uses flexible StreamQuery Model.
|
||||
- Enh: StreamAction now uses flexible StreamQuery Model. (buddha)
|
||||
- Enh: Post markdown support. (buddha)
|
||||
|
@ -1,158 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @link https://www.humhub.org/
|
||||
* @copyright Copyright (c) 2016 HumHub GmbH & Co. KG
|
||||
* @license https://www.humhub.com/licences
|
||||
*/
|
||||
|
||||
namespace humhub\libs;
|
||||
|
||||
use Yii;
|
||||
use yii\base\Component;
|
||||
use yii\base\ViewContextInterface;
|
||||
|
||||
/**
|
||||
* Viewable provides view rendering support including layout and different
|
||||
* output formats (e.g. text, web or mail=.
|
||||
*
|
||||
* @since 1.1
|
||||
* @author Luke
|
||||
*/
|
||||
abstract class Viewable extends Component implements ViewContextInterface
|
||||
{
|
||||
|
||||
const OUTPUT_WEB = 'web';
|
||||
const OUTPUT_MAIL = 'mail';
|
||||
const OUTPUT_MAIL_PLAINTEXT = 'mail_plaintext';
|
||||
const OUTPUT_TEXT = 'text';
|
||||
|
||||
/**
|
||||
* Name of the view, used for rendering the event
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $viewName = null;
|
||||
|
||||
/**
|
||||
* View path
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $viewPath = null;
|
||||
|
||||
/**
|
||||
* Layout file for web version
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $layoutWeb;
|
||||
|
||||
/**
|
||||
* Layout file for mail version
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $layoutMail;
|
||||
|
||||
/**
|
||||
* Layout file for mail plaintext version
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $layoutMailPlaintext;
|
||||
|
||||
/**
|
||||
* Assambles all parameter required for rendering the view.
|
||||
*
|
||||
* @return array all view parameter
|
||||
*/
|
||||
protected function getViewParams($params = [])
|
||||
{
|
||||
$params['originator'] = $this->originator;
|
||||
$params['source'] = $this->source;
|
||||
$params['contentContainer'] = $this->container;
|
||||
$params['record'] = $this->record;
|
||||
$params['url'] = $this->getUrl();
|
||||
|
||||
return $params;
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the notification
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function render($mode = self::OUTPUT_WEB, $params = [])
|
||||
{
|
||||
$viewFile = $this->getViewFile($mode);
|
||||
$viewParams = $this->getViewParams($params);
|
||||
|
||||
$result = Yii::$app->getView()->renderFile($viewFile, $viewParams, $this);
|
||||
|
||||
if ($mode == self::OUTPUT_TEXT) {
|
||||
return strip_tags($result);
|
||||
}
|
||||
|
||||
$viewParams['content'] = $result;
|
||||
return Yii::$app->getView()->renderFile($this->getLayoutFile($mode), $viewParams, $this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the correct view file
|
||||
*
|
||||
* @param string $mode the output mode
|
||||
* @return string the view file
|
||||
*/
|
||||
protected function getViewFile($mode)
|
||||
{
|
||||
$viewFile = $this->getViewPath() . '/' . $this->viewName . '.php';
|
||||
$alternativeViewFile = "";
|
||||
|
||||
// Lookup alternative view file based on view mode
|
||||
if ($mode == self::OUTPUT_MAIL) {
|
||||
$alternativeViewFile = $this->getViewPath() . '/mail/' . $this->viewName . '.php';
|
||||
} elseif ($mode === self::OUTPUT_MAIL_PLAINTEXT) {
|
||||
$alternativeViewFile = $this->getViewPath() . '/mail/plaintext/' . $this->viewName . '.php';
|
||||
}
|
||||
|
||||
if ($alternativeViewFile != "" && file_exists($alternativeViewFile)) {
|
||||
$viewFile = $alternativeViewFile;
|
||||
}
|
||||
|
||||
return $viewFile;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the layout file
|
||||
*
|
||||
* @param string $mode the output mode
|
||||
* @return string the layout file
|
||||
*/
|
||||
protected function getLayoutFile($mode)
|
||||
{
|
||||
if ($mode == self::OUTPUT_MAIL_PLAINTEXT) {
|
||||
return $this->layoutMailPlaintext;
|
||||
} elseif ($mode == self::OUTPUT_MAIL) {
|
||||
return $this->layoutMail;
|
||||
}
|
||||
|
||||
return $this->layoutWeb;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the directory containing the view files for this event.
|
||||
* The default implementation returns the 'views' subdirectory under the directory containing the notification class file.
|
||||
* @return string the directory containing the view files for this notification.
|
||||
*/
|
||||
public function getViewPath()
|
||||
{
|
||||
if ($this->viewPath !== null) {
|
||||
return Yii::getAlias($this->viewPath);
|
||||
}
|
||||
|
||||
$class = new \ReflectionClass($this);
|
||||
return dirname($class->getFileName()) . DIRECTORY_SEPARATOR . 'views';
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
<?php
|
||||
namespace humhub\modules\activity\components;
|
||||
|
||||
use humhub\components\rendering\MailLayoutRenderer;
|
||||
|
||||
/**
|
||||
* Description of ActivityMailRenderer
|
||||
*
|
||||
* @author buddha
|
||||
*/
|
||||
class ActivityMailRenderer extends MailLayoutRenderer
|
||||
{
|
||||
/**
|
||||
* @var string layout file path
|
||||
*/
|
||||
public $layout = '@activity/views/layouts/mail.php';
|
||||
|
||||
/**
|
||||
* @var string text layout file
|
||||
*/
|
||||
public $textLayout = "@activity/views/layouts/mail_plaintext.php";
|
||||
|
||||
}
|
@ -11,7 +11,7 @@ namespace humhub\modules\activity\components;
|
||||
use humhub\modules\activity\models\Activity;
|
||||
use humhub\modules\content\components\ContentActiveRecord;
|
||||
use humhub\modules\content\components\ContentAddonActiveRecord;
|
||||
use humhub\modules\content\components\ContentContainerActiveRecord;
|
||||
use humhub\modules\content\models\Content;
|
||||
|
||||
/**
|
||||
* BaseActivity is the base class for all activities.
|
||||
@ -22,9 +22,10 @@ abstract class BaseActivity extends \humhub\components\SocialActivity
|
||||
{
|
||||
|
||||
/**
|
||||
* Default content visibility of this Activity.
|
||||
* @var int
|
||||
*/
|
||||
public $visibility = 1;
|
||||
public $visibility = Content::VISIBILITY_PRIVATE;
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
@ -40,6 +41,11 @@ abstract class BaseActivity extends \humhub\components\SocialActivity
|
||||
* @inheritdoc
|
||||
*/
|
||||
public $layoutMailPlaintext = "@humhub/modules/notification/views/layouts/mail_plaintext.php";
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public $recordClass = Activity::class;
|
||||
|
||||
/**
|
||||
* @var boolean
|
||||
@ -55,12 +61,13 @@ abstract class BaseActivity extends \humhub\components\SocialActivity
|
||||
throw new \yii\base\InvalidConfigException("Missing viewName!");
|
||||
}
|
||||
|
||||
if ($this->visibility === null) {
|
||||
$this->visibility = \humhub\modules\content\models\Content::VISIBILITY_PRIVATE;
|
||||
}
|
||||
|
||||
parent::init();
|
||||
}
|
||||
|
||||
public function render($params = array())
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
@ -68,9 +75,13 @@ abstract class BaseActivity extends \humhub\components\SocialActivity
|
||||
public function getViewParams($params = [])
|
||||
{
|
||||
$params['clickable'] = $this->clickable;
|
||||
|
||||
return parent::getViewParams($params);
|
||||
}
|
||||
|
||||
public function save()
|
||||
{
|
||||
return $this->record->save();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an activity model and determines the contentContainer/visibility
|
||||
@ -87,40 +98,51 @@ abstract class BaseActivity extends \humhub\components\SocialActivity
|
||||
throw new \yii\base\InvalidConfigException("Invalid source object given!");
|
||||
}
|
||||
|
||||
if ($this->container == null) {
|
||||
$this->container = $this->getContentContainerFromSource();
|
||||
|
||||
if ($this->container == null) {
|
||||
throw new \yii\base\InvalidConfigException("Could not determine content container for activity!");
|
||||
}
|
||||
}
|
||||
|
||||
$this->saveModelInstance();
|
||||
}
|
||||
|
||||
protected function getContentContainerFromSource()
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function from($originator)
|
||||
{
|
||||
if ($this->hasContentSource()) {
|
||||
return $this->source->content->container;
|
||||
} elseif ($this->source instanceof ContentContainerActiveRecord) {
|
||||
return $this->source;
|
||||
}
|
||||
parent::from($originator);
|
||||
$this->record->content->created_by = $originator->id;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function about($source)
|
||||
{
|
||||
parent::from($source);
|
||||
$this->record->content->visibility = $this->getContentVisibility();
|
||||
return $this;
|
||||
}
|
||||
|
||||
protected function hasContentSource()
|
||||
|
||||
/**
|
||||
* Builder function for setting ContentContainerActiveRecord
|
||||
* @param \humhub\modules\content\components\ContentContainerActiveRecord $container
|
||||
*/
|
||||
public function container($container)
|
||||
{
|
||||
return $this->source instanceof ContentActiveRecord || $this->source instanceof ContentAddonActiveRecord;
|
||||
$this->record->content->container = $container;
|
||||
return $this;
|
||||
}
|
||||
|
||||
private function saveModelInstance()
|
||||
{
|
||||
$model = new Activity();
|
||||
$model->class = $this->className();
|
||||
$model->module = $this->moduleId;
|
||||
$model->object_model = $this->source->className();
|
||||
$model->object_id = $this->source->getPrimaryKey();
|
||||
$model->content->container = $this->container;
|
||||
$model->content->visibility = $this->getContentVisibility();
|
||||
$this->record->source_class = $this->source->className();
|
||||
$this->record->source_pk = $this->source->getPrimaryKey();
|
||||
$this->record->content->visibility = $this->getContentVisibility();
|
||||
|
||||
if (!$this->content->container) {
|
||||
$model->content->container = $this->getContentContainer();
|
||||
|
||||
}
|
||||
|
||||
$model->content->created_by = $this->getOriginatorId();
|
||||
|
||||
if ($model->content->created_by == null) {
|
||||
@ -134,7 +156,7 @@ abstract class BaseActivity extends \humhub\components\SocialActivity
|
||||
|
||||
protected function getContentVisibility()
|
||||
{
|
||||
return $this->hasContentSource() ? $this->source->content->visibility : $this->visibility;
|
||||
return $this->hasContent() ? $this->getContent()->visibility : $this->visibility;
|
||||
}
|
||||
|
||||
protected function getOriginatorId()
|
||||
|
@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
use yii\db\Migration;
|
||||
|
||||
class m161228_131023_rename_source_fields extends Migration
|
||||
{
|
||||
public function up()
|
||||
{
|
||||
$this->renameColumn('activity', 'object_model', 'source_class');
|
||||
$this->renameColumn('activity', 'object_id', 'source_pk');
|
||||
}
|
||||
|
||||
public function down()
|
||||
{
|
||||
echo "m161228_131023_rename_source_fields cannot be reverted.\n";
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
// Use safeUp/safeDown to run migration code within a transaction
|
||||
public function safeUp()
|
||||
{
|
||||
}
|
||||
|
||||
public function safeDown()
|
||||
{
|
||||
}
|
||||
*/
|
||||
}
|
@ -36,6 +36,8 @@ class Activity extends ContentActiveRecord
|
||||
return [
|
||||
[
|
||||
'class' => \humhub\components\behaviors\PolymorphicRelation::className(),
|
||||
'classAttribute' => 'source_class',
|
||||
'pkAttribute' => 'source_pk',
|
||||
'mustBeInstanceOf' => [
|
||||
\yii\db\ActiveRecord::className(),
|
||||
]
|
||||
@ -57,9 +59,9 @@ class Activity extends ContentActiveRecord
|
||||
public function rules()
|
||||
{
|
||||
return [
|
||||
[['object_id'], 'integer'],
|
||||
[['source_pk'], 'integer'],
|
||||
[['class'], 'string', 'max' => 100],
|
||||
[['module', 'object_model'], 'string', 'max' => 100]
|
||||
[['module', 'source_class'], 'string', 'max' => 100]
|
||||
];
|
||||
}
|
||||
|
||||
|
@ -80,7 +80,7 @@ class Module extends \humhub\components\Module
|
||||
{
|
||||
if(Yii::$app->user->isAdmin()) {
|
||||
return [
|
||||
'humhub\modules\user\notifications\NewVersionAvailable'
|
||||
'humhub\modules\admin\notifications\NewVersionAvailable'
|
||||
];
|
||||
}
|
||||
return [];
|
||||
|
@ -12,6 +12,7 @@ use Yii;
|
||||
use humhub\libs\ThemeHelper;
|
||||
use humhub\models\UrlOembed;
|
||||
use humhub\modules\admin\components\Controller;
|
||||
use humhub\modules\notification\models\forms\NotificationSettings;
|
||||
|
||||
/**
|
||||
* SettingController
|
||||
@ -138,7 +139,20 @@ class SettingController extends Controller
|
||||
$this->view->saved();
|
||||
}
|
||||
|
||||
return $this->render('mailing', array('model' => $form));
|
||||
return $this->render('mailing', ['model' => $form]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Notification Mailing Settings
|
||||
*/
|
||||
public function actionNotification()
|
||||
{
|
||||
$form = new NotificationSettings();
|
||||
if ($form->load(Yii::$app->request->post()) && $form->validate() && $form->save()) {
|
||||
$this->view->saved();
|
||||
}
|
||||
|
||||
return $this->render('notification', ['model' => $form]);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1,11 +1,4 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
|
||||
namespace humhub\modules\admin\models\forms;
|
||||
|
||||
use Yii;
|
||||
|
@ -0,0 +1,28 @@
|
||||
<?php
|
||||
namespace humhub\modules\admin\notifications;
|
||||
|
||||
use Yii;
|
||||
use humhub\modules\notification\components\NotificationCategory;
|
||||
|
||||
/**
|
||||
* Description of AdminNotificationCategory
|
||||
*
|
||||
* @author buddha
|
||||
*/
|
||||
class AdminNotificationCategory extends NotificationCategory
|
||||
{
|
||||
|
||||
public $id = 'admin';
|
||||
|
||||
public $sortOrder = 100;
|
||||
|
||||
public function getDescription()
|
||||
{
|
||||
return Yii::t('AdminModule.notifications_AdminNotificationCategory', 'Receive Notifications for administrative events like available updates.');
|
||||
}
|
||||
|
||||
public function getTitle()
|
||||
{
|
||||
return Yii::t('AdminModule.notifications_AdminNotificationCategory', 'Administrative');
|
||||
}
|
||||
}
|
@ -34,6 +34,14 @@ class NewVersionAvailable extends BaseNotification
|
||||
{
|
||||
return \yii\helpers\Url::to(['/admin/information/about']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function category()
|
||||
{
|
||||
return new AdminNotificationCategory;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
@ -46,7 +54,7 @@ class NewVersionAvailable extends BaseNotification
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getAsHtml()
|
||||
public function html()
|
||||
{
|
||||
return Yii::t('AdminModule.notification', "There is a new HumHub Version ({version}) available.", ['version' => Html::tag('strong', $this->getLatestHumHubVersion())]);
|
||||
}
|
||||
|
@ -0,0 +1,22 @@
|
||||
<?php
|
||||
use yii\widgets\ActiveForm;
|
||||
/* @var $model \humhub\modules\notification\models\forms\NotificationSettings */
|
||||
?>
|
||||
|
||||
<div class="panel-body">
|
||||
<h4><?= Yii::t('AdminModule.setting', 'Notification Settings'); ?></h4>
|
||||
<div class="help-block">
|
||||
<?= Yii::t('AdminModule.setting',
|
||||
'Here you can configure the default notification behaviour for your users.'); ?><br />
|
||||
<?= Yii::t('AdminModule.setting', 'You can enable outgoing notifications for a notification category by choosing the disired notification targets.'); ?>
|
||||
</div>
|
||||
|
||||
<br />
|
||||
<?php $form = ActiveForm::begin() ?>
|
||||
<?= humhub\modules\notification\widgets\NotificationSettingsForm::widget([
|
||||
'model' => $model,
|
||||
'form' => $form
|
||||
]) ?>
|
||||
<?php ActiveForm::end(); ?>
|
||||
</div>
|
||||
|
@ -26,42 +26,50 @@ class SettingsMenu extends \humhub\widgets\BaseMenu
|
||||
{
|
||||
$canEditSettings = Yii::$app->user->can(new \humhub\modules\admin\permissions\ManageSettings());
|
||||
|
||||
$this->addItem(array(
|
||||
$this->addItem([
|
||||
'label' => Yii::t('AdminModule.widgets_AdminMenuWidget', 'General'),
|
||||
'url' => Url::toRoute('/admin/setting/index'),
|
||||
'icon' => '<i class="fa fa-cogs"></i>',
|
||||
'sortOrder' => 100,
|
||||
'isActive' => (Yii::$app->controller->module && Yii::$app->controller->module->id == 'admin' && Yii::$app->controller->id == 'setting' && Yii::$app->controller->action->id == 'basic'),
|
||||
'isVisible' => $canEditSettings
|
||||
));
|
||||
]);
|
||||
|
||||
$this->addItem(array(
|
||||
$this->addItem([
|
||||
'label' => Yii::t('AdminModule.widgets_AdminMenuWidget', 'Appearance'),
|
||||
'url' => Url::toRoute('/admin/setting/design'),
|
||||
'icon' => '<i class="fa fa-magic"></i>',
|
||||
'sortOrder' => 200,
|
||||
'isActive' => (Yii::$app->controller->module && Yii::$app->controller->module->id == 'admin' && Yii::$app->controller->id == 'setting' && Yii::$app->controller->action->id == 'design'),
|
||||
'isVisible' => $canEditSettings
|
||||
));
|
||||
]);
|
||||
|
||||
$this->addItem(array(
|
||||
$this->addItem([
|
||||
'label' => Yii::t('AdminModule.widgets_AdminMenuWidget', 'E-Mails'),
|
||||
'url' => Url::toRoute('/admin/setting/mailing'),
|
||||
'icon' => '<i class="fa fa-envelope"></i>',
|
||||
'sortOrder' => 300,
|
||||
'isActive' => (Yii::$app->controller->module && Yii::$app->controller->module->id == 'admin' && Yii::$app->controller->id == 'setting' && (Yii::$app->controller->action->id == 'mailing' || Yii::$app->controller->action->id == 'mailing-server')),
|
||||
'isVisible' => $canEditSettings
|
||||
));
|
||||
]);
|
||||
|
||||
$this->addItem([
|
||||
'label' => Yii::t('AdminModule.widgets_AdminMenuWidget', 'Notifications'),
|
||||
'url' => Url::toRoute('/admin/setting/notification'),
|
||||
'icon' => '<i class="fa fa-envelope"></i>',
|
||||
'sortOrder' => 400,
|
||||
'isActive' => (Yii::$app->controller->module && Yii::$app->controller->module->id == 'admin' && Yii::$app->controller->id == 'setting' && (Yii::$app->controller->action->id == 'notification')),
|
||||
'isVisible' => $canEditSettings
|
||||
]);
|
||||
|
||||
$this->addItem(array(
|
||||
$this->addItem([
|
||||
'label' => Yii::t('AdminModule.widgets_AdminMenuWidget', 'Advanced'),
|
||||
'url' => Url::toRoute('/admin/setting/advanced'),
|
||||
'icon' => '<i class="fa fa-lock"></i>',
|
||||
'sortOrder' => 1000,
|
||||
'isVisible' => $canEditSettings
|
||||
));
|
||||
]);
|
||||
|
||||
parent::init();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -38,14 +38,6 @@ class NewComment extends \humhub\modules\notification\components\BaseNotificatio
|
||||
return parent::send($user);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public static function getTitle()
|
||||
{
|
||||
return Yii::t('CommentModule.notifications_NewComment', 'New Comment');
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
|
@ -1,9 +1,2 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
|
||||
return [];
|
@ -33,14 +33,14 @@ class ContentCreated extends BaseActivity
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function render($mode = self::OUTPUT_WEB, $params = array())
|
||||
public function render($params = array())
|
||||
{
|
||||
if ($this->source === null) {
|
||||
Yii::error('Could not render ContentCreated Activity without given source - ' . $this->record->id);
|
||||
return;
|
||||
}
|
||||
|
||||
return parent::render($mode, $params);
|
||||
return parent::render($params);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -12,6 +12,7 @@ use Yii;
|
||||
use yii\base\Exception;
|
||||
use humhub\components\ActiveRecord;
|
||||
use humhub\modules\content\models\Content;
|
||||
use humhub\modules\content\interfaces\ContentOwner;
|
||||
|
||||
/**
|
||||
* ContentActiveRecord is the base ActiveRecord [[\yii\db\ActiveRecord]] for Content.
|
||||
@ -41,7 +42,7 @@ use humhub\modules\content\models\Content;
|
||||
*
|
||||
* @author Luke
|
||||
*/
|
||||
class ContentActiveRecord extends ActiveRecord implements \humhub\modules\content\interfaces\ContentTitlePreview
|
||||
class ContentActiveRecord extends ActiveRecord implements ContentOwner
|
||||
{
|
||||
|
||||
/**
|
||||
@ -188,7 +189,7 @@ class ContentActiveRecord extends ActiveRecord implements \humhub\modules\conten
|
||||
/**
|
||||
* Related Content model
|
||||
*
|
||||
* @return \yii\db\ActiveQuery
|
||||
* @return Content
|
||||
*/
|
||||
public function getContent()
|
||||
{
|
||||
|
@ -11,6 +11,7 @@ namespace humhub\modules\content\components;
|
||||
use Yii;
|
||||
use yii\base\Exception;
|
||||
use humhub\components\ActiveRecord;
|
||||
use humhub\modules\content\interfaces\ContentOwner;
|
||||
|
||||
/**
|
||||
* HActiveRecordContentAddon is the base active record for content addons.
|
||||
@ -28,7 +29,7 @@ use humhub\components\ActiveRecord;
|
||||
* @package humhub.components
|
||||
* @since 0.5
|
||||
*/
|
||||
class ContentAddonActiveRecord extends ActiveRecord implements \humhub\modules\content\interfaces\ContentTitlePreview
|
||||
class ContentAddonActiveRecord extends ActiveRecord implements ContentOwner
|
||||
{
|
||||
|
||||
/**
|
||||
|
@ -8,6 +8,7 @@
|
||||
|
||||
namespace humhub\modules\content\components;
|
||||
|
||||
use Yii;
|
||||
use humhub\libs\BaseSettingsManager;
|
||||
|
||||
/**
|
||||
@ -28,6 +29,22 @@ class ContentContainerSettingsManager extends BaseSettingsManager
|
||||
* @var ContentContainerActiveRecord the content container this settings manager belongs to
|
||||
*/
|
||||
public $contentContainer;
|
||||
|
||||
/**
|
||||
* Returns the setting value of this container for the given setting $name.
|
||||
* If there is not container specific setting, this function will search for a global setting or
|
||||
* return default or null if there is also no global setting.
|
||||
*
|
||||
* @param type $name
|
||||
* @param type $default
|
||||
* @return boolean
|
||||
* @since 1.2
|
||||
*/
|
||||
public function getInherit($name, $default = null) {
|
||||
$result = $this->get($name);
|
||||
return ($result != null) ? $result
|
||||
: Yii::$app->getModule($this->moduleId)->settings->get($name, $default);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
|
15
protected/humhub/modules/content/interfaces/ContentOwner.php
Normal file
15
protected/humhub/modules/content/interfaces/ContentOwner.php
Normal file
@ -0,0 +1,15 @@
|
||||
<?php
|
||||
namespace humhub\modules\content\interfaces;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author luke
|
||||
*/
|
||||
interface ContentOwner
|
||||
{
|
||||
public function getContent();
|
||||
|
||||
public function getContentName();
|
||||
|
||||
public function getContentDescription();
|
||||
}
|
@ -1,21 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
|
||||
namespace humhub\modules\content\interfaces;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author luke
|
||||
*/
|
||||
interface ContentTitlePreview
|
||||
{
|
||||
|
||||
public function getContentName();
|
||||
|
||||
public function getContentDescription();
|
||||
}
|
@ -26,7 +26,7 @@ class ContentCreated extends \humhub\modules\notification\components\BaseNotific
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getAsHtml()
|
||||
public function html()
|
||||
{
|
||||
return Yii::t('ContentModule.notifications_views_ContentCreated', '{displayName} created {contentTitle}.', array(
|
||||
'displayName' => Html::tag('strong', Html::encode($this->originator->displayName)),
|
||||
|
@ -16,7 +16,8 @@ class ContentContainerFixture extends ActiveFixture
|
||||
public $dataFile = '@modules/content/tests/codeception/fixtures/data/contentcontainer.php';
|
||||
|
||||
public $depends = [
|
||||
'humhub\modules\content\tests\codeception\fixtures\ContentContainerPermissionFixture'
|
||||
'humhub\modules\content\tests\codeception\fixtures\ContentContainerPermissionFixture',
|
||||
'humhub\modules\content\tests\codeception\fixtures\ContentContainerSettingFixture'
|
||||
];
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @link https://www.humhub.org/
|
||||
* @copyright Copyright (c) 2015 HumHub GmbH & Co. KG
|
||||
* @license https://www.humhub.com/licences
|
||||
*/
|
||||
|
||||
namespace humhub\modules\content\tests\codeception\fixtures;
|
||||
|
||||
use yii\test\ActiveFixture;
|
||||
|
||||
class ContentContainerSettingFixture extends ActiveFixture
|
||||
{
|
||||
|
||||
public $modelClass = 'humhub\modules\content\models\ContentContainerSetting';
|
||||
public $dataFile = '@modules/content/tests/codeception/fixtures/data/contentcontainer_setting.php';
|
||||
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* HumHub
|
||||
* Copyright © 2014 The HumHub Project
|
||||
*
|
||||
* The texts of the GNU Affero General Public License with an additional
|
||||
* permission and of our proprietary license can be found at and
|
||||
* in the LICENSE file you have received along with this program.
|
||||
*
|
||||
* According to our dual licensing model, this program can be used either
|
||||
* under the terms of the GNU Affero General Public License, version 3,
|
||||
* or under a proprietary license.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*/
|
||||
return [];
|
@ -0,0 +1,52 @@
|
||||
<?php
|
||||
namespace humhub\modules\friendship\notifications;
|
||||
|
||||
use Yii;
|
||||
use humhub\modules\notification\components\NotificationCategory;
|
||||
use humhub\modules\notification\components\NotificationTarget;
|
||||
|
||||
/**
|
||||
* Description of SpaceJoinNotificationCategory
|
||||
*
|
||||
* @author buddha
|
||||
*/
|
||||
class FriendshipNotificationCategory extends NotificationCategory
|
||||
{
|
||||
/**
|
||||
* Category Id
|
||||
* @var string
|
||||
*/
|
||||
public $id = 'friendship';
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getTitle()
|
||||
{
|
||||
return Yii::t('SpaceModule.notifications_FriendshipNotificationCategory', 'Friendship');
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getDescription()
|
||||
{
|
||||
return Yii::t('SpaceModule.notifications_FriendshipNotificationCategory', 'Receive Notifications for Friendship Request and Approval events');
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getDefaultSetting(NotificationTarget $target)
|
||||
{
|
||||
if ($target->id === \humhub\modules\notification\components\MailNotificationTarget::getId()) {
|
||||
return true;
|
||||
} else if ($target->id === \humhub\modules\notification\components\WebNotificationTarget::getId()) {
|
||||
return true;
|
||||
} else if ($target->id === \humhub\modules\notification\components\MobileNotificationTarget::getId()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return $target->defaultSetting;
|
||||
}
|
||||
}
|
@ -37,19 +37,19 @@ class Request extends BaseNotification
|
||||
{
|
||||
return $this->originator->getUrl();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public static function getTitle()
|
||||
public function category()
|
||||
{
|
||||
return Yii::t('FriendshipModule.notifications_Request', 'Friendship Request');
|
||||
return new FriendshipNotificationCategory;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getAsHtml()
|
||||
public function html()
|
||||
{
|
||||
return Yii::t('FriendshipModule.notification', '{displayName} sent you a friend request.', array(
|
||||
'displayName' => Html::tag('strong', Html::encode($this->originator->displayName)),
|
||||
|
@ -30,6 +30,14 @@ class RequestApproved extends BaseNotification
|
||||
*/
|
||||
public $markAsSeenOnClick = true;
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function category()
|
||||
{
|
||||
return new FriendshipNotificationCategory;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
@ -41,19 +49,11 @@ class RequestApproved extends BaseNotification
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public static function getTitle()
|
||||
public function html()
|
||||
{
|
||||
return Yii::t('FriendshipModule.notifications_RequestApproved', 'Friendship Approved');
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getAsHtml()
|
||||
{
|
||||
return Yii::t('FriendshipModule.notification', '{displayName} accepted your friend request.', array(
|
||||
return Yii::t('FriendshipModule.notification', '{displayName} accepted your friend request.', [
|
||||
'displayName' => Html::tag('strong', Html::encode($this->originator->displayName)),
|
||||
));
|
||||
]);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -30,6 +30,11 @@ class RequestDeclined extends BaseNotification
|
||||
*/
|
||||
public $markAsSeenOnClick = true;
|
||||
|
||||
public function category()
|
||||
{
|
||||
return new FriendshipNotificationCategory;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
|
@ -25,14 +25,6 @@ class NewLike extends BaseNotification
|
||||
*/
|
||||
public $moduleId = 'like';
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public static function getTitle()
|
||||
{
|
||||
return Yii::t('LikeModule.notifiations_NewLike', 'New Like');
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
@ -45,20 +37,21 @@ class NewLike extends BaseNotification
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getAsHtml()
|
||||
public function html()
|
||||
{
|
||||
$contentInfo = $this->getContentInfo($this->getLikedRecord());
|
||||
|
||||
if ($this->groupCount > 1) {
|
||||
return Yii::t('LikeModule.notification', "{displayNames} likes {contentTitle}.", array(
|
||||
return Yii::t('LikeModule.notification', "{displayNames} likes {contentTitle}.", [
|
||||
'displayNames' => $this->getGroupUserDisplayNames(),
|
||||
'contentTitle' => $contentInfo
|
||||
));
|
||||
]);
|
||||
}
|
||||
return Yii::t('LikeModule.notification', "{displayName} likes {contentTitle}.", array(
|
||||
|
||||
return Yii::t('LikeModule.notification', "{displayName} likes {contentTitle}.", [
|
||||
'displayName' => Html::tag('strong', Html::encode($this->originator->displayName)),
|
||||
'contentTitle' => $contentInfo
|
||||
));
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1,9 +1,3 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
|
||||
return [];
|
@ -13,11 +13,16 @@ use yii\helpers\Url;
|
||||
use yii\bootstrap\Html;
|
||||
use humhub\modules\notification\models\Notification;
|
||||
use humhub\modules\user\models\User;
|
||||
use humhub\modules\content\components\ContentActiveRecord;
|
||||
use humhub\modules\content\components\ContentAddonActiveRecord;
|
||||
|
||||
/**
|
||||
* BaseNotification
|
||||
* A BaseNotification class describes the behaviour and the type of a Notification.
|
||||
* A BaseNotification is created and can be sent to one or multiple users over different targets.
|
||||
*
|
||||
* The BaseNotification can should be created like this:
|
||||
*
|
||||
* MyNotification::instance()->from($originator)->about($source)->sendBulk($userList);
|
||||
*
|
||||
* This will send Notifications to different NotificationTargets by using a queue.
|
||||
*
|
||||
* @author luke
|
||||
*/
|
||||
@ -25,34 +30,10 @@ abstract class BaseNotification extends \humhub\components\SocialActivity
|
||||
{
|
||||
|
||||
/**
|
||||
* Space this notification belongs to. (Optional)
|
||||
* If source is a Content, ContentAddon or ContentContainer this will be
|
||||
* automatically set.
|
||||
*
|
||||
* @var \humhub\modules\space\models\Space
|
||||
* Can be used to delay the NotificationJob execution.
|
||||
* @var type
|
||||
*/
|
||||
public $space;
|
||||
|
||||
/**
|
||||
* Layout file for web version
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $layoutWeb = "@notification/views/layouts/web.php";
|
||||
|
||||
/**
|
||||
* Layout file for mail version
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $layoutMail = "@notification/views/layouts/mail.php";
|
||||
|
||||
/**
|
||||
* Layout file for mail plaintext version
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $layoutMailPlaintext = "@notification/views/layouts/mail_plaintext.php";
|
||||
public $delay = 0;
|
||||
|
||||
/**
|
||||
* @var boolean automatically mark notification as seen after click on it
|
||||
@ -69,18 +50,72 @@ abstract class BaseNotification extends \humhub\components\SocialActivity
|
||||
*/
|
||||
protected $_groupKey = null;
|
||||
|
||||
/**
|
||||
* @var \humhub\modules\notification\components\NotificationCategory cached category instance
|
||||
*/
|
||||
protected $_category = null;
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public $recordClass = Notification::class;
|
||||
|
||||
/**
|
||||
* Returns the notification category instance. If no category class is set (default) the default notification settings
|
||||
* can't be overwritten.
|
||||
*
|
||||
* The category instance is cached, once created.
|
||||
*
|
||||
* If the Notification configuration should be configurable subclasses have to overwrite this method.
|
||||
*
|
||||
* @return \humhub\modules\notification\components\NotificationCategory
|
||||
*/
|
||||
public function getCategory()
|
||||
{
|
||||
if (!$this->_category) {
|
||||
$this->_category = $this->category();
|
||||
}
|
||||
return $this->_category;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new NotificationCategory instance.
|
||||
*
|
||||
* This function should be overwritten by subclasses to append this BaseNotification
|
||||
* to the returned category. If no category instance is returned, the BaseNotification behavriour (targets) will not be
|
||||
* configurable.
|
||||
*
|
||||
* @return \humhub\modules\notification\components\NotificationCategory
|
||||
*/
|
||||
protected function category()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string title text for this notification
|
||||
*/
|
||||
public function getTitle()
|
||||
{
|
||||
$category = $this->getCategory();
|
||||
if ($category) {
|
||||
return Yii::t('NotificationModule.base', 'There are new updates available at {baseUrl} - ({category})', ['baseUrl' => Url::base(true), 'category' => $category]);
|
||||
} else {
|
||||
return Yii::t('NotificationModule.base', 'There are new updates available at {baseUrl}', ['baseUrl' => Url::base(true)]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getViewParams($params = [])
|
||||
{
|
||||
$params['url'] = Url::to(['/notification/entry', 'id' => $this->record->id], true);
|
||||
$params['space'] = $this->space;
|
||||
$params['isNew'] = ($this->record->seen != 1);
|
||||
$params['asHtml'] = $this->getAsHtml();
|
||||
$params['asText'] = $this->getAsText();
|
||||
$result = [
|
||||
'url' => Url::to(['/notification/entry', 'id' => $this->record->id], true),
|
||||
'isNew' => !$this->record->seen,
|
||||
];
|
||||
|
||||
return parent::getViewParams($params);
|
||||
return \yii\helpers\ArrayHelper::merge(parent::getViewParams($result), $params);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -100,57 +135,98 @@ abstract class BaseNotification extends \humhub\components\SocialActivity
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends this notification to a User
|
||||
* Sends this notification to all notification targets of this User
|
||||
*
|
||||
* @param User $user
|
||||
*/
|
||||
public function send(User $user)
|
||||
{
|
||||
|
||||
if ($this->moduleId == "") {
|
||||
throw new \yii\base\InvalidConfigException("No moduleId given!");
|
||||
if (empty($this->moduleId)) {
|
||||
throw new \yii\base\InvalidConfigException('No moduleId given for "' . $this->className() . '"');
|
||||
}
|
||||
|
||||
// Skip - do not set notification to the originator
|
||||
if ($this->originator !== null && $user->id == $this->originator->id) {
|
||||
if ($this->originator && $this->originator->id == $user->id) {
|
||||
return;
|
||||
}
|
||||
|
||||
$notification = new Notification;
|
||||
$notification->user_id = $user->id;
|
||||
$notification->class = $this->className();
|
||||
$notification->module = $this->moduleId;
|
||||
$notification->seen = 0;
|
||||
|
||||
// Load group key
|
||||
if ($this->_groupKey === null) {
|
||||
$this->_groupKey = $this->getGroupKey();
|
||||
|
||||
//$this->queueJob($user);
|
||||
$this->saveRecord($user);
|
||||
foreach (Yii::$app->notification->getTargets($user) as $target) {
|
||||
$target->send($this, $user);
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->_groupKey !== '') {
|
||||
$notification->group_key = $this->getGroupKey();
|
||||
}
|
||||
/**
|
||||
* Queues the notification job. The Job is responsible for creating and sending
|
||||
* the Notifications out to its NotificationTargets.
|
||||
*
|
||||
* @param User $user
|
||||
*/
|
||||
protected function queueJob(User $user)
|
||||
{
|
||||
Yii::$app->notificationQueue->push(new NotificationJob([
|
||||
'notification' => $this,
|
||||
'user_id' => $user->id
|
||||
]));
|
||||
}
|
||||
|
||||
if ($this->source !== null) {
|
||||
public function save(User $user)
|
||||
{
|
||||
// We reuse our record instance to save multiple records.
|
||||
$this->record->id = null;
|
||||
$this->record->isNewRecord = true;
|
||||
$this->record->user_id = $user->id;
|
||||
return $this->record->save();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the an Notification instance of the current BaseNotification type for the
|
||||
* given $user.
|
||||
*
|
||||
* @param User $user
|
||||
*/
|
||||
public function saveRecord(User $user)
|
||||
{
|
||||
$notification = new Notification([
|
||||
'user_id' => $user->id,
|
||||
'class' => static::class,
|
||||
'module' => $this->moduleId,
|
||||
'group_key' => $this->getGroupKey(),
|
||||
]);
|
||||
|
||||
if ($this->source) {
|
||||
$notification->source_pk = $this->source->getPrimaryKey();
|
||||
$notification->source_class = $this->source->className();
|
||||
|
||||
// Automatically set spaceId if source is Content/Addon/Container
|
||||
if ($this->source instanceof ContentActiveRecord || $this->source instanceof ContentAddonActiveRecord) {
|
||||
if ($this->source->content->container instanceof \humhub\modules\space\models\Space) {
|
||||
$notification->space_id = $this->source->content->container->id;
|
||||
}
|
||||
} elseif ($this->source instanceof \humhub\modules\space\models\Space) {
|
||||
$notification->space_id = $this->source->id;
|
||||
}
|
||||
$notification->space_id = $this->getSpaceId();
|
||||
}
|
||||
|
||||
if ($this->originator !== null) {
|
||||
if ($this->originator) {
|
||||
$notification->originator_user_id = $this->originator->id;
|
||||
}
|
||||
|
||||
$notification->save();
|
||||
$this->record = $notification;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function about($source)
|
||||
{
|
||||
parent::about($source);
|
||||
$this->record->space_id = $this->getSpaceId();
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function from($originator)
|
||||
{
|
||||
$this->originator = $originator;
|
||||
$this->record->originator_user_id = $originator->id;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -160,7 +236,7 @@ abstract class BaseNotification extends \humhub\components\SocialActivity
|
||||
{
|
||||
$condition = [];
|
||||
|
||||
$condition['class'] = $this->className();
|
||||
$condition['class'] = static::class;
|
||||
|
||||
if ($user !== null) {
|
||||
$condition['user_id'] = $user->id;
|
||||
@ -201,71 +277,38 @@ abstract class BaseNotification extends \humhub\components\SocialActivity
|
||||
$similarNotifications = Notification::find()
|
||||
->where(['source_class' => $this->record->source_class, 'source_pk' => $this->record->source_pk, 'user_id' => $this->record->user_id])
|
||||
->andWhere(['!=', 'seen', '1']);
|
||||
foreach ($similarNotifications->all() as $n) {
|
||||
$n->getClass()->markAsSeen();
|
||||
foreach ($similarNotifications->all() as $notification) {
|
||||
$notification->getClass()->markAsSeen();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns key to group notifications.
|
||||
* If empty notification grouping is disabled.
|
||||
* Returns a key for grouping notifications.
|
||||
* If null is returned (default) the notification grouping for this BaseNotification type disabled.
|
||||
*
|
||||
* The returned key could for example be a combination of classname related content id.
|
||||
*
|
||||
* @return string the group key
|
||||
*/
|
||||
public function getGroupKey()
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* Should be overwritten by subclasses. This method provides a user friendly
|
||||
* title for the different notification types.
|
||||
*
|
||||
* @return string e.g. New Like
|
||||
*/
|
||||
public static function getTitle()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns text version of this notification
|
||||
* Renders the Notificaiton for the given NotificationTarget.
|
||||
* Subclasses are able to use custom renderer for different targets by overwriting this function.
|
||||
*
|
||||
* @return string
|
||||
* @param NotificationTarger $target
|
||||
* @return string render result
|
||||
*/
|
||||
public function getAsText()
|
||||
public function render(NotificationTarget $target = null)
|
||||
{
|
||||
$html = $this->getAsHtml();
|
||||
|
||||
if ($html === null) {
|
||||
return null;
|
||||
if (!$target) {
|
||||
$target = Yii::$app->notification->getTarget(WebNotificationTarget::class);
|
||||
}
|
||||
|
||||
return strip_tags($html);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns Html text of this notification,
|
||||
*
|
||||
* @return type
|
||||
*/
|
||||
public function getAsHtml()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function render($mode = self::OUTPUT_WEB, $params = array())
|
||||
{
|
||||
// Set default notification view - when not specified
|
||||
if ($this->viewName === null) {
|
||||
$this->viewName = 'default';
|
||||
$this->viewPath = '@notification/views/notification';
|
||||
}
|
||||
|
||||
return parent::render($mode, $params);
|
||||
return $target->getRenderer()->render($this);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -322,4 +365,42 @@ abstract class BaseNotification extends \humhub\components\SocialActivity
|
||||
return $users;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function asArray()
|
||||
{
|
||||
$result = parent::asArray();
|
||||
$result['title'] = $this->getTitle();
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Should be overwritten by subclasses for a html representation of the notification.
|
||||
* @return type
|
||||
*/
|
||||
public function html()
|
||||
{
|
||||
// Only for backward compatibility.
|
||||
return $this->getAsHtml();
|
||||
}
|
||||
|
||||
/**
|
||||
* Use text() instead
|
||||
* @deprecated since version 1.2
|
||||
*/
|
||||
public function getAsText()
|
||||
{
|
||||
return $this->text();
|
||||
}
|
||||
|
||||
/**
|
||||
* Use html() instead
|
||||
* @deprecated since version 1.2
|
||||
*/
|
||||
public function getAsHtml()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,76 @@
|
||||
<?php
|
||||
|
||||
namespace humhub\modules\notification\components;
|
||||
|
||||
use Yii;
|
||||
use humhub\modules\user\models\User;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author buddha
|
||||
*/
|
||||
class MailNotificationTarget extends NotificationTarget
|
||||
{
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public $id = 'email';
|
||||
|
||||
/**
|
||||
* Enable this target by default.
|
||||
* @var type
|
||||
*/
|
||||
public $defaultSetting = true;
|
||||
|
||||
public $view = [
|
||||
'html' => '@humhub/modules/content/views/mails/Update',
|
||||
'text' => '@humhub/modules/content/views/mails/plaintext/Update'
|
||||
];
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getTitle()
|
||||
{
|
||||
return Yii::t('NotificationModule.components_WebNotificationTarget', 'E-Mail');
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function handle(BaseNotification $notification, User $user)
|
||||
{
|
||||
try {
|
||||
// TODO: find cleaner solution...
|
||||
Yii::$app->view->params['showUnsubscribe'] = true;
|
||||
|
||||
$viewParams = [
|
||||
'notifications' => $notification->render($this),
|
||||
'notifications_plaintext' => $this->getText($notification)
|
||||
];
|
||||
|
||||
return Yii::$app->mailer->compose($this->view, $viewParams)
|
||||
->setFrom([Yii::$app->settings->get('mailer.systemEmailAddress') => Yii::$app->settings->get('mailer.systemEmailName')])
|
||||
->setTo($user->email)
|
||||
->setSubject($notification->getTitle())->send();
|
||||
} catch (\Exception $ex) {
|
||||
Yii::error('Could not send mail to: ' . $user->email . ' - Error: ' . $ex->getMessage());
|
||||
if(YII_DEBUG) {
|
||||
throw $ex;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function getText(BaseNotification $notification)
|
||||
{
|
||||
$textRenderer = $this->getRenderer();
|
||||
|
||||
if (!method_exists($textRenderer, 'renderText')) {
|
||||
$textRenderer = Yii::createObject(MailTargetRenderer::class);
|
||||
}
|
||||
|
||||
return $textRenderer->renderText($notification);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,125 @@
|
||||
<?php
|
||||
|
||||
namespace humhub\modules\notification\components;
|
||||
|
||||
use Yii;
|
||||
use humhub\components\rendering\Viewable;
|
||||
|
||||
/**
|
||||
* The MailTargetRenderer is used to render Notifications for the MailNotificationTarget.
|
||||
*
|
||||
* A BaseNotification can overwrite the default view and layout by setting a specific $viewName and
|
||||
* defining the following files:
|
||||
*
|
||||
* Overwrite default html view for this notification:
|
||||
* @module/views/notification/mail/viewname.php
|
||||
*
|
||||
* Overwrite default mail layout for this notification:
|
||||
* @module/views/layouts/notification/mail/viewname.php
|
||||
*
|
||||
* Overwrite default mail text layout for this notification:
|
||||
* @module/views/layouts/notification/mail/plaintext/viewname.php
|
||||
*
|
||||
* @author buddha
|
||||
*/
|
||||
class MailTargetRenderer extends \humhub\components\rendering\MailLayoutRenderer
|
||||
{
|
||||
|
||||
/**
|
||||
* @var string default notification mail view path
|
||||
*/
|
||||
public $defaultViewPath = '@notification/views/notification/mail';
|
||||
|
||||
/**
|
||||
* @var string default notification mail view
|
||||
*/
|
||||
public $defaultView = '@notification/views/notification/mail/default.php';
|
||||
|
||||
/**
|
||||
* @var string layout file path
|
||||
*/
|
||||
public $defaultLayout = '@notification/views/layouts/mail.php';
|
||||
|
||||
/**
|
||||
* @var string default notification mail text view path
|
||||
*/
|
||||
public $defaultTextViewPath = '@notification/views/notification/mail/plaintext';
|
||||
|
||||
/**
|
||||
* @var string text layout file
|
||||
*/
|
||||
public $defaultTextLayout = "@notification/views/layouts/mail_plaintext.php";
|
||||
|
||||
/**
|
||||
* Returns the view file for the given Viewable Notification.
|
||||
*
|
||||
* This function will search for the view file defined in the Viewable within the module/views/notification/mail directory of
|
||||
* the viewable module.
|
||||
*
|
||||
* If the module view does not exist we search for the viewName within the default notification viewPath.
|
||||
*
|
||||
* If this view also does not exist we return the base notification view file.
|
||||
*
|
||||
* @param \humhub\modules\notification\components\Viewable $viewable
|
||||
* @return string view file of this notification
|
||||
*/
|
||||
public function getViewFile(Viewable $viewable)
|
||||
{
|
||||
$viewFile = $this->getViewPath($viewable) . '/notification/mail/' . $viewable->getViewName();
|
||||
|
||||
if (!file_exists($viewFile)) {
|
||||
$viewFile = Yii::getAlias($this->defaultViewPath) . DIRECTORY_SEPARATOR . $viewable->getViewName();
|
||||
}
|
||||
|
||||
if (!file_exists($viewFile)) {
|
||||
$viewFile = Yii::getAlias($this->defaultView);
|
||||
}
|
||||
|
||||
return $viewFile;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the layout for the given Notification Viewable.
|
||||
*
|
||||
* This function will search for a layout file under module/views/layouts/mail with the view name defined
|
||||
* by $viwable.
|
||||
*
|
||||
* If this file does not exists the default notification mail layout will be returned.
|
||||
*
|
||||
* @param \humhub\modules\notification\components\Viewable $viewable
|
||||
* @return type
|
||||
*/
|
||||
public function getLayout(Viewable $viewable)
|
||||
{
|
||||
$layout = $this->getViewPath($viewable) . '/layouts/notification/mail/' . $viewable->getViewName();
|
||||
|
||||
if (!file_exists($layout)) {
|
||||
$layout = Yii::getAlias($this->defaultLayout);
|
||||
}
|
||||
|
||||
return $layout;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the text layout for the given Notification Viewable.
|
||||
*
|
||||
* This function will search for a view file under module/views/layouts/mail/plaintext with the view name defined
|
||||
* by $viwable.
|
||||
*
|
||||
* If this file does not exists the default notification text mail layout is returned.
|
||||
*
|
||||
* @param \humhub\modules\notification\components\Viewable $viewable
|
||||
* @return type
|
||||
*/
|
||||
public function getTextLayout(Viewable $viewable)
|
||||
{
|
||||
$layout = $this->getViewPath($viewable) . '/layouts/notification/mail/plaintext/' . $viewable->getViewName();
|
||||
|
||||
if (!file_exists($layout)) {
|
||||
$layout = Yii::getAlias($this->defaultTextLayout);
|
||||
}
|
||||
|
||||
return $layout;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,33 @@
|
||||
<?php
|
||||
namespace humhub\modules\notification\components;
|
||||
|
||||
use Yii;
|
||||
use humhub\modules\user\models\User;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author buddha
|
||||
*/
|
||||
class MobileNotificationTarget extends NotificationTarget
|
||||
{
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public $id = 'mobile';
|
||||
|
||||
/**
|
||||
* Used to forward a BaseNotification object to a NotificationTarget.
|
||||
* The NotificationTarget should handle the notification by pushing a Job to
|
||||
* a Queue or directly handling the notification.
|
||||
*
|
||||
* @param BaseNotification $notification
|
||||
*/
|
||||
public function handle(BaseNotification $notification, User $user) {
|
||||
|
||||
}
|
||||
|
||||
public function getTitle()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,102 @@
|
||||
<?php
|
||||
|
||||
namespace humhub\modules\notification\components;
|
||||
|
||||
use humhub\modules\user\models\User;
|
||||
use humhub\modules\notification\components\NotificationTarget;
|
||||
|
||||
/**
|
||||
* NotificationCategories are used to group different notifications in views and
|
||||
* configure the notifications in the notification settings.
|
||||
*
|
||||
*/
|
||||
abstract class NotificationCategory extends \yii\base\Object
|
||||
{
|
||||
|
||||
/**
|
||||
* Category Id
|
||||
* @var type
|
||||
*/
|
||||
public $id;
|
||||
|
||||
/**
|
||||
* Used to sort items in the frontend.
|
||||
* @var type
|
||||
*/
|
||||
public $sortOrder = PHP_INT_MAX;
|
||||
|
||||
public function init()
|
||||
{
|
||||
parent::init();
|
||||
if(!$this->id) {
|
||||
throw new \yii\base\InvalidConfigException('NotificationCategories have to define an id property, which is not the case for "'.self::class.'"');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a human readable title of this category
|
||||
*/
|
||||
public abstract function getTitle();
|
||||
|
||||
/**
|
||||
* Returns a group description
|
||||
*/
|
||||
public abstract function getDescription();
|
||||
|
||||
/**
|
||||
* Returns the default enabled settings for the given $target.
|
||||
* In case the $target is unknown, subclasses can either return $target->defaultSetting
|
||||
* or another default value.
|
||||
*
|
||||
* @param NotificationTarget $target
|
||||
* @return boolean
|
||||
*/
|
||||
public function getDefaultSetting(NotificationTarget $target)
|
||||
{
|
||||
if ($target->id === \humhub\modules\notification\components\MailNotificationTarget::getId()) {
|
||||
return true;
|
||||
} else if ($target->id === \humhub\modules\notification\components\WebNotificationTarget::getId()) {
|
||||
return true;
|
||||
} else if ($target->id === \humhub\modules\notification\components\MobileNotificationTarget::getId()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $target->defaultSetting;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of target ids, which are not editable.
|
||||
*
|
||||
* @param NotificationTarget $target
|
||||
*/
|
||||
public function getFixedSettings()
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the given NotificationTarget is fixed for this category.
|
||||
*
|
||||
* @param type $target
|
||||
* @return type
|
||||
*/
|
||||
public function isFixedSettings(NotificationTarget $target)
|
||||
{
|
||||
return in_array($target->id, $this->getFixedSettings());
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if this category is visible for the given $user.
|
||||
* This can be used if a category is only visible for users with certian permissions.
|
||||
*
|
||||
* Note if no user is given this function should return true in most cases, otherwise this
|
||||
* category won't be visible in the global notification settings.
|
||||
*
|
||||
* @param User $user
|
||||
* @return boolean
|
||||
*/
|
||||
public function isVisible(User $user = null)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
@ -0,0 +1,133 @@
|
||||
<?php
|
||||
namespace humhub\modules\notification\components;
|
||||
|
||||
use Yii;
|
||||
|
||||
/**
|
||||
* Description of NotificationManager
|
||||
*
|
||||
* @author buddha
|
||||
*/
|
||||
class NotificationManager
|
||||
{
|
||||
|
||||
/**
|
||||
*
|
||||
* @var array Target configuration.
|
||||
*/
|
||||
public $targets = [];
|
||||
|
||||
/**
|
||||
*
|
||||
* @var BaseNotification[] Cached array of BaseNotification instances.
|
||||
*/
|
||||
protected $_notifications;
|
||||
|
||||
/**
|
||||
* @var NotificationTarget[] Cached target instances.
|
||||
*/
|
||||
protected $_targets;
|
||||
|
||||
/**
|
||||
* Cached array of NotificationCategories
|
||||
* @var type
|
||||
*/
|
||||
protected $_categories;
|
||||
|
||||
/**
|
||||
* Returns all active targets for the given user.
|
||||
*
|
||||
* @param type $user
|
||||
* @return type
|
||||
*/
|
||||
public function getTargets($user = null)
|
||||
{
|
||||
if($this->_targets) {
|
||||
return $this->_targets;
|
||||
}
|
||||
|
||||
foreach($this->targets as $target) {
|
||||
$instance = Yii::createObject($target);
|
||||
if($instance->isActive($user)) {
|
||||
$this->_targets[] = $instance;
|
||||
}
|
||||
}
|
||||
|
||||
return $this->_targets;
|
||||
}
|
||||
|
||||
public function getTarget($class)
|
||||
{
|
||||
foreach($this->getTargets() as $target) {
|
||||
if($target->className() == $class) {
|
||||
return $target;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all available Notifications
|
||||
*
|
||||
* @return type
|
||||
*/
|
||||
public function getNotifications()
|
||||
{
|
||||
if (!$this->_notifications) {
|
||||
$this->_notifications = $this->searchModuleNotifications();
|
||||
}
|
||||
return $this->_notifications;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all available NotificationCategories as array with category id as
|
||||
* key and a category instance as value.
|
||||
*/
|
||||
public function getNotificationCategories($user = null)
|
||||
{
|
||||
if($this->_categories) {
|
||||
return $this->_categories;
|
||||
}
|
||||
|
||||
$result = [];
|
||||
|
||||
foreach($this->getNotifications() as $notification) {
|
||||
$category = $notification->getCategory();
|
||||
if($category && !array_key_exists($category->id, $result) && $category->isVisible($user)) {
|
||||
$result[$category->id] = $category;
|
||||
}
|
||||
}
|
||||
|
||||
$this->_categories = array_values($result);
|
||||
|
||||
usort($this->_categories, function($a, $b) {
|
||||
return $a->sortOrder - $b->sortOrder;
|
||||
});
|
||||
|
||||
return $this->_categories;
|
||||
}
|
||||
|
||||
/**
|
||||
* Searches for all Notifications exported by modules.
|
||||
* @return type
|
||||
*/
|
||||
protected function searchModuleNotifications()
|
||||
{
|
||||
$result = [];
|
||||
foreach (Yii::$app->moduleManager->getModules(['includeCoreModules' => true]) as $module) {
|
||||
if ($module instanceof \humhub\components\Module && $module->hasNotifications()) {
|
||||
$result = array_merge($result, $this->createNotifications($module->getNotifications()));
|
||||
}
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
protected function createNotifications($notificationClasses)
|
||||
{
|
||||
$result = [];
|
||||
foreach($notificationClasses as $notificationClass) {
|
||||
$result[] = Yii::createObject($notificationClass);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,242 @@
|
||||
<?php
|
||||
|
||||
namespace humhub\modules\notification\components;
|
||||
|
||||
use Yii;
|
||||
use humhub\modules\user\models\User;
|
||||
use humhub\components\rendering\Renderer;
|
||||
|
||||
/**
|
||||
* A NotificationTarget is used to handle new Basenotifications. A NotificationTarget
|
||||
* may send nofication information to external services in specific formats or use
|
||||
* specific protocols.
|
||||
*
|
||||
* @author buddha
|
||||
*/
|
||||
abstract class NotificationTarget extends \yii\base\Object
|
||||
{
|
||||
|
||||
/**
|
||||
* Unique target id has to be defined by subclasses.
|
||||
* @var string
|
||||
*/
|
||||
public $id;
|
||||
|
||||
/**
|
||||
* Holds the title of this insance.
|
||||
* @var type
|
||||
*/
|
||||
public $title;
|
||||
|
||||
/**
|
||||
* Default Renderer for this NotificationTarget
|
||||
* @var type
|
||||
*/
|
||||
public $renderer;
|
||||
|
||||
/**
|
||||
* Defines the acknowledge flag in the notification record.
|
||||
* If not set, the notification target does not support the acknowledgement of a notification,
|
||||
* or provides an custom implemention.
|
||||
*
|
||||
* @var string
|
||||
* @see NotificationTarget::acknowledge()
|
||||
*/
|
||||
public $acknowledgeFlag;
|
||||
|
||||
/**
|
||||
* Will be used as default enable setting, if there is no user specific setting and no
|
||||
* global setting and also no default setting for this target for a given NotificationCategory.
|
||||
* @var boolean
|
||||
*/
|
||||
public $defaultSetting = false;
|
||||
|
||||
public function init()
|
||||
{
|
||||
parent::init();
|
||||
$this->title = $this->getTitle();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string Human readable title for views.
|
||||
*/
|
||||
public abstract function getTitle();
|
||||
|
||||
/**
|
||||
* @return \humhub\components\rendering\Renderer default renderer for this target.
|
||||
*/
|
||||
public function getRenderer()
|
||||
{
|
||||
return \yii\di\Instance::ensure($this->renderer, Renderer::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to handle a BaseNotification for a given $user.
|
||||
*
|
||||
* The NotificationTarget can handle the notification for example by pushing a Job to
|
||||
* a Queue or directly handling the notification.
|
||||
*
|
||||
* @param BaseNotification $notification
|
||||
*/
|
||||
public abstract function handle(BaseNotification $notification, User $user);
|
||||
|
||||
/**
|
||||
* Used to acknowledge the seding/processing of the given $notification.
|
||||
*
|
||||
* @param BaseNotification $notification notification to be acknowledged
|
||||
* @param boolean $state true if successful otherwise false
|
||||
*/
|
||||
public function acknowledge(BaseNotification $notification, $state = true)
|
||||
{
|
||||
if ($this->acknowledgeFlag && $notification->record->hasAttribute($this->acknowledgeFlag)) {
|
||||
$notification->record->setAttribute($this->acknowledgeFlag, $state);
|
||||
$notification->record->save();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return boolean Check if the given $notification has already been processed.
|
||||
*/
|
||||
public function isAcknowledged(BaseNotification $notification)
|
||||
{
|
||||
if ($this->acknowledgeFlag && $notification->record->hasAttribute($this->acknowledgeFlag)) {
|
||||
return $notification->record->getAttribute($this->acknowledgeFlag);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Static access to the target id.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function getId()
|
||||
{
|
||||
$instance = new static();
|
||||
return $instance->id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to process a $notification for the given $user.
|
||||
*
|
||||
* By default the $noification will be marked as acknowledged before processing.
|
||||
* The processing is triggerd by calling $this->handle.
|
||||
* If the processing fails the acknowledged mark will be set to false.
|
||||
*
|
||||
* @param BaseNotification $notification
|
||||
*/
|
||||
public function send(BaseNotification $notification, User $user)
|
||||
{
|
||||
if ($this->isAcknowledged($notification)) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
$this->acknowledge($notification, true);
|
||||
|
||||
if ($this->isEnabled($notification, $user)) {
|
||||
$this->handle($notification, $user);
|
||||
} else {
|
||||
$this->acknowledge($notification, false);
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
Yii::error($e);
|
||||
$this->acknowledge($notification, false);
|
||||
//TODO: increment retry count.
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Used for handling the given $notification for multiple $users.
|
||||
*
|
||||
* @param BaseNotification $notification
|
||||
* @param type $users
|
||||
*/
|
||||
public function sendBulk(BaseNotification $notification, $users)
|
||||
{
|
||||
if ($users instanceof \yii\db\ActiveQuery) {
|
||||
$users = $users->all();
|
||||
}
|
||||
|
||||
foreach ($users as $user) {
|
||||
$this->send($notification, $user);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the setting key for this target of the given $category.
|
||||
* @param type $category
|
||||
* @return type
|
||||
*/
|
||||
public function getSettingKey($category)
|
||||
{
|
||||
return $category->id . '_' . $this->id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Some NotificationTargets may need to be activated first or require a certain permission in order to be used.
|
||||
*
|
||||
* This function checks if this target is active for the given user.
|
||||
* If no user is given this function will determine if the target is globaly active or deactivated.
|
||||
*
|
||||
* If a subclass does not overwrite this function it will be activated for all users by default.
|
||||
*
|
||||
* @param User $user
|
||||
*/
|
||||
public function isActive(User $user = null)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the given $notification is enabled for this target.
|
||||
* If the $notification is not part of a NotificationCategory the $defaultSetting
|
||||
* of this NotificationTarget is returned.
|
||||
*
|
||||
* If this NotificationTarget is not active for the given $user, this function will return false.
|
||||
*
|
||||
* @param BaseNotification $notification
|
||||
* @param User $user
|
||||
* @see NotificationTarget::isActive()
|
||||
* @see NotificationTarget::isCategoryEnabled()
|
||||
* @return boolean
|
||||
*/
|
||||
public function isEnabled(BaseNotification $notification, User $user = null)
|
||||
{
|
||||
if (!$this->isActive($user)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$category = $notification->getCategory();
|
||||
return ($category) ? $this->isCategoryEnabled($category, $user) : $this->defaultSetting;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the enabled setting of this target for the given $category.
|
||||
*
|
||||
* @param NotificationCategory $category
|
||||
* @param User $user
|
||||
* @return boolean
|
||||
*/
|
||||
public function isCategoryEnabled(NotificationCategory $category, User $user = null)
|
||||
{
|
||||
if(!$category->isVisible($user)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if($category->isFixedSettings($this)) {
|
||||
return $category->getDefaultSetting($this);
|
||||
}
|
||||
|
||||
$settingKey = $this->getSettingKey($category);
|
||||
|
||||
if ($user) {
|
||||
$enabled = Yii::$app->getModule('notification')->settings->user($user)->getInherit($settingKey, $category->getDefaultSetting($this));
|
||||
} else {
|
||||
$enabled = Yii::$app->getModule('notification')->settings->get($settingKey, $category->getDefaultSetting($this));
|
||||
}
|
||||
|
||||
return ($enabled === null) ? $this->defaultSetting : boolval($enabled);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
<?php
|
||||
namespace humhub\modules\notification\components;
|
||||
|
||||
use Yii;
|
||||
use humhub\modules\user\models\User;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author buddha
|
||||
*/
|
||||
class WebNotificationTarget extends NotificationTarget
|
||||
{
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public $id = 'web';
|
||||
|
||||
/**
|
||||
* Since the WebNotificationTarget only requires the Notification ActiveRecord to be persisted,
|
||||
* this handler only check the presence of the related Notification record.
|
||||
*/
|
||||
public function handle(BaseNotification $notification, User $user) {
|
||||
if(!$notification->record) {
|
||||
throw new \yii\base\Exception('Notification record not found for BaseNotification "'.$notification->className().'"');
|
||||
}
|
||||
}
|
||||
|
||||
public function getTitle()
|
||||
{
|
||||
return Yii::t('NotificationModule.components_WebNotificationTarget', 'Web');
|
||||
}
|
||||
}
|
@ -0,0 +1,95 @@
|
||||
<?php
|
||||
|
||||
namespace humhub\modules\notification\components;
|
||||
|
||||
use Yii;
|
||||
use humhub\components\rendering\Viewable;
|
||||
|
||||
/**
|
||||
* The WebTargetRenderer is used to render Notifications for the WebNotificationTarget.
|
||||
*
|
||||
* A BaseNotification can overwrite the default view and layout by setting a specific $viewName and
|
||||
* defining the following files:
|
||||
*
|
||||
* Overwrite default view for this notification:
|
||||
* @module/views/notification/viewname.php
|
||||
*
|
||||
* Overwrite default layout for this notification:
|
||||
* @module/views/layouts/notification/viewname.php
|
||||
*
|
||||
* @author buddha
|
||||
*/
|
||||
class WebTargetRenderer extends \humhub\components\rendering\LayoutRenderer
|
||||
{
|
||||
|
||||
/**
|
||||
* @var string default view path
|
||||
*/
|
||||
public $defaultViewPath = '@notification/views/notification';
|
||||
|
||||
/*
|
||||
* @var string default view
|
||||
*/
|
||||
public $defaultView = '@notification/views/notification/default.php';
|
||||
|
||||
/**
|
||||
* @var string default layout
|
||||
*/
|
||||
public $defaultLayout = '@notification/views/layouts/web.php';
|
||||
|
||||
/**
|
||||
* @var string defines the view subfolder containing layouts and views.
|
||||
*/
|
||||
public $viewSubFolder = 'notification';
|
||||
|
||||
/**
|
||||
* Returns the view file for the given Viewable Notification.
|
||||
*
|
||||
* This function will search for the view file defined in the Viewable within the module/views/mail directory of
|
||||
* the viewable module.
|
||||
*
|
||||
* If the module view does not exist we search for the viewName within the default notification viewPath.
|
||||
*
|
||||
* If this view also does not exist we return the base notification view file.
|
||||
*
|
||||
* @param \humhub\modules\notification\components\Viewable $viewable
|
||||
* @return string view file of this notification
|
||||
*/
|
||||
public function getViewFile(Viewable $viewable)
|
||||
{
|
||||
$viewFile = $this->getViewPath($viewable) . '/'.$this->viewSubFolder.'/' . $viewable->getViewName();
|
||||
|
||||
if (!file_exists($viewFile)) {
|
||||
$viewFile = Yii::getAlias($this->defaultViewPath) . DIRECTORY_SEPARATOR . $viewable->getViewName();
|
||||
}
|
||||
|
||||
if (!file_exists($viewFile)) {
|
||||
$viewFile = Yii::getAlias($this->defaultView);
|
||||
}
|
||||
|
||||
return $viewFile;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the layout for the given Notification Viewable.
|
||||
*
|
||||
* This function will search for a layout file under module/views/layouts/mail with the view name defined
|
||||
* by $viwable.
|
||||
*
|
||||
* If this file does not exists the default notification mail layout will be returned.
|
||||
*
|
||||
* @param \humhub\modules\notification\components\Viewable $viewable
|
||||
* @return type
|
||||
*/
|
||||
public function getLayout(Viewable $viewable)
|
||||
{
|
||||
$layout = $this->getViewPath($viewable) . '/layouts/'.$this->viewSubFolder.'/' . $viewable->getViewName();
|
||||
|
||||
if (!file_exists($layout)) {
|
||||
$layout = Yii::getAlias($this->defaultLayout);
|
||||
}
|
||||
|
||||
return $layout;
|
||||
}
|
||||
|
||||
}
|
@ -27,6 +27,14 @@ class Notification extends \humhub\components\ActiveRecord
|
||||
*/
|
||||
public $group_count;
|
||||
|
||||
public function init()
|
||||
{
|
||||
parent::init();
|
||||
if ($this->seen == null) {
|
||||
$this->seen = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
@ -46,13 +54,23 @@ class Notification extends \humhub\components\ActiveRecord
|
||||
[['class', 'source_class'], 'string', 'max' => 100]
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Use getBaseModel instead.
|
||||
* @deprecated since version 1.2
|
||||
* @param type $params
|
||||
*/
|
||||
public function getClass($params = [])
|
||||
{
|
||||
return $this->getBaseModel($params);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the business model of this notification
|
||||
*
|
||||
* @return \humhub\modules\notification\components\BaseNotification
|
||||
*/
|
||||
public function getClass($params = [])
|
||||
public function getBaseModel($params = [])
|
||||
{
|
||||
if (class_exists($this->class)) {
|
||||
$params['source'] = $this->getSourceObject();
|
||||
@ -155,7 +173,7 @@ class Notification extends \humhub\components\ActiveRecord
|
||||
public static function findGrouped()
|
||||
{
|
||||
$query = self::find();
|
||||
$query->addSelect(['notification.*',
|
||||
$query->addSelect(['notification.*',
|
||||
new \yii\db\Expression('count(distinct(originator_user_id)) as group_count'),
|
||||
new \yii\db\Expression('max(created_at) as group_created_at'),
|
||||
new \yii\db\Expression('min(seen) as group_seen'),
|
||||
|
@ -0,0 +1,53 @@
|
||||
<?php
|
||||
namespace humhub\modules\notification\models\forms;
|
||||
|
||||
use Yii;
|
||||
|
||||
/**
|
||||
* Description of NotificationSettings
|
||||
*
|
||||
* @author buddha
|
||||
*/
|
||||
class NotificationSettings extends \yii\base\Model
|
||||
{
|
||||
|
||||
public $settings = [];
|
||||
|
||||
protected $_targets;
|
||||
|
||||
public function rules()
|
||||
{
|
||||
return [
|
||||
['settings', 'safe']
|
||||
];
|
||||
}
|
||||
|
||||
public function targets($user = null)
|
||||
{
|
||||
if(!$this->_targets) {
|
||||
$this->_targets = Yii::$app->notification->getTargets($user);
|
||||
}
|
||||
|
||||
return $this->_targets;
|
||||
}
|
||||
|
||||
public function categories($user = null)
|
||||
{
|
||||
return Yii::$app->notification->getNotificationCategories($user);
|
||||
}
|
||||
|
||||
public function getSettingFormname($category, $target)
|
||||
{
|
||||
return $this->formName()."[settings][".$target->getSettingKey($category)."]";
|
||||
}
|
||||
|
||||
public function save($user = null)
|
||||
{
|
||||
$module = Yii::$app->getModule('notification');
|
||||
$settingManager = ($user) ? $module->settings->user($user) : $module->settings;
|
||||
foreach ($this->settings as $settingKey => $value) {
|
||||
$settingManager->set($settingKey, $value);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
<?php
|
||||
namespace user;
|
||||
namespace notification;
|
||||
|
||||
/**
|
||||
* Inherited Methods
|
||||
|
@ -1,5 +1,5 @@
|
||||
<?php
|
||||
namespace user;
|
||||
namespace notification;
|
||||
|
||||
/**
|
||||
* Inherited Methods
|
||||
|
@ -1,5 +1,5 @@
|
||||
<?php
|
||||
namespace user;
|
||||
namespace notification;
|
||||
|
||||
/**
|
||||
* Inherited Methods
|
||||
|
@ -1,4 +1,4 @@
|
||||
<?php //[STAMP] 890a71cd7f21af7a261c0d3eceef09fb
|
||||
<?php //[STAMP] c20a7faea2c1c711fd2f9ce4e9fd6e65
|
||||
namespace notification\_generated;
|
||||
|
||||
// This class was automatically generated by build task
|
||||
|
@ -1,4 +1,4 @@
|
||||
<?php //[STAMP] 74c0c3a2840b2412882616390669c863
|
||||
<?php //[STAMP] 25c2b4e8b8fd2158213a3465a3ef3b60
|
||||
namespace notification\_generated;
|
||||
|
||||
// This class was automatically generated by build task
|
||||
|
@ -1,4 +1,4 @@
|
||||
<?php //[STAMP] e93907d5924b39a3cd4134cc6a6ea3a3
|
||||
<?php //[STAMP] 0468b7e2480518455b63a22d3aa6f7c2
|
||||
namespace notification\_generated;
|
||||
|
||||
// This class was automatically generated by build task
|
||||
|
@ -1,9 +1,2 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
|
||||
return [];
|
@ -0,0 +1,154 @@
|
||||
<?php
|
||||
|
||||
namespace humhub\modules\notification\tests\codeception\unit\category;
|
||||
|
||||
use Yii;
|
||||
use tests\codeception\_support\HumHubDbTestCase;
|
||||
use Codeception\Specify;
|
||||
use humhub\modules\notification\components\MailNotificationTarget;
|
||||
use humhub\modules\notification\components\WebNotificationTarget;
|
||||
use humhub\modules\notification\tests\codeception\unit\category\notifications\TestNotification;
|
||||
use humhub\modules\notification\tests\codeception\unit\category\notifications\SpecialNotification;
|
||||
use humhub\modules\notification\models\forms\NotificationSettings;
|
||||
|
||||
class NotificationCategoryTest extends HumHubDbTestCase
|
||||
{
|
||||
|
||||
use Specify;
|
||||
|
||||
public function testGlobalCategorySetting()
|
||||
{
|
||||
$notification = new TestNotification();
|
||||
$category = $notification->getCategory();
|
||||
$mailTarget = Yii::$app->notification->getTarget(MailNotificationTarget::class);
|
||||
$webTarget = Yii::$app->notification->getTarget(WebNotificationTarget::class);
|
||||
|
||||
$this->assertFalse($mailTarget->isEnabled($notification));
|
||||
$this->assertTrue($webTarget->isEnabled($notification));
|
||||
|
||||
$settingForm = new NotificationSettings([
|
||||
'settings' => [
|
||||
$mailTarget->getSettingKey($category) => true,
|
||||
$webTarget->getSettingKey($category) => false,
|
||||
]
|
||||
]);
|
||||
|
||||
$settingForm->save();
|
||||
|
||||
$this->assertTrue($mailTarget->isEnabled($notification));
|
||||
$this->assertFalse($webTarget->isEnabled($notification));
|
||||
}
|
||||
|
||||
public function testFixedCategorySetting()
|
||||
{
|
||||
$notification = new SpecialNotification();
|
||||
$category = $notification->getCategory();
|
||||
$mailTarget = Yii::$app->notification->getTarget(MailNotificationTarget::class);
|
||||
$webTarget = Yii::$app->notification->getTarget(WebNotificationTarget::class);
|
||||
|
||||
$this->assertFalse($mailTarget->isEnabled($notification));
|
||||
$this->assertFalse($webTarget->isEnabled($notification));
|
||||
|
||||
// Set true for both
|
||||
$settingForm = new NotificationSettings([
|
||||
'settings' => [
|
||||
$mailTarget->getSettingKey($category) => true,
|
||||
$webTarget->getSettingKey($category) => true,
|
||||
]
|
||||
]);
|
||||
|
||||
$settingForm->save();
|
||||
|
||||
// Check that setting does not effect fixed target setting.
|
||||
$this->assertTrue($webTarget->isEnabled($notification));
|
||||
$this->assertFalse($mailTarget->isEnabled($notification));
|
||||
}
|
||||
|
||||
public function testInvisibleCategorySetting()
|
||||
{
|
||||
// SpecialCategory is invisible for this user.
|
||||
$this->becomeUser('User1');
|
||||
$user = Yii::$app->user->getIdentity();
|
||||
$notification = new SpecialNotification();
|
||||
$category = $notification->getCategory();
|
||||
$mailTarget = Yii::$app->notification->getTarget(MailNotificationTarget::class);
|
||||
$webTarget = Yii::$app->notification->getTarget(WebNotificationTarget::class);
|
||||
|
||||
$this->assertFalse($mailTarget->isEnabled($notification));
|
||||
$this->assertFalse($webTarget->isEnabled($notification));
|
||||
|
||||
// Set global settings to true for both targets
|
||||
$settingForm = new NotificationSettings([
|
||||
'settings' => [
|
||||
$mailTarget->getSettingKey($category) => true,
|
||||
$webTarget->getSettingKey($category) => true,
|
||||
]
|
||||
]);
|
||||
|
||||
$settingForm->save();
|
||||
|
||||
// Check this does not affect the decision for this user
|
||||
$this->assertFalse($webTarget->isEnabled($notification, $user));
|
||||
$this->assertFalse($mailTarget->isEnabled($notification, $user));
|
||||
|
||||
// Save again for the user
|
||||
$settingForm = new NotificationSettings([
|
||||
'settings' => [
|
||||
$mailTarget->getSettingKey($category) => true,
|
||||
$webTarget->getSettingKey($category) => true,
|
||||
]
|
||||
]);
|
||||
|
||||
$settingForm->save($user);
|
||||
|
||||
// Check this does not affect the decision for this user
|
||||
$this->assertFalse($webTarget->isEnabled($notification, $user));
|
||||
$this->assertFalse($mailTarget->isEnabled($notification, $user));
|
||||
}
|
||||
|
||||
public function testUserCategorySetting()
|
||||
{
|
||||
$this->becomeUser('User2');
|
||||
$user = Yii::$app->user->getIdentity();
|
||||
$notification = new TestNotification();
|
||||
$category = $notification->getCategory();
|
||||
$mailTarget = Yii::$app->notification->getTarget(MailNotificationTarget::class);
|
||||
$webTarget = Yii::$app->notification->getTarget(WebNotificationTarget::class);
|
||||
|
||||
// Check default settings.
|
||||
$this->assertFalse($mailTarget->isEnabled($notification, $user));
|
||||
$this->assertTrue($webTarget->isEnabled($notification, $user));
|
||||
|
||||
// Change global default settings, deny both targets.
|
||||
$settingForm = new NotificationSettings([
|
||||
'settings' => [
|
||||
$mailTarget->getSettingKey($category) => false,
|
||||
$webTarget->getSettingKey($category) => false,
|
||||
]
|
||||
]);
|
||||
|
||||
$settingForm->save();
|
||||
|
||||
// Check if global defaults effected user check
|
||||
$this->assertFalse($mailTarget->isEnabled($notification, $user));
|
||||
$this->assertFalse($webTarget->isEnabled($notification, $user));
|
||||
|
||||
// Change user settings.
|
||||
$userSettings = new NotificationSettings([
|
||||
'settings' => [
|
||||
$mailTarget->getSettingKey($category) => true,
|
||||
$webTarget->getSettingKey($category) => true,
|
||||
]
|
||||
]);
|
||||
|
||||
$userSettings->save($user);
|
||||
|
||||
// Check that global settings are unaffected
|
||||
$this->assertFalse($mailTarget->isEnabled($notification));
|
||||
$this->assertFalse($webTarget->isEnabled($notification));
|
||||
|
||||
// Check if user settings
|
||||
$this->assertTrue($mailTarget->isEnabled($notification, $user));
|
||||
$this->assertTrue($webTarget->isEnabled($notification, $user));
|
||||
}
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
namespace humhub\modules\notification\tests\codeception\unit\category\notifications;
|
||||
|
||||
/**
|
||||
* Description of TestedDefaultViewNotification
|
||||
*
|
||||
* @author buddha
|
||||
*/
|
||||
class SpecialNotification extends \humhub\modules\notification\components\BaseNotification
|
||||
{
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function category()
|
||||
{
|
||||
return new SpecialNotificationCategory();
|
||||
}
|
||||
}
|
@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
namespace humhub\modules\notification\tests\codeception\unit\category\notifications;
|
||||
|
||||
|
||||
use humhub\modules\notification\components\NotificationTarget;
|
||||
|
||||
/**
|
||||
* Description of TestedDefaultViewNotification
|
||||
*
|
||||
* @author buddha
|
||||
*/
|
||||
class SpecialNotificationCategory extends \humhub\modules\notification\components\NotificationCategory
|
||||
{
|
||||
|
||||
public $id = 'test_special';
|
||||
|
||||
public function getDefaultSetting(NotificationTarget $target)
|
||||
{
|
||||
if ($target->id === \humhub\modules\notification\components\MailNotificationTarget::getId()) {
|
||||
return false;
|
||||
} else if ($target->id === \humhub\modules\notification\components\WebNotificationTarget::getId()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $target->defaultSetting;
|
||||
}
|
||||
|
||||
public function getFixedSettings()
|
||||
{
|
||||
return [\humhub\modules\notification\components\MailNotificationTarget::getId()];
|
||||
}
|
||||
|
||||
public function isVisible(\humhub\modules\user\models\User $user = null)
|
||||
{
|
||||
return !$user || $user->id != 2;
|
||||
}
|
||||
|
||||
public function getDescription()
|
||||
{
|
||||
return 'My Special Test Notification Category';
|
||||
}
|
||||
|
||||
public function getTitle()
|
||||
{
|
||||
return 'Test Special Category';
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace humhub\modules\notification\tests\codeception\unit\category\notifications;
|
||||
|
||||
/**
|
||||
* Description of TestedDefaultViewNotification
|
||||
*
|
||||
* @author buddha
|
||||
*/
|
||||
class TestNotification extends \humhub\modules\notification\components\BaseNotification
|
||||
{
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function category()
|
||||
{
|
||||
return new TestNotificationCategory();
|
||||
}
|
||||
}
|
@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
namespace humhub\modules\notification\tests\codeception\unit\category\notifications;
|
||||
|
||||
|
||||
use humhub\modules\notification\components\NotificationTarget;
|
||||
|
||||
/**
|
||||
* Description of TestedDefaultViewNotification
|
||||
*
|
||||
* @author buddha
|
||||
*/
|
||||
class TestNotificationCategory extends \humhub\modules\notification\components\NotificationCategory
|
||||
{
|
||||
|
||||
public $id = 'test';
|
||||
|
||||
public function getDefaultSetting(NotificationTarget $target)
|
||||
{
|
||||
if ($target->id === \humhub\modules\notification\components\MailNotificationTarget::getId()) {
|
||||
return false;
|
||||
} else if ($target->id === \humhub\modules\notification\components\WebNotificationTarget::getId()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return $target->defaultSetting;
|
||||
}
|
||||
|
||||
|
||||
public function getDescription()
|
||||
{
|
||||
return 'My Test Notification Category';
|
||||
}
|
||||
|
||||
public function getTitle()
|
||||
{
|
||||
return 'Test Category';
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,43 @@
|
||||
<?php
|
||||
|
||||
namespace humhub\modules\notification\tests\codeception\unit\rendering;
|
||||
|
||||
use Yii;
|
||||
use tests\codeception\_support\HumHubDbTestCase;
|
||||
use Codeception\Specify;
|
||||
use humhub\modules\notification\components\MailNotificationTarget;
|
||||
|
||||
class MailTargetRenderTest extends HumHubDbTestCase
|
||||
{
|
||||
|
||||
use Specify;
|
||||
|
||||
public function testDefaultView()
|
||||
{
|
||||
$notification = notifications\TestedMailViewNotification::instance();
|
||||
$target = Yii::$app->notification->getTarget(MailNotificationTarget::class);
|
||||
$renderer = $target->getRenderer();
|
||||
$this->assertContains('<h1>TestedMailViewNotificationHTML</h1>', $renderer->render($notification));
|
||||
$this->assertContains('TestedMailViewNotificationText', $renderer->renderText($notification));
|
||||
}
|
||||
|
||||
public function testOverwriteViewFile()
|
||||
{
|
||||
$notification = notifications\TestedMailViewNotification::instance();
|
||||
$notification->viewName = 'special';
|
||||
$target = Yii::$app->notification->getTarget(MailNotificationTarget::class);
|
||||
$renderer = $target->getRenderer();
|
||||
$this->assertContains('<div>Special:<h1>TestedMailViewNotificationHTML</h1></div>', $renderer->render($notification));
|
||||
$this->assertContains('TestedMailViewNotificationText', $renderer->renderText($notification));
|
||||
}
|
||||
|
||||
public function testOverwriteLayoutFile()
|
||||
{
|
||||
$notification = notifications\TestedMailViewNotification::instance();
|
||||
$notification->viewName = 'specialLayout';
|
||||
$target = Yii::$app->notification->getTarget(MailNotificationTarget::class);
|
||||
$renderer = $target->getRenderer();
|
||||
$this->assertEquals('<div>MyLayout:<h1>TestedMailViewNotificationHTML</h1></div>', trim($renderer->render($notification)));
|
||||
$this->assertEquals('MyLayout:TestedMailViewNotificationText', trim($renderer->renderText($notification)));
|
||||
}
|
||||
}
|
@ -0,0 +1,46 @@
|
||||
<?php
|
||||
|
||||
namespace humhub\modules\notification\tests\codeception\unit\rendering;
|
||||
|
||||
use Yii;
|
||||
use tests\codeception\_support\HumHubDbTestCase;
|
||||
use Codeception\Specify;
|
||||
use humhub\modules\notification\components\WebNotificationTarget;
|
||||
|
||||
class WebTargetRenderTest extends HumHubDbTestCase
|
||||
{
|
||||
|
||||
use Specify;
|
||||
|
||||
public function testDefaultView()
|
||||
{
|
||||
$notification = notifications\TestedMailViewNotification::instance();
|
||||
$target = Yii::$app->notification->getTarget(WebNotificationTarget::class);
|
||||
$renderer = $target->getRenderer();
|
||||
$result = $renderer->render($notification);
|
||||
$this->assertContains('New', $result);
|
||||
$this->assertContains('<h1>TestedMailViewNotificationHTML</h1>', $result);
|
||||
}
|
||||
|
||||
public function testOverwriteViewFile()
|
||||
{
|
||||
$notification = notifications\TestedMailViewNotification::instance();
|
||||
$notification->viewName = 'special';
|
||||
$target = Yii::$app->notification->getTarget(WebNotificationTarget::class);
|
||||
$renderer = $target->getRenderer();
|
||||
$result = $renderer->render($notification);
|
||||
$this->assertContains('New', $result);
|
||||
$this->assertContains('<div>Special:<h1>TestedMailViewNotificationHTML</h1></div>', $result);
|
||||
}
|
||||
|
||||
public function testOverwriteLayoutFile()
|
||||
{
|
||||
$notification = notifications\TestedMailViewNotification::instance();
|
||||
$notification->viewName = 'specialLayout';
|
||||
$target = Yii::$app->notification->getTarget(WebNotificationTarget::class);
|
||||
$renderer = $target->getRenderer();
|
||||
$result = $renderer->render($notification);
|
||||
$this->assertNotContains('New', $result);
|
||||
$this->assertEquals('<div>MyLayout:<h1>TestedMailViewNotificationHTML</h1></div>', trim($result));
|
||||
}
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
namespace humhub\modules\notification\tests\codeception\unit\rendering\notifications;
|
||||
|
||||
/**
|
||||
* Description of TestedDefaultViewNotification
|
||||
*
|
||||
* @author buddha
|
||||
*/
|
||||
class TestedMailViewNotification extends \humhub\modules\notification\components\BaseNotification
|
||||
{
|
||||
public function html()
|
||||
{
|
||||
return '<h1>TestedMailViewNotificationHTML</h1>';
|
||||
}
|
||||
|
||||
public function text()
|
||||
{
|
||||
return 'TestedMailViewNotificationText';
|
||||
}
|
||||
}
|
@ -0,0 +1,2 @@
|
||||
MyLayout:<?= $content ?>
|
||||
|
@ -0,0 +1,2 @@
|
||||
<div>MyLayout:<?= $content ?></div>
|
||||
|
@ -0,0 +1,2 @@
|
||||
<div>MyLayout:<?= $content ?></div>
|
||||
|
@ -0,0 +1,2 @@
|
||||
<div>Special:<?= $html ?></div>
|
||||
|
@ -0,0 +1,2 @@
|
||||
<div>Special:<?= $html ?></div>
|
||||
|
@ -64,7 +64,7 @@ use yii\helpers\Html;
|
||||
<tr>
|
||||
<td style="font-size: 13px; line-height: 22px; font-family:Open Sans,Arial,Tahoma, Helvetica, sans-serif; color:#555555; font-weight:300; text-align:left; ">
|
||||
|
||||
<?php echo $content; ?>
|
||||
<?= $content; ?>
|
||||
|
||||
<!-- check if activity object has a space -->
|
||||
<?php if ($space !== null): ?>
|
||||
|
@ -8,7 +8,7 @@
|
||||
|
||||
?>
|
||||
<li class="<?php if ($isNew) : ?>new<?php endif; ?>">
|
||||
<a href="<?php echo $url; ?>">
|
||||
<a href="<?= $url; ?>">
|
||||
<div class="media">
|
||||
|
||||
<!-- show user image -->
|
||||
@ -30,10 +30,10 @@
|
||||
<!-- show content -->
|
||||
<div class="media-body">
|
||||
|
||||
<?php echo $content; ?>
|
||||
<?= $content; ?>
|
||||
|
||||
<br> <?php echo humhub\widgets\TimeAgo::widget(['timestamp' => $record->created_at]); ?>
|
||||
<?php if ($isNew) : ?> <span class="label label-danger"><?php echo Yii::t('NotificationModule.views_notificationLayout', 'New'); ?></span><?php endif; ?>
|
||||
<?php if ($isNew) : ?> <span class="label label-danger"><?= Yii::t('NotificationModule.views_notificationLayout', 'New'); ?></span><?php endif; ?>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
@ -1 +1 @@
|
||||
<?= $asHtml; ?>
|
||||
<?= $html; ?>
|
@ -0,0 +1 @@
|
||||
<?= $html; ?>
|
@ -1 +1 @@
|
||||
<?= $asText; ?>
|
||||
<?= $text; ?>
|
@ -0,0 +1,38 @@
|
||||
<?php
|
||||
namespace humhub\modules\notification\widgets;
|
||||
|
||||
/**
|
||||
* Description of NotificationSettingForm
|
||||
*
|
||||
* @author buddha
|
||||
*/
|
||||
class NotificationSettingsForm extends \yii\base\Widget
|
||||
{
|
||||
/**
|
||||
* @var \yii\widgets\ActiveForm
|
||||
*/
|
||||
public $form;
|
||||
|
||||
/**
|
||||
* @var \humhub\modules\notification\models\forms\NotificationSettings
|
||||
*/
|
||||
public $model;
|
||||
|
||||
/**
|
||||
* Used for user notification settings. If null use global settings.
|
||||
* @var type
|
||||
*/
|
||||
public $user;
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
return $this->render('notificationSettingsForm', [
|
||||
'form' => $this->form,
|
||||
'model' => $this->model,
|
||||
'user' => $this->user
|
||||
]);
|
||||
}
|
||||
}
|
@ -0,0 +1,43 @@
|
||||
<?php
|
||||
/* @var $model \humhub\modules\notification\models\forms\NotificationSettings */
|
||||
/* @var $form yii\widgets\ActiveForm */
|
||||
|
||||
use yii\bootstrap\Html
|
||||
?>
|
||||
<div class="table-responsive">
|
||||
<table class="table table-middle table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th><?= Yii::t('NotificationModule.widgets_views_notificationSettingsForm', 'Category') ?></th>
|
||||
<th><?= Yii::t('NotificationModule.widgets_views_notificationSettingsForm', 'Description') ?></th>
|
||||
<?php foreach ($model->targets($user) as $target): ?>
|
||||
<th class="text-center">
|
||||
<?= $target->getTitle(); ?>
|
||||
</th>
|
||||
<?php endforeach; ?>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($model->categories($user) as $category): ?>
|
||||
<tr>
|
||||
<td>
|
||||
<?= $category->getTitle() ?>
|
||||
</td>
|
||||
<td>
|
||||
<?= $category->getDescription() ?>
|
||||
</td>
|
||||
|
||||
<?php foreach ($model->targets($user) as $target): ?>
|
||||
<td class="text-center">
|
||||
<label style="margin:0px;">
|
||||
<?= Html::checkbox($model->getSettingFormname($category, $target), $target->isCategoryEnabled($category), ['style' => 'margin:0px;']) ?>
|
||||
</label>
|
||||
</td>
|
||||
<?php endforeach; ?>
|
||||
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
@ -53,6 +53,7 @@ humhub.module('post', function(module, require, $) {
|
||||
};
|
||||
|
||||
Post.prototype.toggleCollapse = function() {
|
||||
debugger;
|
||||
if(this.$.data('state') === 'collapsed') {
|
||||
this.expand();
|
||||
} else {
|
||||
|
@ -1,3 +1,5 @@
|
||||
<span data-ui-widget="post.Post" data-state="collapsed" data-ui-init id="post-content-<?= $post->id; ?>" style="overflow: hidden; margin-bottom: 5px;">
|
||||
<?= humhub\widgets\RichText::widget(['text' => $post->message, 'record' => $post]) ?>
|
||||
</span>
|
||||
<div data-ui-widget="post.Post" data-state="collapsed" data-ui-init id="post-content-<?= $post->id; ?>" style="overflow: hidden; margin-bottom: 5px;">
|
||||
<div data-ui-markdown>
|
||||
<?= humhub\widgets\RichText::widget(['text' => $post->message, 'record' => $post]) ?>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -46,7 +46,7 @@ class SpaceModelMembership extends Behavior
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Checks if a given Userid is allowed to leave this space.
|
||||
* A User is allowed to leave, if the can_cancel_membership flag in the space_membership table is 1. If it is 2, the decision is delegated to the space.
|
||||
@ -56,17 +56,17 @@ class SpaceModelMembership extends Behavior
|
||||
*/
|
||||
public function canLeave($userId = "")
|
||||
{
|
||||
|
||||
|
||||
// Take current userid if none is given
|
||||
if ($userId == "")
|
||||
$userId = Yii::$app->user->id;
|
||||
|
||||
|
||||
$membership = $this->getMembership($userId);
|
||||
|
||||
if ($membership != null && !empty($membership->can_cancel_membership)) {
|
||||
return $membership->can_cancel_membership === 1 || ($membership->can_cancel_membership === 2 && !empty($this->owner->members_can_leave));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -182,8 +182,9 @@ class SpaceModelMembership extends Behavior
|
||||
*/
|
||||
public function getMembership($userId = "")
|
||||
{
|
||||
if ($userId == "")
|
||||
if ($userId == "") {
|
||||
$userId = Yii::$app->user->id;
|
||||
}
|
||||
|
||||
return Membership::findOne(['user_id' => $userId, 'space_id' => $this->owner->id]);
|
||||
}
|
||||
@ -209,7 +210,7 @@ class SpaceModelMembership extends Behavior
|
||||
|
||||
$userInvite = Invite::findOne(['email' => $email]);
|
||||
// No invite yet
|
||||
if ($userInvite == null) {
|
||||
if ($userInvite == null) {
|
||||
// Invite EXTERNAL user
|
||||
$userInvite = new Invite();
|
||||
$userInvite->email = $email;
|
||||
@ -224,12 +225,12 @@ class SpaceModelMembership extends Behavior
|
||||
$userInvite->user_originator_id = $originatorUserId;
|
||||
$userInvite->space_invite_id = $this->owner->id;
|
||||
}
|
||||
|
||||
if($userInvite->validate() && $userInvite->save()) {
|
||||
|
||||
if ($userInvite->validate() && $userInvite->save()) {
|
||||
$userInvite->sendInviteMail();
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -279,51 +280,58 @@ class SpaceModelMembership extends Behavior
|
||||
* If user is applicant approve it.
|
||||
*
|
||||
* @param type $userId
|
||||
* @param type $originatorUserId
|
||||
* @param type $originatorId
|
||||
*/
|
||||
public function inviteMember($userId, $originatorUserId)
|
||||
public function inviteMember($userId, $originatorId)
|
||||
{
|
||||
$membership = $this->getMembership($userId);
|
||||
|
||||
if ($membership != null) {
|
||||
|
||||
// User is already member
|
||||
if ($membership->status == Membership::STATUS_MEMBER) {
|
||||
return;
|
||||
}
|
||||
|
||||
// User requested already membership, just approve him
|
||||
if ($membership->status == Membership::STATUS_APPLICANT) {
|
||||
$this->addMember(Yii::$app->user->id);
|
||||
return;
|
||||
}
|
||||
|
||||
// Already invite, reinvite him
|
||||
if ($membership->status == Membership::STATUS_INVITED) {
|
||||
// Remove existing notification
|
||||
$notification = new \humhub\modules\space\notifications\Invite;
|
||||
$notification->source = $this->owner;
|
||||
$notification->delete(User::findOne(['id' => $userId]));
|
||||
switch ($membership->status) {
|
||||
case Membership::STATUS_APPLICANT:
|
||||
// If user is an applicant of this space add user and return.
|
||||
$this->addMember(Yii::$app->user->id);
|
||||
case Membership::STATUS_MEMBER:
|
||||
// If user is already a member just ignore the invitation.
|
||||
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->delete(User::findOne(['id' => $userId]));
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
$membership = new Membership;
|
||||
$membership = new Membership([
|
||||
'space_id' => $this->owner->id,
|
||||
'user_id' => $userId,
|
||||
'status' => Membership::STATUS_INVITED,
|
||||
'group_id' => Space::USERGROUP_MEMBER
|
||||
]);
|
||||
}
|
||||
|
||||
// Update or set originator
|
||||
$membership->originator_user_id = $originatorId;
|
||||
|
||||
$membership->space_id = $this->owner->id;
|
||||
$membership->user_id = $userId;
|
||||
$membership->originator_user_id = $originatorUserId;
|
||||
|
||||
$membership->status = Membership::STATUS_INVITED;
|
||||
$membership->group_id = Space::USERGROUP_MEMBER;
|
||||
|
||||
if (!$membership->save()) {
|
||||
if ($membership->save()) {
|
||||
$this->sendInviteNotification($userId, $originatorId);
|
||||
} else {
|
||||
throw new \yii\base\Exception("Could not save membership!" . print_r($membership->getErrors(), 1));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends an Invite Notification to the given user.
|
||||
*
|
||||
* @param type $userId
|
||||
* @param type $originatorId
|
||||
*/
|
||||
protected function sendInviteNotification($userId, $originatorId)
|
||||
{
|
||||
$notification = new \humhub\modules\space\notifications\Invite([
|
||||
'source' => $this->owner,
|
||||
'originator' => User::findOne(['id' => $originatorId])
|
||||
]);
|
||||
|
||||
$notification = new \humhub\modules\space\notifications\Invite;
|
||||
$notification->source = $this->owner;
|
||||
$notification->originator = User::findOne(['id' => $originatorUserId]);
|
||||
$notification->send(User::findOne(['id' => $userId]));
|
||||
}
|
||||
|
||||
@ -412,8 +420,9 @@ class SpaceModelMembership extends Behavior
|
||||
*/
|
||||
public function removeMember($userId = "")
|
||||
{
|
||||
if ($userId == "")
|
||||
if ($userId == "") {
|
||||
$userId = Yii::$app->user->id;
|
||||
}
|
||||
|
||||
$user = User::findOne(['id' => $userId]);
|
||||
|
||||
|
@ -157,7 +157,7 @@ class MembershipController extends \humhub\modules\content\components\ContentCon
|
||||
|
||||
// Check Permissions to Invite
|
||||
if (!$space->canInvite()) {
|
||||
throw new HttpException(403, 'Access denied - You cannot invite members!');
|
||||
throw new HttpException(403, Yii::t('SpaceModule.controllers_MembershipController', 'Access denied - You cannot invite members!'));
|
||||
}
|
||||
|
||||
$model = new \humhub\modules\space\models\forms\InviteForm();
|
||||
|
@ -9,10 +9,7 @@
|
||||
namespace humhub\modules\space\models;
|
||||
|
||||
use Yii;
|
||||
use humhub\modules\comment\models\Comment;
|
||||
use humhub\modules\user\models\User;
|
||||
use humhub\modules\content\models\WallEntry;
|
||||
use humhub\modules\activity\models\Activity;
|
||||
|
||||
|
||||
/**
|
||||
|
@ -29,11 +29,19 @@ class ApprovalRequest extends BaseNotification
|
||||
* @inheritdoc
|
||||
*/
|
||||
public $markAsSeenOnClick = false;
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function category()
|
||||
{
|
||||
return new SpaceMemberNotificationCategory;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getAsHtml()
|
||||
public function html()
|
||||
{
|
||||
return Yii::t('SpaceModule.notification', '{displayName} requests membership for the space {spaceName}', array(
|
||||
'{displayName}' => Html::tag('strong', Html::encode($this->originator->displayName)),
|
||||
|
@ -25,10 +25,18 @@ class ApprovalRequestAccepted extends BaseNotification
|
||||
*/
|
||||
public $moduleId = "space";
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function category()
|
||||
{
|
||||
return new SpaceMemberNotificationCategory;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getAsHtml()
|
||||
public function html()
|
||||
{
|
||||
return Yii::t('SpaceModule.notification', '{displayName} approved your membership for the space {spaceName}', array(
|
||||
'{displayName}' => Html::tag('strong', Html::encode($this->originator->displayName)),
|
||||
|
@ -24,11 +24,19 @@ class ApprovalRequestDeclined extends BaseNotification
|
||||
* @inheritdoc
|
||||
*/
|
||||
public $moduleId = "space";
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function category()
|
||||
{
|
||||
return new SpaceMemberNotificationCategory;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getAsHtml()
|
||||
public function html()
|
||||
{
|
||||
return Yii::t('SpaceModule.notification', '{displayName} declined your membership request for the space {spaceName}', array(
|
||||
'{displayName}' => Html::tag('strong', Html::encode($this->originator->displayName)),
|
||||
|
@ -29,11 +29,19 @@ class Invite extends BaseNotification
|
||||
* @inheritdoc
|
||||
*/
|
||||
public $markAsSeenOnClick = false;
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function category()
|
||||
{
|
||||
return new SpaceMemberNotificationCategory;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getAsHtml()
|
||||
public function html()
|
||||
{
|
||||
return Yii::t('SpaceModule.notification', '{displayName} invited you to the space {spaceName}', array(
|
||||
'{displayName}' => Html::tag('strong', Html::encode($this->originator->displayName)),
|
||||
|
@ -26,11 +26,19 @@ class InviteAccepted extends BaseNotification
|
||||
* @inheritdoc
|
||||
*/
|
||||
public $moduleId = "space";
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function category()
|
||||
{
|
||||
return new SpaceMemberNotificationCategory;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getAsHtml()
|
||||
public function html()
|
||||
{
|
||||
return Yii::t('SpaceModule.notification', '{displayName} accepted your invite for the space {spaceName}', array(
|
||||
'{displayName}' => Html::tag('strong', Html::encode($this->originator->displayName)),
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user