Skip to content

Commit

Permalink
Merge pull request #32 from bayareawebpro/dev
Browse files Browse the repository at this point in the history
add beforeSave callback
  • Loading branch information
bayareawebpro committed Jul 15, 2022
2 parents 2a16c0e + b7723cd commit ce5341d
Show file tree
Hide file tree
Showing 6 changed files with 172 additions and 103 deletions.
12 changes: 12 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,12 +72,20 @@ return Form::make('my-form', [
// After step validation...
->onStep(3, function (Form $form) {
logger('onStep3', $form->toArray());

if($form->request->get('submit') === 'reset'){
$form->reset();
}else{
return response('OK');
}
})

// Modify data before saved to session after each step.
->beforeSave(function(array $data) {

// Transform non-serializable objects to paths, array data etc...
return $data;
})
;
```

Expand Down Expand Up @@ -173,6 +181,10 @@ Get a field value from the form state (session / old input) or fallback to a def

Set a field value from the session form state.

#### `beforeSave(Closure $callback)`

Will be passed the full array of validated data for modification before saving. Callback MUST return an array to be saved.

#### `currentStep()`

Get the current saved step number.
Expand Down
56 changes: 24 additions & 32 deletions phpunit.xml
Original file line number Diff line number Diff line change
@@ -1,34 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit bootstrap="vendor/autoload.php"
backupGlobals="false"
backupStaticAttributes="false"
colors="true"
verbose="true"
convertErrorsToExceptions="true"
convertNoticesToExceptions="true"
convertWarningsToExceptions="true"
processIsolation="false"
stopOnFailure="false">
<testsuites>
<testsuite name="Unit">
<directory suffix="Test.php">./tests/Unit</directory>
</testsuite>
</testsuites>
<filter>
<whitelist addUncoveredFilesFromWhitelist="false">
<directory suffix=".php">src/</directory>
</whitelist>
</filter>
<logging>
<log type="tap" target="build/report.tap"/>
<log type="junit" target="build/report.junit.xml"/>
<log type="coverage-clover" target="build/clover.xml"/>
</logging>
<php>
<env name="APP_KEY" value="AckfSECXIvnK5r28GVIWUAxmbBSjTsm1"/>
<env name="APP_ENV" value="testing"/>
<env name="APP_URL" value="http://localhost"/>
<env name="DB_DATABASE" value=":memory:"/>
<env name="DB_CONNECTION" value="sqlite"/>
</php>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" bootstrap="vendor/autoload.php" backupGlobals="false" backupStaticAttributes="false" colors="true" verbose="true" convertErrorsToExceptions="true" convertNoticesToExceptions="true" convertWarningsToExceptions="true" processIsolation="false" stopOnFailure="false" xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/9.3/phpunit.xsd">
<coverage includeUncoveredFiles="false">
<include>
<directory suffix=".php">src/</directory>
</include>
<report>
<clover outputFile="build/clover.xml"/>
</report>
</coverage>
<testsuites>
<testsuite name="Unit">
<directory suffix="Test.php">./tests/Unit</directory>
</testsuite>
</testsuites>
<logging>
<junit outputFile="build/report.junit.xml"/>
</logging>
<php>
<env name="APP_KEY" value="AckfSECXIvnK5r28GVIWUAxmbBSjTsm1"/>
<env name="APP_ENV" value="testing"/>
<env name="APP_URL" value="http://localhost"/>
<env name="DB_DATABASE" value=":memory:"/>
<env name="DB_CONNECTION" value="sqlite"/>
</php>
</phpunit>
34 changes: 34 additions & 0 deletions phpunit.xml.bak
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit bootstrap="vendor/autoload.php"
backupGlobals="false"
backupStaticAttributes="false"
colors="true"
verbose="true"
convertErrorsToExceptions="true"
convertNoticesToExceptions="true"
convertWarningsToExceptions="true"
processIsolation="false"
stopOnFailure="false">
<testsuites>
<testsuite name="Unit">
<directory suffix="Test.php">./tests/Unit</directory>
</testsuite>
</testsuites>
<filter>
<whitelist addUncoveredFilesFromWhitelist="false">
<directory suffix=".php">src/</directory>
</whitelist>
</filter>
<logging>
<log type="tap" target="build/report.tap"/>
<log type="junit" target="build/report.junit.xml"/>
<log type="coverage-clover" target="build/clover.xml"/>
</logging>
<php>
<env name="APP_KEY" value="AckfSECXIvnK5r28GVIWUAxmbBSjTsm1"/>
<env name="APP_ENV" value="testing"/>
<env name="APP_URL" value="http://localhost"/>
<env name="DB_DATABASE" value=":memory:"/>
<env name="DB_CONNECTION" value="sqlite"/>
</php>
</phpunit>
16 changes: 16 additions & 0 deletions src/MultiStepForm.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
class MultiStepForm implements Responsable, Arrayable
{
protected string $namespace = 'multistep-form';
protected Closure|null $beforeSaveCallback = null;
protected bool $wasReset = false;
protected bool $canGoBack = false;
public Collection $after;
Expand Down Expand Up @@ -443,13 +444,28 @@ public function isLastStep(): bool
return $this->isStep($this->lastStep());
}

/**
* Set the data mapper callback.
* @param Closure $callback
* @return self
*/
public function beforeSave(Closure $callback): self
{
$this->beforeSaveCallback = $callback;
return $this;
}

/**
* Save the validation data to the session.
* @param array $data
* @return $this
*/
protected function save(array $data = []): self
{
if(is_callable($this->beforeSaveCallback)){
$data = call_user_func($this->beforeSaveCallback, $data);
}

$this->session->put($this->namespace, array_merge(
$this->session->get($this->namespace, []), $data
));
Expand Down
143 changes: 73 additions & 70 deletions tests/Fixtures/routes.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,86 +4,89 @@
use BayAreaWebPro\MultiStepForms\MultiStepForm;
use Illuminate\Support\Facades\Route;

Route::any('/hooks', function(){
Route::any('/hooks', function () {
return MultiStepForm::make('form', [
'title' => 'MultiStep Form'
])
->namespaced('test')
->tap(new Invoke)
->beforeStep('*', function (MultiStepForm $form) {
$form->setValue('before', true);
if($form->request->filled('before*')){
return response('before*');
}
})
->onStep('*', function (MultiStepForm $form) {
if($form->request->filled('on*')){
return response('on*');
}
})
->addStep(1)
->onStep(1, function (MultiStepForm $form) {
if($form->request->filled('on1')){
return response('on1');
}
})
->beforeStep(1, function (MultiStepForm $form) {
if($form->request->filled('before1')){
return response('before1');
}
})
->addStep(2)
->onStep(2, function (MultiStepForm $form) {
if($form->request->filled('on2')){
return response('on2');
}
})
->beforeStep(2, function (MultiStepForm $form) {
if($form->request->filled('before2')){
return response('before2');
}
})
;
->namespaced('test')
->tap(new Invoke)
->beforeSave(function (array $data) {
$data['before_save'] = true;
return $data;
})
->beforeStep('*', function (MultiStepForm $form) {
$form->setValue('before', true);
if ($form->request->filled('before*')) {
return response('before*');
}
})
->onStep('*', function (MultiStepForm $form) {
if ($form->request->filled('on*')) {
return response('on*');
}
})
->addStep(1)
->onStep(1, function (MultiStepForm $form) {
if ($form->request->filled('on1')) {
return response('on1');
}
})
->beforeStep(1, function (MultiStepForm $form) {
if ($form->request->filled('before1')) {
return response('before1');
}
})
->addStep(2)
->onStep(2, function (MultiStepForm $form) {
if ($form->request->filled('on2')) {
return response('on2');
}
})
->beforeStep(2, function (MultiStepForm $form) {
if ($form->request->filled('before2')) {
return response('before2');
}
});
})
->middleware('web')
->name('hooks');
->middleware('web')
->name('hooks');


Route::any('/', function(){
Route::any('/', function () {
return MultiStepForm::make('form', [
'title' => 'MultiStep Form'
])
->canNavigateBack(true)
->namespaced('test')
->addStep(1, [
'rules' => ['name' => 'required'],
'data' => ['title' => 'MultiStep Form | Step 1']
])
->addStep(2, [
'rules' => ['role' => 'required'],
'data' => ['title' => 'MultiStep Form | Step 2']
])
->onStep(2, function (MultiStepForm $form) {
->canNavigateBack(true)
->namespaced('test')
->addStep(1, [
'rules' => ['name' => 'required'],
'data' => ['title' => 'MultiStep Form | Step 1']
])
->addStep(2, [
'rules' => ['role' => 'required'],
'data' => ['title' => 'MultiStep Form | Step 2']
])
->onStep(2, function (MultiStepForm $form) {


throw_if($form->isFuture(4), \Exception::class,"Step 4 not future.");
throw_if($form->isLastStep(), \Exception::class,"Step 2 not last.");
throw_unless($form->isFuture(3), \Exception::class,"Step 3 future.");
})
->addStep(3)
->beforeStep('*', function (MultiStepForm $form) {
if($form->request->get('submit') === 'reset'){
$form->reset(['reset' => true]);
}
})
->onStep(3, function (MultiStepForm $form) {
throw_unless($form->isActive(3), \Exception::class,"Step 3 active.");
throw_if($form->isActive(2), \Exception::class,"Step 2 not active.");
throw_if($form->isFuture(4), \Exception::class, "Step 4 not future.");
throw_if($form->isLastStep(), \Exception::class, "Step 2 not last.");
throw_unless($form->isFuture(3), \Exception::class, "Step 3 future.");
})
->addStep(3)
->beforeStep('*', function (MultiStepForm $form) {
if ($form->request->get('submit') === 'reset') {
$form->reset(['reset' => true]);
}
})
->onStep(3, function (MultiStepForm $form) {
throw_unless($form->isActive(3), \Exception::class, "Step 3 active.");
throw_if($form->isActive(2), \Exception::class, "Step 2 not active.");

throw_unless($form->isPast(1), \Exception::class,"Step 1 not past.");
throw_if($form->isPast(3), \Exception::class,"Step 3 not past.");
return response('OK');
});
throw_unless($form->isPast(1), \Exception::class, "Step 1 not past.");
throw_if($form->isPast(3), \Exception::class, "Step 3 not past.");
return response('OK');
});
})
->middleware('web')
->name('submit');
->middleware('web')
->name('submit');
14 changes: 13 additions & 1 deletion tests/Unit/HooksTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,26 @@

class HooksTest extends TestCase
{
public function test_before_save()
{
$this->withSession(['test' => []]);
$this
->json('POST', route('hooks'), [
'form_step' => 1,
])
->assertOk()
->assertSessionHas('test.before_save')
;
}

public function test_tap()
{
$this
->json('GET', route('hooks'),[
'invoke' =>true,
])
->assertSessionHas('test.invoke')
->assertOk()
->assertSessionHas('test.invoke')
;
}

Expand Down

0 comments on commit ce5341d

Please sign in to comment.