-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
f80567a
commit b349098
Showing
14 changed files
with
299 additions
and
49 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
<?php | ||
|
||
namespace Livewire\Features\SupportFormObjects; | ||
|
||
use Illuminate\Contracts\Support\Arrayable; | ||
use Livewire\Component; | ||
use Livewire\Drawer\Utils; | ||
|
||
class Form implements Arrayable | ||
{ | ||
function __construct( | ||
protected Component $component, | ||
protected $propertyName | ||
) { | ||
$this->addValidationRulesToComponent(); | ||
} | ||
|
||
public function getComponent() { return $this->component; } | ||
public function getPropertyName() { return $this->propertyName; } | ||
|
||
public function addValidationRulesToComponent() | ||
{ | ||
$rules = []; | ||
|
||
if (method_exists($this, 'rules')) $rules = $this->rules(); | ||
else if (property_exists($this, 'rules')) $rules = $this->rules; | ||
|
||
$rulesWithPrefixedKeys = []; | ||
|
||
foreach ($rules as $key => $value) { | ||
$rulesWithPrefixedKeys[$this->propertyName . '.' . $key] = $value; | ||
} | ||
|
||
$this->component->addRulesFromOutside($rulesWithPrefixedKeys); | ||
} | ||
|
||
public function validate() | ||
{ | ||
$rules = $this->component->getRules(); | ||
|
||
$filteredRules = []; | ||
|
||
foreach ($rules as $key => $value) { | ||
if (! str($key)->startsWith($this->propertyName . '.')) continue; | ||
|
||
$filteredRules[$key] = $value; | ||
} | ||
|
||
return $this->component->validate($filteredRules)[$this->propertyName]; | ||
} | ||
|
||
public function toArray() | ||
{ | ||
return Utils::getPublicProperties($this); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
<?php | ||
|
||
namespace Livewire\Features\SupportFormObjects; | ||
|
||
use Livewire\Mechanisms\HandleComponents\Synthesizers\Synth; | ||
use Livewire\Features\SupportAttributes\AttributeCollection; | ||
use Livewire\Drawer\Utils; | ||
|
||
class FormObjectSynth extends Synth { | ||
public static $key = 'form'; | ||
|
||
static function match($target) | ||
{ | ||
return $target instanceof Form; | ||
} | ||
|
||
function dehydrate($target, $dehydrateChild) | ||
{ | ||
$data = $target->toArray(); | ||
|
||
foreach ($data as $key => $child) { | ||
$data[$key] = $dehydrateChild($key, $child); | ||
} | ||
|
||
return [$data, ['class' => get_class($target)]]; | ||
} | ||
|
||
function hydrate($data, $meta, $hydrateChild) | ||
{ | ||
$form = new $meta['class']($this->context->component, $this->path); | ||
|
||
static::bootFormObject($this->context->component, $form, $this->path); | ||
|
||
foreach ($data as $key => $child) { | ||
$form->$key = $hydrateChild($key, $child); | ||
} | ||
|
||
return $form; | ||
} | ||
|
||
function set(&$target, $key, $value,) | ||
{ | ||
$target->$key = $value; | ||
} | ||
|
||
public static function bootFormObject($component, $form, $path) | ||
{ | ||
$component->mergeOutsideAttributes( | ||
AttributeCollection::fromComponent($component, $form, $path . '.') | ||
); | ||
} | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
<?php | ||
|
||
namespace Livewire\Features\SupportFormObjects; | ||
|
||
use ReflectionClass; | ||
use Livewire\ComponentHook; | ||
use Livewire\Features\SupportAttributes\AttributeCollection; | ||
|
||
class SupportFormObjects extends ComponentHook | ||
{ | ||
public static function provide() | ||
{ | ||
app('livewire')->propertySynthesizer( | ||
FormObjectSynth::class | ||
); | ||
} | ||
|
||
function boot() | ||
{ | ||
$this->initializeFormObjects(); | ||
} | ||
|
||
protected function initializeFormObjects() | ||
{ | ||
foreach ((new ReflectionClass($this->component))->getProperties() as $property) { | ||
// Public properties only... | ||
if ($property->isPublic() !== true) continue; | ||
// Uninitialized properties only... | ||
if ($property->isInitialized($this->component)) continue; | ||
|
||
$type = $property->getType()->getName(); | ||
|
||
// "Form" object property types only... | ||
if (! is_subclass_of($type, Form::class)) continue; | ||
|
||
$form = new $type( | ||
$this->component, | ||
$name = $property->getName() | ||
); | ||
|
||
FormObjectSynth::bootFormObject($this->component, $form, $name); | ||
|
||
$property->setValue($this->component, $form); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
<?php | ||
|
||
namespace Livewire\Features\SupportFormObjects; | ||
|
||
use Livewire\Livewire; | ||
use Livewire\Component; | ||
use ReflectionObject; | ||
|
||
class UnitTest extends \Tests\TestCase | ||
{ | ||
/** @test */ | ||
function can_use_a_form_object() | ||
{ | ||
Livewire::test(new class extends Component { | ||
public PostFormStub $form; | ||
|
||
public function render() { | ||
return '<div></div>'; | ||
} | ||
}) | ||
->assertSet('form.title', '') | ||
->assertSet('form.content', '') | ||
->set('form.title', 'Some Title') | ||
->set('form.content', 'Some content...') | ||
->assertSet('form.title', 'Some Title') | ||
->assertSet('form.content', 'Some content...') | ||
; | ||
} | ||
|
||
/** @test */ | ||
function can_validate_a_form_object() | ||
{ | ||
Livewire::test(new class extends Component { | ||
public PostFormValidateStub $form; | ||
|
||
function save() | ||
{ | ||
$this->form->validate(); | ||
} | ||
|
||
public function render() { | ||
return '<div></div>'; | ||
} | ||
}) | ||
->assertSet('form.title', '') | ||
->assertSet('form.content', '') | ||
->assertHasNoErrors() | ||
->call('save') | ||
->assertHasErrors('form.title') | ||
->assertHasErrors('form.content') | ||
; | ||
} | ||
|
||
/** @test */ | ||
function can_validate_a_form_object_using_rule_attributes() | ||
{ | ||
Livewire::test(new class extends Component { | ||
public PostFormRuleAttributeStub $form; | ||
|
||
function save() | ||
{ | ||
$this->form->validate(); | ||
} | ||
|
||
function render() { | ||
return '<div></div>'; | ||
} | ||
}) | ||
->assertSet('form.title', '') | ||
->assertSet('form.content', '') | ||
->assertHasNoErrors() | ||
->call('save') | ||
->assertHasErrors('form.title') | ||
->assertHasErrors('form.content') | ||
->set('form.title', 'title...') | ||
->set('form.content', 'content...') | ||
->assertHasNoErrors() | ||
->call('save') | ||
; | ||
} | ||
} | ||
|
||
class PostFormStub extends Form | ||
{ | ||
public $title = ''; | ||
|
||
public $content = ''; | ||
} | ||
|
||
class PostFormValidateStub extends Form | ||
{ | ||
public $title = ''; | ||
|
||
public $content = ''; | ||
|
||
protected $rules = [ | ||
'title' => 'required', | ||
'content' => 'required', | ||
]; | ||
} | ||
|
||
class PostFormRuleAttributeStub extends Form | ||
{ | ||
#[\Livewire\Attributes\Rule('required')] | ||
public $title = ''; | ||
|
||
#[\Livewire\Attributes\Rule('required')] | ||
public $content = ''; | ||
} |
Oops, something went wrong.