Skip to content

Commit

Permalink
Add global order config
Browse files Browse the repository at this point in the history
  • Loading branch information
Tofandel committed Mar 4, 2024
1 parent 64f68a2 commit 4c04072
Show file tree
Hide file tree
Showing 8 changed files with 82 additions and 49 deletions.
7 changes: 7 additions & 0 deletions config/block_editor.php
Original file line number Diff line number Diff line change
Expand Up @@ -95,4 +95,11 @@
'repeaters' => resource_path('views/twill/repeaters'),
],
],
'blocks' => [],
'block_rules' => [
// List of block identifiers to globally disallow
'disable' => [],
// List of block identifiers to order blocks by if no order is provided
'order' => [],
]
];
3 changes: 2 additions & 1 deletion src/Facades/TwillBlocks.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,12 @@
/**
* @method static void globallyExcludeBlocks(array|callable $blocks)
* @method static array getGloballyExcludedBlocks
* @method static void setGloballyExcludedBlocks(array $exclude = [])
* @method static Collection<Block>getBlocks
* @method static Collection<Block>getSettingsBlocks
* @method static Collection<Block>getRepeaters
* @method static registerManualBlock(string $blockClass, string $source = Block::SOURCE_APP)
* @method static Collection<Block>generateListOfAvailableBlocks(?array $blocks = null, ?array $groups = null, bool $settingsOnly = false, array|callable $excludeBlocks = [])
* @method static Collection<Block>generateListOfAvailableBlocks(?array $blocks = null, ?array $groups = null, bool $settingsOnly = false, array|callable $excludeBlocks = [], bool $defaultOrder = false)
*/
class TwillBlocks extends Facade
{
Expand Down
5 changes: 0 additions & 5 deletions src/Services/Blocks/Block.php
Original file line number Diff line number Diff line change
Expand Up @@ -206,11 +206,6 @@ public function newInstance(): static
);
}

public function getPosition(): float|int|string
{
return $this->componentClass && is_callable([$this->componentClass, 'getPosition']) ? $this->componentClass::getPosition() : 0;
}

/**
* Gets the first match being a block or repeater.
*/
Expand Down
9 changes: 9 additions & 0 deletions src/Services/Forms/Fields/BlockEditor.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ class BlockEditor extends BaseFormField
protected bool $isSettings = false;

protected bool $withoutSeparator = false;
protected bool $usingDefaultOrder = false;

public static function make(): static
{
Expand Down Expand Up @@ -58,6 +59,14 @@ public function blocks(array $blocks): static
return $this;
}


public function usingDefaultOrder(bool $usingDefaultOrder = true): static
{
$this->usingDefaultOrder = $usingDefaultOrder;

return $this;
}

public function getBlocks(): array
{
return $this->blocks;
Expand Down
44 changes: 34 additions & 10 deletions src/TwillBlocks.php
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,11 @@ public function globallyExcludeBlocks(array|callable $blocks): void
$this->globallyExcludedBlocks[] = $blocks;
}

public function setGloballyExcludedBlocks(array $exclude = []): void
{
$this->globallyExcludedBlocks = [];
}

public function getGloballyExcludedBlocks(): array
{
return $this->globallyExcludedBlocks;
Expand Down Expand Up @@ -342,7 +347,7 @@ public function getAllCropConfigs(): array
return $this->cropConfigs;
}

public function generateListOfAllBlocks(bool $settingsOnly = false)
public function generateListOfAllBlocks(bool $settingsOnly = false): Collection
{
return once(function () use ($settingsOnly) {
/** @var Collection $blockList */
Expand All @@ -352,11 +357,14 @@ public function generateListOfAllBlocks(bool $settingsOnly = false)
$blockList = TwillBlocks::getBlocks();
}

$customOrder = array_flip(config('twill.block_editor.block_rules.order', []));
$disabledBlocks = array_flip(config('twill.block_editor.block_rules.disable', []));

$appBlocksList = $blockList->filter(function (Block $block) {
return $block->source !== Block::SOURCE_TWILL;
});

return $blockList->filter(function (Block $block) use ($appBlocksList) {
return $blockList->filter(function (Block $block) use ($disabledBlocks, $appBlocksList) {
if ($block->group === Block::SOURCE_TWILL) {
if (!collect(config('twill.block_editor.use_twill_blocks'))->contains($block->name)) {
return false;
Expand All @@ -372,16 +380,21 @@ function ($appBlock) use ($block) {
return false;
}
}
return true;
})->sortBy(function (Block $b) {
// Blocks are by default sorted by the order they have been found in directories, but we can allow individual blocks to override this behavior
return $b->getPosition();
})->values();
return isset($disabledBlocks[$block->name]) || isset($disabledBlocks[ltrim($block->componentClass, '\\')]);
})->sortBy(function (Block $b) use ($customOrder) {
// Sort blocks by custom order then by group and then by name
return ($customOrder[$b->name] ?? $customOrder[ltrim($b->componentClass, '\\')] ?? PHP_INT_MAX) . '-' . $b->group . '-' . $b->name;
}, SORT_NATURAL)->values();
});
}

