Skip to content
This repository was archived by the owner on Feb 8, 2024. It is now read-only.
Open
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
8 changes: 8 additions & 0 deletions src/Contracts/Element.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,14 @@ interface Element
{
public function __construct(array $options = []);

public function setOptions(array $options): Element;

public function getOptions(): array;

public function isValid(): bool;

public function resolve(): Element;

public function render(): string;

public function toString(): string;
Expand Down
2 changes: 2 additions & 0 deletions src/Elements/BladeElement.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ abstract class BladeElement extends Element
{
public function render(): string
{
$this->resolve();

return $this->getEngine()->make(implode('.', array_filter([
$this->getPath(),
$this->name,
Expand Down
61 changes: 47 additions & 14 deletions src/Elements/Element.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace Curlyspoon\Core\Elements;

use Curlyspoon\Core\Contracts\Element as ElementContract;
use Exception;
use Symfony\Component\OptionsResolver\OptionsResolver;

abstract class Element implements ElementContract
Expand Down Expand Up @@ -45,21 +46,51 @@ abstract class Element implements ElementContract
*/
protected $options = [];

/**
* @var OptionsResolver
*/
protected $resolver;

public function __construct(array $options = [])
{
$this->setOptions($options);
}

public function setOptions(array $options)
public static function make(array $options = []): ElementContract
{
$this->options = $this->optionsResolver()->resolve($options);
return new static($options);
}

public function setOptions(array $options): ElementContract
{
$this->options = $options;

return $this;
}

public function getOptions(): array
{
return $this->options;
}

public function resolve(): ElementContract
{
$this->setOptions($this->optionsResolver()->resolve($this->getOptions()));

return $this;
}

public function isValid(): bool
{
try {
$this->optionsResolver()->resolve($this->getOptions());

return true;
} catch (Exception $exception) {
return false;
}
}

abstract public function render(): string;

public function toString(): string
Expand All @@ -74,23 +105,25 @@ public function __toString(): string

protected function optionsResolver(): OptionsResolver
{
$resolver = new OptionsResolver();
$resolver->setDefaults($this->defaults);
if (is_null($this->resolver)) {
$this->resolver = new OptionsResolver();
$this->resolver->setDefaults($this->defaults);

$resolver->setRequired($this->required);
$this->resolver->setRequired($this->required);

foreach ($this->types as $option => $types) {
$resolver->setAllowedTypes($option, $types);
}
foreach ($this->types as $option => $types) {
$this->resolver->setAllowedTypes($option, $types);
}

foreach ($this->values as $option => $values) {
$resolver->setAllowedValues($option, $values);
}
foreach ($this->values as $option => $values) {
$this->resolver->setAllowedValues($option, $values);
}

if (method_exists($this, 'configureOptions')) {
$this->configureOptions($resolver);
if (method_exists($this, 'configureOptions')) {
$this->configureOptions($this->resolver);
}
}

return $resolver;
return $this->resolver;
}
}
2 changes: 2 additions & 0 deletions src/Elements/PugElement.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ abstract class PugElement extends Element
{
public function render(): string
{
$this->resolve();

return $this->getEngine()->renderFile($this->getPath().'/'.$this->name.'.pug', $this->getOptions());
}

Expand Down
2 changes: 2 additions & 0 deletions src/Elements/TwigElement.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ abstract class TwigElement extends Element
{
public function render(): string
{
$this->resolve();

return $this->getEngine()->render($this->name.'.twig', $this->getOptions());
}

Expand Down
2 changes: 2 additions & 0 deletions tests/Elements/Native/Headline.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ class Headline extends Element

public function render(): string
{
$this->resolve();

return sprintf('<h%d>%s</h%d>', $this->options['size'], $this->options['text'], $this->options['size']);
}
}
12 changes: 6 additions & 6 deletions tests/integration/Libs/ElementTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ public function text_option_is_required()
$this->expectException(MissingOptionsException::class);
$this->expectExceptionMessage('The required option "text" is missing.');

new Headline();
Headline::make()->resolve();
}

/** @test */
Expand All @@ -32,12 +32,12 @@ public function text_option_does_not_accept_array()
$this->expectException(InvalidOptionsException::class);
$this->expectExceptionMessage('The option "text" with value array is expected to be of type "string", but is of type "array".');

new Headline([
Headline::make([
'text' => [
'my',
'headline',
],
]);
])->resolve();
}

/** @test */
Expand All @@ -47,7 +47,7 @@ public function size_option_has_default()
'text' => 'my headline',
]);

$this->assertEquals(1, $headline->getOptions()['size']);
$this->assertEquals(1, $headline->resolve()->getOptions()['size']);
}

/** @test */
Expand All @@ -56,10 +56,10 @@ public function size_option_does_not_accept_zero()
$this->expectException(InvalidOptionsException::class);
$this->expectExceptionMessage('The option "size" with value 0 is invalid. Accepted values are: 1, 2, 3, 4, 5, 6.');

new Headline([
Headline::make([
'text' => 'my headline',
'size' => 0,
]);
])->resolve();
}

/** @test */
Expand Down