Enh: Make profile content archivable

Fix: container property not set on StreamQuery init
Enh: Archived stream filter now only included archived content
This commit is contained in:
buddh4 2020-07-13 16:52:35 +02:00
parent 25b718fb4e
commit c81d52e9a3
7 changed files with 112 additions and 22 deletions

View File

@ -16,3 +16,5 @@ HumHub Change Log
- Fix #4199: Pinned posts of other spaces are excluded from profile stream - Fix #4199: Pinned posts of other spaces are excluded from profile stream
- Enh #3995: Added additional user profile stream filter to include or exclude non profile stream content - Enh #3995: Added additional user profile stream filter to include or exclude non profile stream content
- Enh: Added `humhub\modules\stream\actions\Stream:initQuery` to manage query filter in subclasses - Enh: Added `humhub\modules\stream\actions\Stream:initQuery` to manage query filter in subclasses
- Enh: Make profile content archivable
- Enh: Archived stream filter now only included archived content

View File

@ -223,7 +223,7 @@ abstract class Stream extends Action
$streamQueryClass = $this->streamQueryClass; $streamQueryClass = $this->streamQueryClass;
/* @var $instance StreamQuery */ /* @var $instance StreamQuery */
$instance = $streamQueryClass::find($this->includes, $this->excludes)->forUser($this->user); $instance = $streamQueryClass::find($this->includes, $this->excludes)->forUser($this->user);
$instance->setAttributes($options); $instance->setAttributes($options, false);
return $instance; return $instance;
} }

View File

@ -61,8 +61,10 @@ class DefaultStreamFilter extends StreamQueryFilter
$this->filterFile(); $this->filterFile();
} }
// Only apply archived filter when we should load more than one entry if ($this->isFilterActive(self::FILTER_ARCHIVED)) {
if (!$this->streamQuery->isSingleContentQuery() && !$this->isFilterActive(self::FILTER_ARCHIVED)) { $this->filterArchived();
} else if(!$this->streamQuery->isSingleContentQuery()) {
// Only omit archived content by default when we load more than one entry
$this->unFilterArchived(); $this->unFilterArchived();
} }
@ -108,6 +110,12 @@ class DefaultStreamFilter extends StreamQueryFilter
return $this; return $this;
} }
protected function filterArchived()
{
$this->query->andWhere("(content.archived = 1)");
return $this;
}
protected function filterMine() protected function filterMine()
{ {
if ($this->streamQuery->user) { if ($this->streamQuery->user) {

View File

@ -72,6 +72,7 @@ class WallStreamFilterNavigation extends FilterNavigation
const FILTER_BLOCK_BASIC = 'basic'; const FILTER_BLOCK_BASIC = 'basic';
const FILTER_BLOCK_VISIBILITY = 'visibility'; const FILTER_BLOCK_VISIBILITY = 'visibility';
const FILTER_BLOCK_SORTING = 'sorting'; const FILTER_BLOCK_SORTING = 'sorting';
const FILTER_BLOCK_SCOPE = 'scope';
const FILTER_BLOCK_CONTENT_TYPE = 'contentType'; const FILTER_BLOCK_CONTENT_TYPE = 'contentType';
const FILTER_BLOCK_TOPIC = 'topics'; const FILTER_BLOCK_TOPIC = 'topics';
const FILTER_BLOCK_ORIGINATORS = 'originators'; const FILTER_BLOCK_ORIGINATORS = 'originators';
@ -183,6 +184,12 @@ class WallStreamFilterNavigation extends FilterNavigation
'title' => Yii::t('ContentModule.base', 'With file attachments'), 'title' => Yii::t('ContentModule.base', 'With file attachments'),
'sortOrder' => 300 'sortOrder' => 300
], static::FILTER_BLOCK_BASIC); ], static::FILTER_BLOCK_BASIC);
$this->addFilter([
'id' => static::FILTER_ARCHIVED,
'title' => Yii::t('ContentModule.base', 'Archived'),
'sortOrder' => 200
], static::FILTER_BLOCK_BASIC);
} }
protected function initVisibilityFilters() protected function initVisibilityFilters()
@ -192,7 +199,7 @@ class WallStreamFilterNavigation extends FilterNavigation
// Private spaces do not have public content // Private spaces do not have public content
if($container && $container->canAccessPrivateContent() if($container && $container->canAccessPrivateContent()
&& ($container instanceof User && ($container instanceof User
|| ($container instanceof Space && $container->visibility != Space::VISIBILITY_NONE))) { || ($container instanceof Space && $container->visibility !== Space::VISIBILITY_NONE))) {
$this->addFilter([ $this->addFilter([
'id' => static::FILTER_VISIBILITY_PUBLIC, 'id' => static::FILTER_VISIBILITY_PUBLIC,
@ -212,12 +219,6 @@ class WallStreamFilterNavigation extends FilterNavigation
'sortOrder' => 200 'sortOrder' => 200
], static::FILTER_BLOCK_VISIBILITY); ], static::FILTER_BLOCK_VISIBILITY);
} }
$this->addFilter([
'id' => static::FILTER_ARCHIVED,
'title' => Yii::t('ContentModule.base', 'Include archived content'),
'sortOrder' => 200
], static::FILTER_BLOCK_VISIBILITY);
} }
protected function initSortFilters() protected function initSortFilters()

View File

