Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add cookbook() method to Widget::class. #37

Merged
merged 3 commits into from
Mar 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
Change Log
==========

## 0.1.4 Under development
## 0.1.4 March 28, 2024

- Enh #37: Add `cookbook()` method to `Widget::class` (@terabytesoftw)

## 0.1.3 March 26, 2024

Expand Down
36 changes: 36 additions & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,42 @@ final class DefaultDefinition extends Element
}
```

## Cookbook

The `cookbook()` method is used to configure the widget with the provided default definitions.

```php
<?php

declare(strict_types=1);

namespace App\Widget;

use App\Definition\BootstrapAlertDismissible;

final class DefaultDefinition extends Element
{
private string $id = '';

public function getCookbooks(string $option): array
{
return [
'bootstrap-alert-dismmisible' => BootstrapAlertDismissible::definition($option),
];
}
}
```

```php
<?php

declare(strict_types=1);

use App\Widget\DefaultDefinition;

DefaultDefinition::widget()->cookbook('bootstrap-alert-dismmisible', 'success')->render();
```

## Creating

To create a widget, you need to extend the `PHPForge\Widget\AbstractWidget::class` and implement the `PHPForge\Widget\Widget::run()` protected method.
Expand Down
1 change: 0 additions & 1 deletion ecs.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@
)
->withPhpCsFixerSets(perCS20: true)
->withPreparedSets(
arrays: true,
cleanCode: true,
comments:true,
docblocks: true,
Expand Down
28 changes: 28 additions & 0 deletions src/Base/Widget.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,22 @@ final public function __toString(): string
return $this->run();
}

/**
* This method is used to configure the widget with the provided cookbook definitions.
*
* @param string $key The key to load the cookbook for.
* @param string $option The option to load the cookbook for.
*
* @return static The widget instance with the cookbook definitions applied.
*/
final public function cookbook(string $key, string $option): static
{
/** @psalm-var array<string, mixed> $cookbook */
$cookbook = $this->getCookbooks($option)[$key] ?? [];

return SimpleFactory::configure($this, $cookbook);
}

/**
* This method is a static factory method that creates an instance of the widget.
* It uses the ReflectionClass to create a new instance of the widget with the provided arguments.
Expand All @@ -57,6 +73,18 @@ final public static function widget(mixed ...$args): static
*/
abstract protected function run(): string;

/**
* This method is used to configure the widget with the provided cookbooks.
*
* @param string $option The option to load the cookbook for.
*
* @return array The cookbook for the widget configuration.
*/
protected function getCookbooks(string $option): array
{
return [];
}

/**
* This method is used to configure the widget with the provided default definitions.
*/
Expand Down
11 changes: 2 additions & 9 deletions src/Factory/SimpleFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -77,12 +77,7 @@ public static function create(string $class, array $args): Widget
*
* @return Widget The widget with the applied definitions.
*
* @psalm-template T of Widget
*
* @psalm-param T $widget The widget to configure.
* @psalm-param array<string, mixed> $definitions The definitions to apply to the widget.
*
* @psalm-return T The widget with the applied definitions.
* @psalm-param array<string, mixed> $definitions
*/
public static function configure(object $widget, array $definitions): widget
{
Expand All @@ -97,16 +92,14 @@ public static function configure(object $widget, array $definitions): widget
}

if ($definitions === []) {
/** @psalm-var T $widget */
return $widget;
}

foreach ($definitions as $action => $arguments) {
if (str_ends_with($action, '()')) {
$setter = call_user_func_array([$widget, substr($action, 0, -2)], $arguments);

if ($setter instanceof $widget) {
/** @psalm-var T $widget */
if ($setter instanceof Widget) {
$widget = $setter;
}
}
Expand Down
16 changes: 4 additions & 12 deletions tests/Factory/SimpleFactoryTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,7 @@ public function testConfigure(): void
{
$widget = SimpleFactory::configure(
Widget::widget(),
[
'id()' => ['id-configure'],
]
['id()' => ['id-configure']]
);

$this->assertSame('<id="id-configure">', $widget->render());
Expand Down Expand Up @@ -54,12 +52,8 @@ public function testCreate(): void
public function testCreateWithDefaultDefinitions(): void
{
$defaultDefinitions = [
Widget::class => [
'id()' => ['id-widget'],
],
WidgetConstructor::class => [
'id()' => ['id-constructor'],
],
Widget::class => ['id()' => ['id-widget']],
WidgetConstructor::class => ['id()' => ['id-constructor']],
];

SimpleFactory::defaultDefinitions($defaultDefinitions);
Expand All @@ -85,9 +79,7 @@ public function testPriority(): void
{
$widget = SimpleFactory::configure(
DefaultDefinition::widget(),
[
'id()' => ['id-configure'],
]
['id()' => ['id-configure']]
);

$this->assertSame('<id="id-configure">', $widget->render());
Expand Down
7 changes: 7 additions & 0 deletions tests/Support/Widget/Widget.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,13 @@ protected function afterRun(string $result): string
return $result;
}

protected function getCookbooks(string $option): array
{
return [
'cookbook-id' => ['id()' => [$option]],
];
}

protected function run(): string
{
return '<id="' . $this->id . '">';
Expand Down
6 changes: 1 addition & 5 deletions tests/Widget/ConstructorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,7 @@ public function testRender(): void

public function testConstructorWithDefinitions(): void
{
$output = WidgetConstructor::widget(
[
'id()' => ['w1'],
]
);
$output = WidgetConstructor::widget(['id()' => ['w1']]);

$this->assertSame('<id="w1">', $output->render());
}
Expand Down
40 changes: 40 additions & 0 deletions tests/Widget/CookbookTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<?php

declare(strict_types=1);

namespace PHPForge\Widget\Tests\Widget;

use PHPForge\Widget\Element;
use PHPForge\Widget\Tests\Support\Widget\Widget;
use PHPUnit\Framework\TestCase;

/**
* @psalm-suppress PropertyNotSetInConstructor
*/
final class CookbookTest extends TestCase
{
public function testCookbook(): void
{
$this->assertSame(
'<id="test-id">',
Widget::widget()->cookbook('cookbook-id', 'test-id')->render()
);
}

public function testGetCookbooks(): void
{
$instance = new class () extends Element {
protected function run(): string
{
return '';
}

public function cookbooks(): array
{
return $this->getCookbooks('');
}
};

$this->assertEmpty($instance->cookbooks());
}
}
Loading