mirror of
https://github.com/humhub/humhub.git
synced 2025-02-12 03:26:25 +01:00
- Enh #4213: Only render topic chooser if there are topics available or user can create topics
- Enh: Added `humhub\modules\ui\form\widgets\ActiveField:preventRendering` to manage render state within field classes - Enh: Added `humhub\modules\ui\form\widgets\JsInputWidget:emptyResult()` helper to manage render state of JsInputWidget - Enh: Added `humhub\modules\ui\form\widgets\JsInputWidget:field` in order to access ActiveField instances within JsInputWidget
This commit is contained in:
parent
5ebaa01686
commit
9ef6987034
@ -13,3 +13,7 @@ HumHub Change Log
|
||||
- Chg #4158: Cleanup post table removed unused column
|
||||
- Fix #4182: Native edge password reveal icons interferes with custom one
|
||||
- Fix #4173: Notification overview HTML compliant issue
|
||||
- Enh #4213: Only render topic chooser if there are topics available or user can create topics
|
||||
- Enh: Added `humhub\modules\ui\form\widgets\ActiveField:preventRendering` to manage render state within field classes
|
||||
- Enh: Added `humhub\modules\ui\form\widgets\JsInputWidget:emptyResult()` helper to manage render state of JsInputWidget
|
||||
- Enh: Added `humhub\modules\ui\form\widgets\JsInputWidget:field` in order to access ActiveField instances within JsInputWidget
|
||||
|
@ -31,6 +31,8 @@ class ContentTagDropDown extends JsInputWidget
|
||||
|
||||
public function int()
|
||||
{
|
||||
parent::init();
|
||||
|
||||
if (!$this->tagClass) {
|
||||
$this->tagClass = ContentTag::class;
|
||||
// Reset default behavior inf no specific tagClass is given
|
||||
@ -49,7 +51,7 @@ class ContentTagDropDown extends JsInputWidget
|
||||
$items = $this->getItems();
|
||||
|
||||
if (empty($items)) {
|
||||
return;
|
||||
return $this->emptyResult();
|
||||
}
|
||||
|
||||
$options = $this->getOptions();
|
||||
|
@ -97,9 +97,11 @@ $pickerUrl = ($contentContainer instanceof Space) ? $contentContainer->createUrl
|
||||
<li>
|
||||
<?= Link::withAction(Yii::t('ContentModule.base', 'Notify members'), 'notifyUser')->icon('fa-bell')?>
|
||||
</li>
|
||||
<li>
|
||||
<?= Link::withAction(Yii::t('ContentModule.base', 'Topics'), 'setTopics')->icon(Yii::$app->getModule('topic')->icon) ?>
|
||||
</li>
|
||||
<?php if(TopicPicker::showTopicPicker($contentContainer)) : ?>
|
||||
<li>
|
||||
<?= Link::withAction(Yii::t('ContentModule.base', 'Topics'), 'setTopics')->icon(Yii::$app->getModule('topic')->icon) ?>
|
||||
</li>
|
||||
<?php endif; ?>
|
||||
<?php if ($canSwitchVisibility): ?>
|
||||
<li>
|
||||
<?= Link::withAction(Yii::t('ContentModule.base', 'Make public'), 'changeVisibility')
|
||||
@ -120,4 +122,4 @@ $pickerUrl = ($contentContainer instanceof Space) ? $contentContainer->createUrl
|
||||
<?= Html::endForm(); ?>
|
||||
</div>
|
||||
<!-- /panel body -->
|
||||
</div> <!-- /panel -->
|
||||
</div> <!-- /panel -->
|
||||
|
@ -11,6 +11,7 @@ namespace humhub\modules\topic;
|
||||
use humhub\modules\content\components\ContentActiveRecord;
|
||||
use humhub\modules\topic\models\Topic;
|
||||
use humhub\modules\topic\widgets\ContentTopicButton;
|
||||
use humhub\modules\topic\widgets\TopicPicker;
|
||||
use humhub\modules\ui\menu\MenuLink;
|
||||
use humhub\modules\user\events\UserEvent;
|
||||
use humhub\modules\user\widgets\AccountMenu;
|
||||
@ -24,7 +25,7 @@ class Events extends BaseObject
|
||||
/** @var ContentActiveRecord $record */
|
||||
$record = $event->sender->object;
|
||||
|
||||
if ($record->content->canEdit()) {
|
||||
if ($record->content->canEdit() && TopicPicker::showTopicPicker($record->content->container)) {
|
||||
$event->sender->addWidget(ContentTopicButton::class, ['record' => $record], ['sortOrder' => 370]);
|
||||
}
|
||||
}
|
||||
|
31
protected/humhub/modules/topic/tests/codeception.yml
Normal file
31
protected/humhub/modules/topic/tests/codeception.yml
Normal file
@ -0,0 +1,31 @@
|
||||
actor: Tester
|
||||
namespace: topic
|
||||
bootstrap: _bootstrap.php
|
||||
coverage:
|
||||
c3_url: 'http://localhost:8080/index-test.php'
|
||||
enabled: true
|
||||
remote: false
|
||||
include:
|
||||
- ../models/*
|
||||
- ../widgets/*
|
||||
- ../Module.php
|
||||
settings:
|
||||
suite_class: \PHPUnit_Framework_TestSuite
|
||||
colors: true
|
||||
shuffle: false
|
||||
memory_limit: 1024M
|
||||
log: true
|
||||
|
||||
# This value controls whether PHPUnit attempts to backup global variables
|
||||
# See https://phpunit.de/manual/current/en/appendixes.annotations.html#appendixes.annotations.backupGlobals
|
||||
backup_globals: true
|
||||
paths:
|
||||
tests: codeception
|
||||
log: codeception/_output
|
||||
data: codeception/_data
|
||||
helpers: codeception/_support
|
||||
envs: ../../../tests/config/env
|
||||
config:
|
||||
# the entry script URL (with host info) for functional and acceptance tests
|
||||
# PLEASE ADJUST IT TO THE ACTUAL ENTRY SCRIPT URL
|
||||
test_entry_url: http://localhost:8080/index-test.php
|
@ -0,0 +1,49 @@
|
||||
<?php
|
||||
/**
|
||||
* This is the initial test bootstrap, which will load the default test bootstrap from the humhub core
|
||||
*/
|
||||
// Parse the environment arguments (Note: only simple --env ENV is supported no comma sepration merge...)
|
||||
$env = isset($GLOBALS['env']) ? $GLOBALS['env'] : [];
|
||||
|
||||
// If environment was set try loading special environment config else load default
|
||||
if (count($env) > 0) {
|
||||
\Codeception\Configuration::append(['environment' => $env]);
|
||||
|
||||
|
||||
$envCfgFile = dirname(__DIR__) . '/config/env/test.' . $env[0][0] . '.php';
|
||||
|
||||
if (file_exists($envCfgFile)) {
|
||||
$cfg = array_merge(require_once(__DIR__ . '/../config/test.php'), require_once($envCfgFile));
|
||||
}
|
||||
}
|
||||
|
||||
// If no environment is set we have to load the default config
|
||||
if (!isset($cfg)) {
|
||||
$cfg = require_once(__DIR__ . '/../config/test.php');
|
||||
}
|
||||
|
||||
// If no humhub_root is given we assume our module is in the a root to be in /protected/humhub/modules/<module>/tests/codeception directory
|
||||
$cfg['humhub_root'] = isset($cfg['humhub_root']) ? $cfg['humhub_root'] : dirname(__DIR__) . '/../../../../..';
|
||||
|
||||
|
||||
// Load default test bootstrap
|
||||
require_once($cfg['humhub_root'] . '/protected/humhub/tests/codeception/_bootstrap.php');
|
||||
|
||||
// Overwrite the default test alias
|
||||
Yii::setAlias('@tests', dirname(__DIR__));
|
||||
Yii::setAlias('@env', '@tests/config/env');
|
||||
Yii::setAlias('@root', $cfg['humhub_root']);
|
||||
Yii::setAlias('@humhubTests', $cfg['humhub_root'] . '/protected/humhub/tests');
|
||||
|
||||
// Load all supporting test classes needed for test execution
|
||||
\Codeception\Util\Autoload::addNamespace('', Yii::getAlias('@humhubTests/codeception/_support'));
|
||||
\Codeception\Util\Autoload::addNamespace('tests\codeception\fixtures', Yii::getAlias('@humhubTests/codeception/fixtures'));
|
||||
\Codeception\Util\Autoload::addNamespace('', Yii::getAlias('@humhubTests/codeception/_pages'));
|
||||
if(isset($cfg['modules'])) {
|
||||
\Codeception\Configuration::append(['humhub_modules' => $cfg['modules']]);
|
||||
}
|
||||
|
||||
if(isset($cfg['fixtures'])) {
|
||||
\Codeception\Configuration::append(['fixtures' => $cfg['fixtures']]);
|
||||
}
|
||||
?>
|
4
protected/humhub/modules/topic/tests/codeception/_output/.gitignore
vendored
Normal file
4
protected/humhub/modules/topic/tests/codeception/_output/.gitignore
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
# Ignore everything in this directory
|
||||
*
|
||||
# Except this file
|
||||
!.gitignore
|
@ -0,0 +1,26 @@
|
||||
<?php
|
||||
namespace topic;
|
||||
|
||||
/**
|
||||
* Inherited Methods
|
||||
* @method void wantToTest($text)
|
||||
* @method void wantTo($text)
|
||||
* @method void execute($callable)
|
||||
* @method void expectTo($prediction)
|
||||
* @method void expect($prediction)
|
||||
* @method void amGoingTo($argumentation)
|
||||
* @method void am($role)
|
||||
* @method void lookForwardTo($achieveValue)
|
||||
* @method void comment($description)
|
||||
* @method \Codeception\Lib\Friend haveFriend($name, $actorClass = null)
|
||||
*
|
||||
* @SuppressWarnings(PHPMD)
|
||||
*/
|
||||
class AcceptanceTester extends \AcceptanceTester
|
||||
{
|
||||
use _generated\AcceptanceTesterActions;
|
||||
|
||||
/**
|
||||
* Define custom actions here
|
||||
*/
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
<?php
|
||||
namespace topic;
|
||||
|
||||
/**
|
||||
* Inherited Methods
|
||||
* @method void wantToTest($text)
|
||||
* @method void wantTo($text)
|
||||
* @method void execute($callable)
|
||||
* @method void expectTo($prediction)
|
||||
* @method void expect($prediction)
|
||||
* @method void amGoingTo($argumentation)
|
||||
* @method void am($role)
|
||||
* @method void lookForwardTo($achieveValue)
|
||||
* @method void comment($description)
|
||||
* @method \Codeception\Lib\Friend haveFriend($name, $actorClass = null)
|
||||
*
|
||||
* @SuppressWarnings(PHPMD)
|
||||
*/
|
||||
class FunctionalTester extends \FunctionalTester
|
||||
{
|
||||
use _generated\FunctionalTesterActions;
|
||||
|
||||
/**
|
||||
* Define custom actions here
|
||||
*/
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
<?php
|
||||
namespace topic;
|
||||
|
||||
/**
|
||||
* Inherited Methods
|
||||
* @method void wantToTest($text)
|
||||
* @method void wantTo($text)
|
||||
* @method void execute($callable)
|
||||
* @method void expectTo($prediction)
|
||||
* @method void expect($prediction)
|
||||
* @method void amGoingTo($argumentation)
|
||||
* @method void am($role)
|
||||
* @method void lookForwardTo($achieveValue)
|
||||
* @method void comment($description)
|
||||
* @method \Codeception\Lib\Friend haveFriend($name, $actorClass = null)
|
||||
*
|
||||
* @SuppressWarnings(PHPMD)
|
||||
*/
|
||||
class UnitTester extends \UnitTester
|
||||
{
|
||||
use _generated\UnitTesterActions;
|
||||
|
||||
/**
|
||||
* Define custom actions here
|
||||
*/
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
# Codeception Test Suite Configuration
|
||||
|
||||
# suite for acceptance tests.
|
||||
# perform tests in browser using the Selenium-like tools.
|
||||
# powered by Mink (http://mink.behat.org).
|
||||
# (tip: that's what your customer will see).
|
||||
# (tip: test your ajax and javascript by one of Mink drivers).
|
||||
|
||||
# RUN `build` COMMAND AFTER ADDING/REMOVING MODULES.
|
||||
|
||||
class_name: AcceptanceTester
|
||||
modules:
|
||||
enabled:
|
||||
- WebDriver
|
||||
- tests\codeception\_support\WebHelper
|
||||
- tests\codeception\_support\DynamicFixtureHelper
|
||||
config:
|
||||
WebDriver:
|
||||
url: 'http://localhost:8080/'
|
||||
browser: chrome
|
||||
window_size: maximize
|
||||
port: 4444
|
@ -0,0 +1,6 @@
|
||||
<?php
|
||||
/**
|
||||
* Initialize the HumHub Application for functional testing. The default application configuration for this suite can be overwritten
|
||||
* in @tests/config/functional.php
|
||||
*/
|
||||
require(Yii::getAlias('@humhubTests/codeception/acceptance/_bootstrap.php'));
|
@ -0,0 +1,3 @@
|
||||
<?php
|
||||
|
||||
return \tests\codeception\_support\HumHubTestConfiguration::getSuiteConfig('functional');
|
@ -0,0 +1,3 @@
|
||||
<?php
|
||||
|
||||
return \tests\codeception\_support\HumHubTestConfiguration::getSuiteConfig('unit');
|
@ -0,0 +1,18 @@
|
||||
# Codeception Test Suite Configuration
|
||||
|
||||
# suite for functional (integration) tests.
|
||||
# emulate web requests and make application process them.
|
||||
# (tip: better to use with frameworks).
|
||||
|
||||
# RUN `build` COMMAND AFTER ADDING/REMOVING MODULES.
|
||||
class_name: FunctionalTester
|
||||
modules:
|
||||
enabled:
|
||||
- Filesystem
|
||||
- Yii2
|
||||
- tests\codeception\_support\TestHelper
|
||||
- tests\codeception\_support\DynamicFixtureHelper
|
||||
- tests\codeception\_support\HumHubHelper
|
||||
config:
|
||||
Yii2:
|
||||
configFile: 'codeception/config/functional.php'
|
@ -0,0 +1,6 @@
|
||||
<?php
|
||||
/**
|
||||
* Initialize the HumHub Application for functional testing. The default application configuration for this suite can be overwritten
|
||||
* in @tests/config/functional.php
|
||||
*/
|
||||
require(Yii::getAlias('@humhubTests/codeception/functional/_bootstrap.php'));
|
@ -0,0 +1,14 @@
|
||||
# Codeception Test Suite Configuration
|
||||
|
||||
# suite for unit (internal) tests.
|
||||
# RUN `build` COMMAND AFTER ADDING/REMOVING MODULES.
|
||||
|
||||
class_name: UnitTester
|
||||
modules:
|
||||
enabled:
|
||||
- tests\codeception\_support\CodeHelper
|
||||
- Yii2
|
||||
config:
|
||||
Yii2:
|
||||
configFile: 'codeception/config/unit.php'
|
||||
transaction: false
|
@ -0,0 +1,68 @@
|
||||
<?php
|
||||
|
||||
namespace tests\codeception\unit;
|
||||
|
||||
use humhub\modules\post\models\Post;
|
||||
use humhub\modules\space\models\Space;
|
||||
use humhub\modules\topic\models\Topic;
|
||||
use humhub\modules\topic\widgets\TopicPicker;
|
||||
use tests\codeception\_support\HumHubDbTestCase;
|
||||
|
||||
class TopicPickerTest extends HumHubDbTestCase
|
||||
{
|
||||
/**
|
||||
* Make sure users with create topic permission sees topic picker
|
||||
*/
|
||||
public function testUserWithCreateTopicPermissionSeesTopicPickerWithSpaceTopics()
|
||||
{
|
||||
// User2 is moderator in Space3
|
||||
$space = Space::findOne(3);
|
||||
$this->becomeUser('User2');
|
||||
|
||||
$topic = new Topic($space);
|
||||
$topic->name = 'TestTopic';
|
||||
$this->assertTrue($topic->save());
|
||||
|
||||
$this->assertTrue(TopicPicker::showTopicPicker($space));
|
||||
}
|
||||
|
||||
/**
|
||||
* Make sure users with create topic permission sees topic picker even if there are no topics available
|
||||
*/
|
||||
public function testUserWithCreateTopicPermissionSeesTopicPickerWithoutSpaceTopics()
|
||||
{
|
||||
// User2 is moderator in Space3
|
||||
$space = Space::findOne(3);
|
||||
$this->becomeUser('User2');
|
||||
$this->assertTrue(TopicPicker::showTopicPicker($space));
|
||||
}
|
||||
|
||||
/**
|
||||
* Make sure users without create topic permission sees topic picker if topics are available
|
||||
*/
|
||||
public function testUserWithoutCreateTopicPermissionSeesTopicPickerWithSpaceTopics()
|
||||
{
|
||||
// User1 is member in Space3
|
||||
$space = Space::findOne(3);
|
||||
$this->becomeUser('User1');
|
||||
|
||||
$topic = new Topic($space);
|
||||
$topic->name = 'TestTopic';
|
||||
$this->assertTrue($topic->save());
|
||||
|
||||
$this->assertTrue(TopicPicker::showTopicPicker($space));
|
||||
}
|
||||
|
||||
/**
|
||||
* Make sure users without create topic permission does not sees topic picker if there are no topics available
|
||||
*/
|
||||
public function testUserWithoutCreateTopicPermissionDoesNotSeesTopicPickerWithoutSpaceTopics()
|
||||
{
|
||||
// User1 is member in Space3
|
||||
$space = Space::findOne(3);
|
||||
$this->becomeUser('User1');
|
||||
$this->assertFalse(TopicPicker::showTopicPicker($space));
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,119 @@
|
||||
<?php
|
||||
|
||||
namespace tests\codeception\unit;
|
||||
|
||||
use humhub\modules\post\models\Post;
|
||||
use humhub\modules\space\models\Space;
|
||||
use humhub\modules\topic\models\Topic;
|
||||
use tests\codeception\_support\HumHubDbTestCase;
|
||||
|
||||
class TopicTest extends HumHubDbTestCase
|
||||
{
|
||||
|
||||
/**
|
||||
* Make sure space admin is allowed to create content by default
|
||||
* @throws \yii\base\Exception
|
||||
*/
|
||||
public function testSpaceAdminCanCreateTopic()
|
||||
{
|
||||
// User2 is moderator in Space3
|
||||
$space = Space::findOne(3);
|
||||
$this->becomeUser('Admin');
|
||||
|
||||
$post = new Post($space, ['message' => 'Test Post']);
|
||||
$this->assertTrue($post->save());
|
||||
|
||||
Topic::attach($post->content, ['_add:NewTopic']);
|
||||
|
||||
$topics = Topic::findByContent($post->content)->all();
|
||||
$this->assertCount(1, $topics);
|
||||
$this->assertEquals('NewTopic', $topics[0]->name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Make sure moderator is allowed to create content by default
|
||||
* @throws \yii\base\Exception
|
||||
*/
|
||||
public function testSpaceModeratorCanCreateTopic()
|
||||
{
|
||||
// User2 is moderator in Space3
|
||||
$space = Space::findOne(3);
|
||||
$this->becomeUser('User2');
|
||||
|
||||
$post = new Post($space, ['message' => 'Test Post']);
|
||||
$this->assertTrue($post->save());
|
||||
|
||||
Topic::attach($post->content, ['_add:NewTopic']);
|
||||
|
||||
$topics = Topic::findByContent($post->content)->all();
|
||||
$this->assertCount(1, $topics);
|
||||
$this->assertEquals('NewTopic', $topics[0]->name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Make sure user is not allowed to create content by default
|
||||
* @throws \yii\base\Exception
|
||||
*/
|
||||
public function testSpaceMemberCanNotCreateTopic()
|
||||
{
|
||||
// User1 is member in Space3
|
||||
$space = Space::findOne(3);
|
||||
$this->becomeUser('User1');
|
||||
|
||||
$post = new Post($space, ['message' => 'Test Post']);
|
||||
$this->assertTrue($post->save());
|
||||
|
||||
Topic::attach($post->content, ['_add:NewTopic']);
|
||||
|
||||
$topics = Topic::findByContent($post->content)->all();
|
||||
$this->assertEmpty($topics);
|
||||
}
|
||||
|
||||
/**
|
||||
* Make sure user is not allowed to create content by default
|
||||
* @throws \yii\base\Exception
|
||||
*/
|
||||
public function testAttachTopicByInstance()
|
||||
{
|
||||
// User2 is moderator in Space3
|
||||
$space = Space::findOne(3);
|
||||
$this->becomeUser('User2');
|
||||
|
||||
$post = new Post($space, ['message' => 'Test Post']);
|
||||
$this->assertTrue($post->save());
|
||||
|
||||
$topic = new Topic($space);
|
||||
$topic->name = 'NewTopic';
|
||||
$this->assertTrue($topic->save());
|
||||
|
||||
Topic::attach($post->content, [$topic]);
|
||||
|
||||
$topics = Topic::findByContent($post->content)->all();
|
||||
$this->assertCount(1, $topics);
|
||||
$this->assertEquals('NewTopic', $topics[0]->name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Make sure user is not allowed to create content by default
|
||||
* @throws \yii\base\Exception
|
||||
*/
|
||||
public function testAttachTopicById()
|
||||
{
|
||||
// User2 is moderator in Space3
|
||||
$space = Space::findOne(3);
|
||||
$this->becomeUser('User2');
|
||||
|
||||
$post = new Post($space, ['message' => 'Test Post']);
|
||||
$this->assertTrue($post->save());
|
||||
|
||||
$topic = new Topic($space);
|
||||
$topic->name = 'NewTopic';
|
||||
$this->assertTrue($topic->save());
|
||||
|
||||
Topic::attach($post->content, [$topic->id]);
|
||||
|
||||
$topics = Topic::findByContent($post->content)->all();
|
||||
$this->assertCount(1, $topics);
|
||||
$this->assertEquals('NewTopic', $topics[0]->name);
|
||||
}
|
||||
}
|
@ -0,0 +1,6 @@
|
||||
<?php
|
||||
/**
|
||||
* Initialize the HumHub Application for functional testing. The default application configuration for this suite can be overwritten
|
||||
* in @tests/config/functional.php
|
||||
*/
|
||||
require(Yii::getAlias('@humhubTests/codeception/unit/_bootstrap.php'));
|
5
protected/humhub/modules/topic/tests/config/common.php
Normal file
5
protected/humhub/modules/topic/tests/config/common.php
Normal file
@ -0,0 +1,5 @@
|
||||
<?php
|
||||
/**
|
||||
* This config is shared by all suites (unit/functional/acceptance) and can be overwritten by a suite config (e.g. functional.php)
|
||||
*/
|
||||
return [];
|
@ -0,0 +1,5 @@
|
||||
<?php
|
||||
/**
|
||||
* Here you can overwrite the default config for the functional suite. The default config resides in @humhubTests/codeception/config/config.php
|
||||
*/
|
||||
return [];
|
5
protected/humhub/modules/topic/tests/config/test.php
Normal file
5
protected/humhub/modules/topic/tests/config/test.php
Normal file
@ -0,0 +1,5 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
'fixtures' => ['default']
|
||||
];
|
5
protected/humhub/modules/topic/tests/config/unit.php
Normal file
5
protected/humhub/modules/topic/tests/config/unit.php
Normal file
@ -0,0 +1,5 @@
|
||||
<?php
|
||||
/**
|
||||
* Here you can overwrite your functional humhub config. The default config resiedes in @humhubTests/codeception/config/config.php
|
||||
*/
|
||||
return [];
|
@ -8,6 +8,7 @@
|
||||
|
||||
namespace humhub\modules\topic\widgets;
|
||||
|
||||
use humhub\modules\content\components\ContentContainerActiveRecord;
|
||||
use humhub\modules\content\helpers\ContentContainerHelper;
|
||||
use humhub\modules\topic\permissions\AddTopic;
|
||||
use humhub\modules\content\widgets\ContentTagPicker;
|
||||
@ -15,6 +16,10 @@ use humhub\modules\topic\models\Topic;
|
||||
use Yii;
|
||||
use yii\helpers\Url;
|
||||
|
||||
/**
|
||||
* This InputWidget class can be used to add a topic picker input field. The topic picker field is only
|
||||
* rendered if there are topics available or if the user is allowed to create topics.
|
||||
*/
|
||||
class TopicPicker extends ContentTagPicker
|
||||
{
|
||||
/**
|
||||
@ -37,7 +42,7 @@ class TopicPicker extends ContentTagPicker
|
||||
*/
|
||||
public function init()
|
||||
{
|
||||
$this->contentContainer = $this->contentContainer ? $this->contentContainer : ContentContainerHelper::getCurrent();
|
||||
$this->contentContainer = $this->contentContainer ?: ContentContainerHelper::getCurrent();
|
||||
|
||||
if (!$this->url && $this->contentContainer) {
|
||||
$this->url = $this->contentContainer->createUrl('/topic/topic/search');
|
||||
@ -45,16 +50,71 @@ class TopicPicker extends ContentTagPicker
|
||||
$this->url = Url::to(['/topic/topic/search']);
|
||||
}
|
||||
|
||||
$this->addOptions = $this->contentContainer && $this->contentContainer->can(AddTopic::class);
|
||||
$this->addOptions = static::canAddTopic($this->contentContainer);
|
||||
|
||||
parent::init();
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
if(!static::canAddTopic($this->contentContainer) && !static::hasTopics($this->contentContainer)) {
|
||||
return $this->emptyResult();
|
||||
}
|
||||
|
||||
return parent::run();
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if a topicpicker should be rendered for the current user. This is only the case if there are topics
|
||||
* available for the given container or the user is allowed to create topics.
|
||||
*
|
||||
* @param ContentContainerActiveRecord|null $container
|
||||
* @return bool
|
||||
*/
|
||||
public static function showTopicPicker(ContentContainerActiveRecord $container = null)
|
||||
{
|
||||
return static::canAddTopic($container) || static::hasTopics($container);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if the current user is allowed to add topics on this container.
|
||||
*
|
||||
* @return bool
|
||||
* @since 1.6
|
||||
*/
|
||||
private static function canAddTopic(ContentContainerActiveRecord $container = null)
|
||||
{
|
||||
return $container && $container->can(AddTopic::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if there are topics available on this container.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private static function hasTopics(ContentContainerActiveRecord $container = null)
|
||||
{
|
||||
if(!$container) {
|
||||
return (bool) Topic::find()->count();
|
||||
}
|
||||
|
||||
return (bool) Topic::findByContainer($container)->count();
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getItemImage($item)
|
||||
{
|
||||
return Yii::$app->getModule('topic')->icon;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
protected function getData()
|
||||
{
|
||||
$result = parent::getData();
|
||||
|
@ -17,6 +17,13 @@ namespace humhub\modules\ui\form\widgets;
|
||||
*/
|
||||
class ActiveField extends \yii\bootstrap\ActiveField
|
||||
{
|
||||
/**
|
||||
* @var bool Can be set to true in order to prevent this field from being rendered. This may be used by InputWidgets
|
||||
* or other fields responsible for custom visibility management.
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
public $preventRendering = false;
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
@ -28,11 +35,50 @@ class ActiveField extends \yii\bootstrap\ActiveField
|
||||
$config['attribute'] = $this->attribute;
|
||||
$config['view'] = $this->form->getView();
|
||||
|
||||
if (isset($config['options']) && isset(class_parents($class)['humhub\widgets\InputWidget'])) {
|
||||
$this->adjustLabelFor($config['options']);
|
||||
if(is_subclass_of($class, JsInputWidget::class)) {
|
||||
if(isset($config['options'])) {
|
||||
$this->adjustLabelFor($config['options']);
|
||||
}
|
||||
|
||||
$config['field'] = $this;
|
||||
}
|
||||
|
||||
return parent::widget($class, $config);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function begin()
|
||||
{
|
||||
if($this->preventRendering) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return parent::begin();
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function render($content = null)
|
||||
{
|
||||
if($this->preventRendering) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return parent::render($content);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function end()
|
||||
{
|
||||
if($this->preventRendering) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return parent::end();
|
||||
}
|
||||
}
|
||||
|
@ -26,7 +26,7 @@ class ActiveForm extends \yii\bootstrap\ActiveForm
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public $fieldClass = 'humhub\modules\ui\form\widgets\ActiveField';
|
||||
public $fieldClass = ActiveField::class;
|
||||
|
||||
public $acknowledge = false;
|
||||
|
||||
|
@ -45,7 +45,7 @@ class ColorPicker extends JsInputWidget
|
||||
*/
|
||||
public function init()
|
||||
{
|
||||
if (!empty($this->field)) {
|
||||
if (!empty($this->field) && is_array($this->field)) {
|
||||
$this->attribute = $this->field;
|
||||
}
|
||||
|
||||
|
@ -72,6 +72,13 @@ abstract class JsInputWidget extends JsWidget
|
||||
*/
|
||||
public $options = [];
|
||||
|
||||
/**
|
||||
* @var \yii\widgets\ActiveField active input field, which triggers this widget rendering.
|
||||
* This field will be automatically filled up in case widget instance is created via [[\yii\widgets\ActiveField::widget()]].
|
||||
* @since 1.6
|
||||
*/
|
||||
public $field;
|
||||
|
||||
/**
|
||||
* Initializes the widget.
|
||||
* If you override this method, make sure you call the parent implementation first.
|
||||
@ -87,9 +94,43 @@ abstract class JsInputWidget extends JsWidget
|
||||
if (!$this->id && !isset($this->options['id'])) {
|
||||
$this->id = $this->options['id'] = $this->hasModel() ? Html::getInputId($this->model, $this->attribute) : $this->getId(true);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Should be returned by [[run]] in order to prevent rendering the field.
|
||||
* This function will prepare the ActiveField instance by resetting the template and label and return
|
||||
* an empty string.
|
||||
*
|
||||
* ```php
|
||||
* public function run()
|
||||
* {
|
||||
* if(!$this->shouldRender()) {
|
||||
* return $this->emptyResult();
|
||||
* }
|
||||
*
|
||||
* return parent::run();
|
||||
* }
|
||||
* ```
|
||||
* @return string
|
||||
* @since 1.6
|
||||
*/
|
||||
protected function emptyResult()
|
||||
{
|
||||
if($this->field) {
|
||||
$this->field->label(false);
|
||||
// Prevents empty-help/error block rendering
|
||||
$this->field->template = '';
|
||||
|
||||
if($this->field instanceof ActiveField) {
|
||||
$this->field->preventRendering = true;
|
||||
}
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string the field value either by extracting from model or if no model is given `$this->value`
|
||||
* @since 1.3
|
||||
|
Loading…
x
Reference in New Issue
Block a user