public function generateListOfAvailableBlocks(?array $blocks = null, ?array $groups = null, bool $settingsOnly = false, array|callable $excludeBlocks = []): Collection
{
public function generateListOfAvailableBlocks(
?array $blocks = null,
?array $groups = null,
bool $settingsOnly = false,
array|callable $excludeBlocks = [],
bool $defaultOrder = false
): Collection {
$globalExcludeBlocks = TwillBlocks::getGloballyExcludedBlocks();

$matchBlock = function ($matcher, $block, $someFn = null) {
Expand All @@ -393,7 +406,7 @@ public function generateListOfAvailableBlocks(?array $blocks = null, ?array $gro
}
return null;
};
return $this->generateListOfAllBlocks($settingsOnly)->filter(
$finalList = $this->generateListOfAllBlocks($settingsOnly)->filter(
function (Block $block) use ($blocks, $groups, $excludeBlocks, $globalExcludeBlocks, $matchBlock) {
if ($matchBlock($excludeBlocks, $block)) {
return false;
Expand All @@ -420,5 +433,16 @@ function (Block $block) use ($blocks, $groups, $excludeBlocks, $globalExcludeBlo
return true;
}
);
if (! $defaultOrder) {
if (! empty($blocks)) {
$blocks = array_flip($blocks);
$finalList = $finalList->sortBy(fn(Block $block) => $blocks[$block->name] ?? $blocks[ltrim($block->componentClass, '\\')] ?? PHP_INT_MAX, SORT_NUMERIC);
}
if (! empty($groups)) {
$groups = array_flip($groups);
$finalList = $finalList->sortBy(fn(Block $block) => $groups[$block->group] ?? PHP_INT_MAX, SORT_NUMERIC);
}
}
return $finalList;
}
}
5 changes: 0 additions & 5 deletions src/View/Components/Blocks/TwillBlockComponent.php
Original file line number Diff line number Diff line change
Expand Up @@ -112,11 +112,6 @@ public static function getBlockGroup(): string
return Str::slug(Str::before(static::class, '\\'));
}

public static function getPosition(): float|int|string
{
return 0;
}

public static function getBlockIcon(): string
{
return 'text';
Expand Down
2 changes: 2 additions & 0 deletions src/View/Components/Fields/BlockEditor.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ public function __construct(
public ?string $group = null,
public ?string $trigger = null,
public bool $isSettings = false,
public bool $usingDefaultOrder = false,
) {
parent::__construct(
name: $name,
Expand All @@ -46,6 +47,7 @@ public function getAllowedBlocks(): array
$groups,
$this->isSettings,
$this->excludeBlocks ?? null,
$this->usingDefaultOrder
)->pluck('name')->all();
}

Expand Down
56 changes: 28 additions & 28 deletions tests/unit/Helpers/BlockHelpersTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use A17\Twill\Services\Forms\Form;
use A17\Twill\Tests\Unit\TestCase;
use A17\Twill\View\Components\Blocks\TwillBlockComponent;
use Spatie\Once\Cache;

class GroupBlock extends TwillBlockComponent {
public static function getBlockGroup(): string
Expand Down Expand Up @@ -35,11 +36,6 @@ public static function getBlockName(): string
{
return 'block2';
}

public static function getPosition(): float|int|string
{
return 2;
}
}

class AppBlock extends GroupBlock
Expand All @@ -48,11 +44,6 @@ public static function getBlockGroup(): string
{
return 'app';
}

public static function getPosition(): float|int|string
{
return 1;
}
}
class BlockHelpersTest extends TestCase
{
Expand All @@ -66,36 +57,27 @@ public function testGenerateListOfAvailableBlocks()
$this->assertContains(GroupBlock::class, $blockClasses);
$this->assertContains(AppBlock::class, $blockClasses);

$available = TwillBlocks::generateListOfAvailableBlocks()->pluck('componentClass');

$this->assertGreaterThanOrEqual(3, count($available));
$available = TwillBlocks::generateListOfAvailableBlocks()->pluck('componentClass')->filter();
// Ensure correct order
$this->assertEquals([AppBlock::class, GroupBlock::class, GroupBlock2::class], $available->all());

Check failure on line 62 in tests/unit/Helpers/BlockHelpersTest.php

View workflow job for this annotation

GitHub Actions / PHP 8.3 - LARAVEL 9.*

Failed asserting that two arrays are equal.

Check failure on line 62 in tests/unit/Helpers/BlockHelpersTest.php

View workflow job for this annotation

GitHub Actions / PHP 8.3 - LARAVEL 10.*

Failed asserting that two arrays are equal.

Check failure on line 62 in tests/unit/Helpers/BlockHelpersTest.php

View workflow job for this annotation

GitHub Actions / PHP 8.2 - LARAVEL 9.*

Failed asserting that two arrays are equal.

Check failure on line 62 in tests/unit/Helpers/BlockHelpersTest.php

View workflow job for this annotation

GitHub Actions / PHP 8.2 - LARAVEL 10.*

Failed asserting that two arrays are equal.

Check failure on line 62 in tests/unit/Helpers/BlockHelpersTest.php

View workflow job for this annotation

GitHub Actions / PHP 8.1 - LARAVEL 9.*

Failed asserting that two arrays are equal.

Check failure on line 62 in tests/unit/Helpers/BlockHelpersTest.php

View workflow job for this annotation

GitHub Actions / PHP 8.1 - LARAVEL 10.*

Failed asserting that two arrays are equal.

Check failure on line 62 in tests/unit/Helpers/BlockHelpersTest.php

View workflow job for this annotation

GitHub Actions / PHP 8 - LARAVEL 9.*

Failed asserting that two arrays are equal.

$available = TwillBlocks::generateListOfAvailableBlocks([GroupBlock2::class, 'app-block'])->pluck('componentClass');
// Ensure correct order
$this->assertEquals([GroupBlock2::class, AppBlock::class], $available->all());

$this->assertEquals(GroupBlock2::class, $available->pop());
$this->assertEquals(AppBlock::class, $available->pop());
$available = TwillBlocks::generateListOfAvailableBlocks([GroupBlock2::class, AppBlock::class], ['group', 'app'])->pluck('componentClass');
$this->assertEquals([GroupBlock2::class, GroupBlock::class, AppBlock::class], $available->all());

$available = TwillBlocks::generateListOfAvailableBlocks(['app-block', GroupBlock2::class])->pluck('componentClass');
$this->assertCount(2, $available);
$this->assertContains(AppBlock::class, $available);
$this->assertContains(GroupBlock2::class, $available);

$available = TwillBlocks::generateListOfAvailableBlocks([GroupBlock2::class], ['group'])->pluck('componentClass');
$this->assertCount(2, $available);
$this->assertContains(GroupBlock::class, $available);

$available = TwillBlocks::generateListOfAvailableBlocks(['app-block', GroupBlock2::class], excludeBlocks: ['app-block'])->pluck('componentClass');

$this->assertCount(1, $available);
$this->assertContains(GroupBlock2::class, $available);
$this->assertEquals([GroupBlock2::class], $available->all());

$available = TwillBlocks::generateListOfAvailableBlocks(
[AppBlock::class, GroupBlock::class, GroupBlock2::class],
excludeBlocks: fn (Block $block) => $block->componentClass && $block->componentClass::getBlockName() == 'block'
)->pluck('componentClass');

$this->assertCount(1, $available);
$this->assertContains(GroupBlock2::class, $available);
$this->assertEquals([GroupBlock2::class], $available->all());

TwillBlocks::globallyExcludeBlocks([GroupBlock::class]);
TwillBlocks::globallyExcludeBlocks(fn (Block $block) => $block->name == 'group-block2');
Expand All @@ -105,6 +87,24 @@ public function testGenerateListOfAvailableBlocks()
)->pluck('componentClass');
$this->assertCount(1, $available);
$this->assertContains(AppBlock::class, $available);

TwillBlocks::setGloballyExcludedBlocks();

config(['twill.block_editor.block_rules.order' => ['group-block2', AppBlock::class, 'group-block']]);

Cache::getInstance()->flush();

$available = TwillBlocks::generateListOfAvailableBlocks()->pluck('componentClass')->filter();
// Ensure correct order
$this->assertEquals([GroupBlock2::class, AppBlock::class, GroupBlock::class], $available->all());

config(['twill.block_editor.block_rules.disable' => ['group-block2', AppBlock::class]]);

Cache::getInstance()->flush();

$available = TwillBlocks::generateListOfAvailableBlocks()->pluck('componentClass')->filter();
$this->assertEquals([GroupBlock::class], $available->all());

}

}

0 comments on commit 4c04072

Please sign in to comment.