@ -30,9 +30,13 @@ class ProfileStreamQuery extends ContentContainerStreamQuery
{ {
parent::beforeApplyFilters(); parent::beforeApplyFilters();
$this->removeFilterHandler(ContentContainerStreamFilter::class); $this->removeFilterHandler(ContentContainerStreamFilter::class);
// The default scope may be overwritten by first request, the real default is handled in the stream filter navigation
$this->addFilterHandler(new IncludeAllContributionsFilter([ $this->addFilterHandler(new IncludeAllContributionsFilter([
'container' => $this->container, 'container' => $this->container,
'filters' => $this->includeContributions ? [IncludeAllContributionsFilter::ID] : [] 'scope' => $this->includeContributions
? IncludeAllContributionsFilter::SCOPE_PROFILE
: IncludeAllContributionsFilter::SCOPE_ALL
])); ]));
} }
} }

View File

@ -8,18 +8,23 @@ use humhub\modules\user\models\User;
use Yii; use Yii;
/** /**
* Class IncludeAllContributionsFilter * This stream query filter manages the scope of a profile stream. This filter supports two scopes
* @package humhub\modules\user\stream\filters *
* - `StreamQuery[scope] = 'all'`: Include all user related contributions
* - `StreamQuery[scope] = 'profile'`: Only include profile posts
*
* @since 1.6
*/ */
class IncludeAllContributionsFilter extends ContentContainerStreamFilter class IncludeAllContributionsFilter extends ContentContainerStreamFilter
{ {
const ID = 'includeAllContributions'; const SCOPE_ALL = 'all';
const SCOPE_PROFILE = 'profile';
/** /**
* @var array * @var array
*/ */
public $filters = []; public $scope;
/** /**
* @inheritdoc * @inheritdoc
@ -27,7 +32,7 @@ class IncludeAllContributionsFilter extends ContentContainerStreamFilter
public function rules() public function rules()
{ {
return [ return [
[['filters'], 'safe'] [['scope'], 'safe'],
]; ];
} }
@ -79,8 +84,11 @@ class IncludeAllContributionsFilter extends ContentContainerStreamFilter
$this->query->andWhere("{$conditionSpace} OR {$conditionUser} OR content.contentcontainer_id IS NULL"); $this->query->andWhere("{$conditionSpace} OR {$conditionUser} OR content.contentcontainer_id IS NULL");
} }
/**
* @return bool whether or not the include all filter is active or not
*/
public function isActive() public function isActive()
{ {
return $this->container instanceof User && $this->streamQuery->user !== null && in_array(static::ID, $this->filters); return $this->container instanceof User && $this->streamQuery->user !== null && $this->scope === static::SCOPE_ALL;
} }
} }

View File

@ -5,19 +5,64 @@ namespace humhub\modules\user\widgets;
use humhub\modules\stream\widgets\WallStreamFilterNavigation; use humhub\modules\stream\widgets\WallStreamFilterNavigation;
use humhub\modules\ui\filter\widgets\RadioFilterInput;
use humhub\modules\user\Module; use humhub\modules\user\Module;
use humhub\modules\user\stream\filters\IncludeAllContributionsFilter; use humhub\modules\user\stream\filters\IncludeAllContributionsFilter;
use Yii; use Yii;
/**
* Stream filter navigation for profile streams. The profile stream adds some additional filters as a scope.
*/
class ProfileStreamFilterNavigation extends WallStreamFilterNavigation class ProfileStreamFilterNavigation extends WallStreamFilterNavigation
{ {
/**
* Extra filter category for profile scope
* @since 1.6
*/
const FILTER_BLOCK_SCOPE = 'scope';
/**
* @inheritDoc
*/
protected function initFilterBlocks()
{
parent::initFilterBlocks();
$this->initScopeFilterBlock();
}
/**
* Initializes the profile scope filter block
* @since 1.6
*/
protected function initScopeFilterBlock()
{
if(!$this->isScopeFilterSupported()) {
return;
}
$this->addFilterBlock('scope', [
'title' => Yii::t('StreamModule.filter', 'Scope'),
'sortOrder' => 90
], static::PANEL_POSITION_CENTER);
}
/**
* @inheritDoc
*/
protected function initFilters() protected function initFilters()
{ {
parent::initFilters(); parent::initFilters();
$this->initScopeFilter();
}
// IncludeAllContributionsFilter currently only supported for non guest users /**
if(Yii::$app->user->isGuest) { * Initializes the profile scope filter
* @since 1.6
*/
protected function initScopeFilter()
{
if(!$this->isScopeFilterSupported()) {
return; return;
} }
@ -25,11 +70,33 @@ class ProfileStreamFilterNavigation extends WallStreamFilterNavigation
$module = Yii::$app->getModule('user'); $module = Yii::$app->getModule('user');
$this->addFilter([ $this->addFilter([
'id' => IncludeAllContributionsFilter::ID, 'id' => IncludeAllContributionsFilter::SCOPE_ALL,
'title' => Yii::t('UserModule.base', 'Include all content'), 'title' => Yii::t('UserModule.base', 'Show all content'),
'class' => RadioFilterInput::class,
'category' => 'scope',
'radioGroup' => 'scope',
'force' => true,
'sortOrder' => 500, 'sortOrder' => 500,
'checked' => $module->includeAllUserContentsOnProfile 'checked' => $module->includeAllUserContentsOnProfile
], static::FILTER_BLOCK_BASIC); ], static::FILTER_BLOCK_SCOPE);
$this->addFilter([
'id' => IncludeAllContributionsFilter::SCOPE_PROFILE,
'title' => Yii::t('UserModule.base', 'Profile posts only'),
'class' => RadioFilterInput::class,
'category' => 'scope',
'radioGroup' => 'scope',
'force' => true,
'sortOrder' => 510,
'checked' => !$module->includeAllUserContentsOnProfile
], static::FILTER_BLOCK_SCOPE);
} }
/**
* @return bool scope filter is currently not supported for guest users
*/
protected function isScopeFilterSupported()
{
return !Yii::$app->user->isGuest;
}
} }