mirror of
https://github.com/flarum/framework.git
synced 2024-11-22 12:48:28 +08:00
feat: conditional extenders (#3759)
This commit is contained in:
parent
a6a067ad48
commit
8372363cc2
61
framework/core/src/Extend/Conditional.php
Normal file
61
framework/core/src/Extend/Conditional.php
Normal file
|
@ -0,0 +1,61 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Flarum.
|
||||
*
|
||||
* For detailed copyright and license information, please view the
|
||||
* LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Flarum\Extend;
|
||||
|
||||
use Flarum\Extension\Extension;
|
||||
use Flarum\Extension\ExtensionManager;
|
||||
use Illuminate\Contracts\Container\Container;
|
||||
|
||||
class Conditional implements ExtenderInterface
|
||||
{
|
||||
/**
|
||||
* @var array<array{condition: bool|callable, extenders: ExtenderInterface[]}>
|
||||
*/
|
||||
protected $conditions = [];
|
||||
|
||||
/**
|
||||
* @param ExtenderInterface[] $extenders
|
||||
*/
|
||||
public function whenExtensionEnabled(string $extensionId, array $extenders): self
|
||||
{
|
||||
return $this->when(function (ExtensionManager $extensions) use ($extensionId) {
|
||||
return $extensions->isEnabled($extensionId);
|
||||
}, $extenders);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool|callable $condition
|
||||
* @param ExtenderInterface[] $extenders
|
||||
*/
|
||||
public function when($condition, array $extenders): self
|
||||
{
|
||||
$this->conditions[] = [
|
||||
'condition' => $condition,
|
||||
'extenders' => $extenders,
|
||||
];
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function extend(Container $container, Extension $extension = null)
|
||||
{
|
||||
foreach ($this->conditions as $condition) {
|
||||
if (is_callable($condition['condition'])) {
|
||||
$condition['condition'] = $container->call($condition['condition']);
|
||||
}
|
||||
|
||||
if ($condition['condition']) {
|
||||
foreach ($condition['extenders'] as $extender) {
|
||||
$extender->extend($container, $extension);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -414,19 +414,19 @@ class Extension implements Arrayable
|
|||
$links['source'] = $sourceUrl;
|
||||
}
|
||||
|
||||
if (($discussUrl = $this->composerJsonAttribute('support.forum'))) {
|
||||
if ($discussUrl = $this->composerJsonAttribute('support.forum')) {
|
||||
$links['discuss'] = $discussUrl;
|
||||
}
|
||||
|
||||
if (($documentationUrl = $this->composerJsonAttribute('support.docs'))) {
|
||||
if ($documentationUrl = $this->composerJsonAttribute('support.docs')) {
|
||||
$links['documentation'] = $documentationUrl;
|
||||
}
|
||||
|
||||
if (($websiteUrl = $this->composerJsonAttribute('homepage'))) {
|
||||
if ($websiteUrl = $this->composerJsonAttribute('homepage')) {
|
||||
$links['website'] = $websiteUrl;
|
||||
}
|
||||
|
||||
if (($supportEmail = $this->composerJsonAttribute('support.email'))) {
|
||||
if ($supportEmail = $this->composerJsonAttribute('support.email')) {
|
||||
$links['support'] = "mailto:$supportEmail";
|
||||
}
|
||||
|
||||
|
|
|
@ -65,7 +65,7 @@ class Gate
|
|||
$appliedPolicies = [];
|
||||
|
||||
if ($model) {
|
||||
$modelClasses = is_string($model) ? [$model] : array_merge(class_parents(($model)), [get_class($model)]);
|
||||
$modelClasses = is_string($model) ? [$model] : array_merge(class_parents($model), [get_class($model)]);
|
||||
|
||||
foreach ($modelClasses as $class) {
|
||||
$appliedPolicies = array_merge($appliedPolicies, $this->getPolicies($class));
|
||||
|
@ -87,7 +87,7 @@ class Gate
|
|||
// If no policy covered this permission query, we will only grant
|
||||
// the permission if the actor's groups have it. Otherwise, we will
|
||||
// not allow the user to perform this action.
|
||||
if ($actor->isAdmin() || ($actor->hasPermission($ability))) {
|
||||
if ($actor->isAdmin() || $actor->hasPermission($ability)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
162
framework/core/tests/integration/extenders/ConditionalTest.php
Normal file
162
framework/core/tests/integration/extenders/ConditionalTest.php
Normal file
|
@ -0,0 +1,162 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Flarum.
|
||||
*
|
||||
* For detailed copyright and license information, please view the
|
||||
* LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Flarum\Tests\integration\extenders;
|
||||
|
||||
use Exception;
|
||||
use Flarum\Api\Serializer\ForumSerializer;
|
||||
use Flarum\Extend;
|
||||
use Flarum\Extension\ExtensionManager;
|
||||
use Flarum\Testing\integration\RetrievesAuthorizedUsers;
|
||||
use Flarum\Testing\integration\TestCase;
|
||||
|
||||
class ConditionalTest extends TestCase
|
||||
{
|
||||
use RetrievesAuthorizedUsers;
|
||||
|
||||
/** @test */
|
||||
public function conditional_works_if_condition_is_primitive_true()
|
||||
{
|
||||
$this->extend(
|
||||
(new Extend\Conditional())
|
||||
->when(true, [
|
||||
(new Extend\ApiSerializer(ForumSerializer::class))
|
||||
->attributes(function () {
|
||||
return [
|
||||
'customConditionalAttribute' => true
|
||||
];
|
||||
})
|
||||
])
|
||||
);
|
||||
|
||||
$this->app();
|
||||
|
||||
$response = $this->send(
|
||||
$this->request('GET', '/api', [
|
||||
'authenticatedAs' => 1,
|
||||
])
|
||||
);
|
||||
|
||||
$payload = json_decode($response->getBody()->getContents(), true);
|
||||
|
||||
$this->assertArrayHasKey('customConditionalAttribute', $payload['data']['attributes']);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function conditional_does_not_work_if_condition_is_primitive_false()
|
||||
{
|
||||
$this->extend(
|
||||
(new Extend\Conditional())
|
||||
->when(false, [
|
||||
(new Extend\ApiSerializer(ForumSerializer::class))
|
||||
->attributes(function () {
|
||||
return [
|
||||
'customConditionalAttribute' => true
|
||||
];
|
||||
})
|
||||
])
|
||||
);
|
||||
|
||||
$this->app();
|
||||
|
||||
$response = $this->send(
|
||||
$this->request('GET', '/api', [
|
||||
'authenticatedAs' => 1,
|
||||
])
|
||||
);
|
||||
|
||||
$payload = json_decode($response->getBody()->getContents(), true);
|
||||
|
||||
$this->assertArrayNotHasKey('customConditionalAttribute', $payload['data']['attributes']);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function conditional_works_if_condition_is_callable_true()
|
||||
{
|
||||
$this->extend(
|
||||
(new Extend\Conditional())
|
||||
->when(function () {
|
||||
return true;
|
||||
}, [
|
||||
(new Extend\ApiSerializer(ForumSerializer::class))
|
||||
->attributes(function () {
|
||||
return [
|
||||
'customConditionalAttribute' => true
|
||||
];
|
||||
})
|
||||
])
|
||||
);
|
||||
|
||||
$this->app();
|
||||
|
||||
$response = $this->send(
|
||||
$this->request('GET', '/api', [
|
||||
'authenticatedAs' => 1,
|
||||
])
|
||||
);
|
||||
|
||||
$payload = json_decode($response->getBody()->getContents(), true);
|
||||
|
||||
$this->assertArrayHasKey('customConditionalAttribute', $payload['data']['attributes']);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function conditional_does_not_work_if_condition_is_callable_false()
|
||||
{
|
||||
$this->extend(
|
||||
(new Extend\Conditional())
|
||||
->when(function () {
|
||||
return false;
|
||||
}, [
|
||||
(new Extend\ApiSerializer(ForumSerializer::class))
|
||||
->attributes(function () {
|
||||
return [
|
||||
'customConditionalAttribute' => true
|
||||
];
|
||||
})
|
||||
])
|
||||
);
|
||||
|
||||
$this->app();
|
||||
|
||||
$response = $this->send(
|
||||
$this->request('GET', '/api', [
|
||||
'authenticatedAs' => 1,
|
||||
])
|
||||
);
|
||||
|
||||
$payload = json_decode($response->getBody()->getContents(), true);
|
||||
|
||||
$this->assertArrayNotHasKey('customConditionalAttribute', $payload['data']['attributes']);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function conditional_injects_dependencies_to_condition_callable()
|
||||
{
|
||||
$this->expectNotToPerformAssertions();
|
||||
|
||||
$this->extend(
|
||||
(new Extend\Conditional())
|
||||
->when(function (?ExtensionManager $extensions) {
|
||||
if (! $extensions) {
|
||||
throw new Exception('ExtensionManager not injected');
|
||||
}
|
||||
}, [
|
||||
(new Extend\ApiSerializer(ForumSerializer::class))
|
||||
->attributes(function () {
|
||||
return [
|
||||
'customConditionalAttribute' => true
|
||||
];
|
||||
})
|
||||
])
|
||||
);
|
||||
|
||||
$this->app();
|
||||
}
|
||||
}
|
|
@ -42,7 +42,7 @@ class LocalesTest extends TestCase
|
|||
public function custom_translation_exists_if_added()
|
||||
{
|
||||
$this->extend(
|
||||
(new Extend\Locales(dirname(__FILE__, 3).'/fixtures/locales'))
|
||||
new Extend\Locales(dirname(__FILE__, 3).'/fixtures/locales')
|
||||
);
|
||||
|
||||
$this->app()->getContainer()->make('flarum.locales');
|
||||
|
@ -57,7 +57,7 @@ class LocalesTest extends TestCase
|
|||
public function custom_translation_exists_if_added_with_intl_suffix()
|
||||
{
|
||||
$this->extend(
|
||||
(new Extend\Locales(dirname(__FILE__, 3).'/fixtures/locales'))
|
||||
new Extend\Locales(dirname(__FILE__, 3).'/fixtures/locales')
|
||||
);
|
||||
|
||||
$this->app()->getContainer()->make('flarum.locales');
|
||||
|
@ -72,7 +72,7 @@ class LocalesTest extends TestCase
|
|||
public function messageformat_works_in_translations()
|
||||
{
|
||||
$this->extend(
|
||||
(new Extend\Locales(dirname(__FILE__, 3).'/fixtures/locales'))
|
||||
new Extend\Locales(dirname(__FILE__, 3).'/fixtures/locales')
|
||||
);
|
||||
|
||||
$this->app()->getContainer()->make('flarum.locales');
|
||||
|
@ -87,7 +87,7 @@ class LocalesTest extends TestCase
|
|||
public function laravel_interface_methods_work()
|
||||
{
|
||||
$this->extend(
|
||||
(new Extend\Locales(dirname(__FILE__, 3).'/fixtures/locales'))
|
||||
new Extend\Locales(dirname(__FILE__, 3).'/fixtures/locales')
|
||||
);
|
||||
|
||||
$this->app()->getContainer()->make('flarum.locales');
|
||||
|
|
Loading…
Reference in New Issue
Block a user