mirror of
https://github.com/silverstripe/silverstripe-multiform
synced 2024-10-22 11:05:49 +02:00
feat: silverstripe 5 support
This commit is contained in:
parent
27552089c1
commit
3d5995526c
11
.github/workflows/ci.yml
vendored
Normal file
11
.github/workflows/ci.yml
vendored
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
name: CI
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
pull_request:
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
ci:
|
||||||
|
name: CI
|
||||||
|
uses: silverstripe/gha-ci/.github/workflows/ci.yml@v1
|
37
.travis.yml
37
.travis.yml
@ -1,37 +0,0 @@
|
|||||||
language: php
|
|
||||||
|
|
||||||
dist: trusty
|
|
||||||
|
|
||||||
env:
|
|
||||||
global:
|
|
||||||
- COMPOSER_ROOT_VERSION=4.0.x-dev
|
|
||||||
|
|
||||||
matrix:
|
|
||||||
include:
|
|
||||||
- php: 5.6
|
|
||||||
env: DB=MYSQL PHPCS_TEST=1 PHPUNIT_TEST=1
|
|
||||||
- php: 7.0
|
|
||||||
env: DB=PGSQL PHPUNIT_TEST=1
|
|
||||||
- php: 7.1
|
|
||||||
env: DB=MYSQL PHPUNIT_COVERAGE_TEST=1
|
|
||||||
- php: 7.2
|
|
||||||
env: DB=MYSQL PHPUNIT_TEST=1
|
|
||||||
|
|
||||||
before_script:
|
|
||||||
# Init PHP
|
|
||||||
- phpenv rehash
|
|
||||||
- phpenv config-rm xdebug.ini
|
|
||||||
|
|
||||||
# Install composer dependencies
|
|
||||||
- composer validate
|
|
||||||
- composer require --no-update silverstripe/recipe-core:1.0.x-dev
|
|
||||||
- if [[ $DB == PGSQL ]]; then composer require --no-update silverstripe/postgresql:2.0.x-dev; fi
|
|
||||||
- composer install --prefer-dist --no-interaction --no-progress --no-suggest --optimize-autoloader --verbose --profile
|
|
||||||
|
|
||||||
script:
|
|
||||||
- if [[ $PHPUNIT_TEST ]]; then vendor/bin/phpunit; fi
|
|
||||||
- if [[ $PHPUNIT_COVERAGE_TEST ]]; then phpdbg -qrr vendor/bin/phpunit --coverage-clover=coverage.xml; fi
|
|
||||||
- if [[ $PHPCS_TEST ]]; then vendor/bin/phpcs --standard=vendor/silverstripe/framework/phpcs.xml.dist src/ tests/; fi
|
|
||||||
|
|
||||||
after_success:
|
|
||||||
- if [[ $PHPUNIT_COVERAGE_TEST ]]; then bash <(curl -s https://codecov.io/bash) -f coverage.xml; fi
|
|
34
CHANGELOG
34
CHANGELOG
@ -1,34 +0,0 @@
|
|||||||
0.3:
|
|
||||||
API CHANGE Changed MultiFormStep::$next_steps to public, and MultiFormStep::$is_final_step to public
|
|
||||||
API CHANGE MultiForm::$start_step is now declared as public, not protected, due to changes in Object::get_static()
|
|
||||||
ENHANCEMENT Custom text for back/next and submit buttons on a per-step basis
|
|
||||||
BUGFIX Checking $this->Data exists before trying to unserialize it
|
|
||||||
BUGFIX #4480 MultiForm::next() and MultiForm::prev() now save the form data before checking the next or previous step
|
|
||||||
API CHANGE Added currentSessionHash property to MultiForm which stores the currently opened session by the user
|
|
||||||
API CHANGE Renamed MultiForm::getSessionRecord() to getCurrentSession() and removed the parameter, since this wasn't done in a very OOP manner
|
|
||||||
ENHANCEMENT: enabled MultiForm to use customised action (actions_exempt_from_validation).
|
|
||||||
Changed has been done in the constructor to read the static variables (incl. overwritten variables).
|
|
||||||
BUGFIX: MultiFormStep::saveInto() needs the current Controller as the new $form Controller to work
|
|
||||||
ENHANCEMENT Added language files
|
|
||||||
BUGFIX If the step doesn't exist, don't attempt to delete it
|
|
||||||
BUGFIX Ensure that any relations to MultiFormStep are destroyed before calling delete()
|
|
||||||
ENHANCEMENT Removed hack of specific action to bypass validation and allow specifying actions to be exempt through a public static variable
|
|
||||||
|
|
||||||
0.2:
|
|
||||||
- ENHANCEMENT Updated entities and added german translation for multiform
|
|
||||||
- ENHANCEMENT Making multiform module translatable
|
|
||||||
- ENHANCEMENT Added MultiFormStep->saveInto() to simulate Form->saveInto()
|
|
||||||
- ENHANCEMENT Made MultiForm->prev() do the same behaviour for saving data
|
|
||||||
- ENHANCEMENT Added MultiForm->getSavedSteps()
|
|
||||||
- BUGFIX Removing url_type which isnt very useful
|
|
||||||
- BUGFIX $this->form wasn't accessible on MultiFormStep
|
|
||||||
- ENHANCEMENT Correct use of parent::construct() so that fields, actions
|
|
||||||
- BUGFIX SQL injection possibility fix on MultiForm->getSessionRecordByID()
|
|
||||||
- BUGFIX Disable security token inherited from Form, which isn't required
|
|
||||||
- BUGFIX Made MultiFormPurgeTask greatly simplified, and workable
|
|
||||||
- ENHANCEMENT Allowed static $ignored_fields to be overloaded on subclass of MultiForm
|
|
||||||
- BUGFIX Use $nextStep->Link and $prevStep->Link() for prev() and next() on MultiForm
|
|
||||||
- API CHANGE Ticket #2562 - Cleaner instanciation of MultiForm subclass without having to call ->init()
|
|
||||||
|
|
||||||
0.1:
|
|
||||||
- initial release
|
|
191
README.md
191
README.md
@ -15,46 +15,46 @@ individual implementation can be customized to the project requirements.
|
|||||||
|
|
||||||
## Maintainer Contact
|
## Maintainer Contact
|
||||||
|
|
||||||
* Sean Harvey (Nickname: sharvey, halkyon) <sean (at) silverstripe (dot) com>
|
- Sean Harvey (Nickname: sharvey, halkyon) <sean (at) silverstripe (dot) com>
|
||||||
* Ingo Schommer (Nickname: chillu) <ingo (at) silverstripe (dot) com>
|
- Ingo Schommer (Nickname: chillu) <ingo (at) silverstripe (dot) com>
|
||||||
|
|
||||||
## Requirements
|
## Requirements
|
||||||
|
|
||||||
* SilverStripe ^4.0
|
- SilverStripe ^5.
|
||||||
|
|
||||||
**Note:** For a SilverStripe 3.x compatible version, please use [the 1.x release line](https://github.com/silverstripe/silverstripe-multiform/tree/1.3).
|
**Note:** For a SilverStripe 4.x or 3.x compatible version, please use `^2` or `^1` tagged version
|
||||||
|
|
||||||
## What it does do
|
## What it does do
|
||||||
|
|
||||||
* Abstracts fields, actions and validation to each individual step.
|
- Abstracts fields, actions and validation to each individual step.
|
||||||
* Maintains flow control automatically, so it knows which steps are ahead and
|
- Maintains flow control automatically, so it knows which steps are ahead and
|
||||||
behind. It also can retrieve an entire step process from start to finish, useful
|
behind. It also can retrieve an entire step process from start to finish, useful
|
||||||
for a step list.
|
for a step list.
|
||||||
* Persists data by storing it in the session for each step, once it's
|
- Persists data by storing it in the session for each step, once it's
|
||||||
completed. The session is saved into the database.
|
completed. The session is saved into the database.
|
||||||
* Allows customisation of next, previous steps, saving, loading and
|
- Allows customisation of next, previous steps, saving, loading and
|
||||||
finalisation of the entire step process
|
finalisation of the entire step process
|
||||||
* Allows for basic ability to branch a step by overloading the next step method
|
- Allows for basic ability to branch a step by overloading the next step method
|
||||||
with logic to switch based on a condition (e.g. a checkbox, or dropdown in the
|
with logic to switch based on a condition (e.g. a checkbox, or dropdown in the
|
||||||
field data).
|
field data).
|
||||||
* Ties a user logged in who is using the step process (if applicable). This
|
- Ties a user logged in who is using the step process (if applicable). This
|
||||||
means you can build extended security or logging.
|
means you can build extended security or logging.
|
||||||
* Basic flexibility on the URL presented to the user when they are using the
|
- Basic flexibility on the URL presented to the user when they are using the
|
||||||
forms. By default it stores an encrypted hash of the session in the URL, but you
|
forms. By default it stores an encrypted hash of the session in the URL, but you
|
||||||
can reference it by the ID instead. It's recommend that additional security,
|
can reference it by the ID instead. It's recommend that additional security,
|
||||||
such as checking the user who first started the session be applied if you want
|
such as checking the user who first started the session be applied if you want
|
||||||
to reference by ID.
|
to reference by ID.
|
||||||
|
|
||||||
## What it doesn't do
|
## What it doesn't do
|
||||||
|
|
||||||
* Automatically handle relation saving, e.g. MembershipForm manages the Member
|
- Automatically handle relation saving, e.g. MembershipForm manages the Member
|
||||||
* Provide a complete package out of the box (you must write a bit of code using
|
- Provide a complete package out of the box (you must write a bit of code using
|
||||||
the tutorial!)
|
the tutorial!)
|
||||||
* Automatically determine what to do at the end of the process, and where to
|
- Automatically determine what to do at the end of the process, and where to
|
||||||
save it
|
save it
|
||||||
* Provide nicely presented URLs of each step (an enhancement, for the future)
|
- Provide nicely presented URLs of each step (an enhancement, for the future)
|
||||||
|
|
||||||
Note: The *multiform* directory should sit in your SilverStripe root project
|
Note: The _multiform_ directory should sit in your SilverStripe root project
|
||||||
directory in the file system as a sibling of cms and framework.
|
directory in the file system as a sibling of cms and framework.
|
||||||
|
|
||||||
## Reporting bugs
|
## Reporting bugs
|
||||||
@ -74,7 +74,7 @@ before.
|
|||||||
If you are not familiar with SilverStripe, it is highly recommended you run
|
If you are not familiar with SilverStripe, it is highly recommended you run
|
||||||
through the tutorials before attempting to start with this one.
|
through the tutorials before attempting to start with this one.
|
||||||
|
|
||||||
* [View a listing of all available tutorials](http://doc.silverstripe.org/tutorials)
|
- [View a listing of all available tutorials](http://doc.silverstripe.org/tutorials)
|
||||||
|
|
||||||
### 1. Installing
|
### 1. Installing
|
||||||
|
|
||||||
@ -88,9 +88,9 @@ composer require silverstripe/multiform
|
|||||||
|
|
||||||
### 2. Create subclass of MultiForm
|
### 2. Create subclass of MultiForm
|
||||||
|
|
||||||
First of all, we need to create a new subclass of *MultiForm*.
|
First of all, we need to create a new subclass of _MultiForm_.
|
||||||
|
|
||||||
For the above example, our multi-form will be called *SurveyForm*
|
For the above example, our multi-form will be called _SurveyForm_
|
||||||
|
|
||||||
```php
|
```php
|
||||||
use SilverStripe\MultiForm\Forms\MultiForm;
|
use SilverStripe\MultiForm\Forms\MultiForm;
|
||||||
@ -144,7 +144,7 @@ To get more than one step, each step needs to know what it's next step is in
|
|||||||
order to use flow control in our system.
|
order to use flow control in our system.
|
||||||
|
|
||||||
To let the step know what step is next in the process, we do the same as setting
|
To let the step know what step is next in the process, we do the same as setting
|
||||||
the `$start_step` variable *SurveyForm*, but we call it `$next_steps`.
|
the `$start_step` variable _SurveyForm_, but we call it `$next_steps`.
|
||||||
|
|
||||||
```php
|
```php
|
||||||
use SilverStripe\MultiForm\Models\MultiFormStep;
|
use SilverStripe\MultiForm\Models\MultiFormStep;
|
||||||
@ -166,7 +166,7 @@ class PersonalDetailsStep extends MultiFormStep
|
|||||||
```
|
```
|
||||||
|
|
||||||
At the very least, each step also has to have a `getFields()` method returning
|
At the very least, each step also has to have a `getFields()` method returning
|
||||||
a *FieldSet* with some form field objects. These are the fields that the form
|
a _FieldSet_ with some form field objects. These are the fields that the form
|
||||||
will render for the given step.
|
will render for the given step.
|
||||||
|
|
||||||
Keep in mind that our multi-form also requires an end point. This step is the
|
Keep in mind that our multi-form also requires an end point. This step is the
|
||||||
@ -188,17 +188,17 @@ class OrganisationDetailsStep extends MultiFormStep
|
|||||||
|
|
||||||
### 5. Run database integrity check
|
### 5. Run database integrity check
|
||||||
|
|
||||||
We need to run *dev/build?flush=1* now, so that the classes are available to the
|
We need to run _dev/build?flush=1_ now, so that the classes are available to the
|
||||||
SilverStripe manifest builder, and to ensure that the database is up to date
|
SilverStripe manifest builder, and to ensure that the database is up to date
|
||||||
with all the latest tables. So you can go ahead and do that.
|
with all the latest tables. So you can go ahead and do that.
|
||||||
|
|
||||||
*Note: Whenever you add a new step, you **MUST** run dev/build?flush=1 or you
|
_Note: Whenever you add a new step, you **MUST** run dev/build?flush=1 or you
|
||||||
may receive errors.*
|
may receive errors._
|
||||||
|
|
||||||
However, we've forgotten one thing. We need to create a method on a page-type so
|
However, we've forgotten one thing. We need to create a method on a page-type so
|
||||||
that the form can be rendered into a given template.
|
that the form can be rendered into a given template.
|
||||||
|
|
||||||
So, if we want to render our multi-form as `$SurveyForm` in the *Page.ss*
|
So, if we want to render our multi-form as `$SurveyForm` in the _Page.ss_
|
||||||
template, we need to create a SurveyForm method (function) on the controller:
|
template, we need to create a SurveyForm method (function) on the controller:
|
||||||
|
|
||||||
```php
|
```php
|
||||||
@ -228,32 +228,23 @@ class PageController extends ContentController
|
|||||||
```
|
```
|
||||||
|
|
||||||
The `SurveyForm()` function will create a new instance of our subclass of
|
The `SurveyForm()` function will create a new instance of our subclass of
|
||||||
MultiForm, which in this example, is *SurveyForm*. This in turn will then set
|
MultiForm, which in this example, is _SurveyForm_. This in turn will then set
|
||||||
up all the form fields, actions, and validation available to each step, as well
|
up all the form fields, actions, and validation available to each step, as well
|
||||||
as the session.
|
as the session.
|
||||||
|
|
||||||
You can of course, put the *SurveyForm* method on any controller class you
|
You can of course, put the _SurveyForm_ method on any controller class you
|
||||||
like.
|
like.
|
||||||
|
|
||||||
Your template should look something like this, to render the form in:
|
Your template should look something like this, to render the form in:
|
||||||
|
|
||||||
```html
|
```html
|
||||||
<div id="content">
|
<div id="content">
|
||||||
<% if $Content %>
|
<% if $Content %> $Content <% end_if %> <% if $SurveyForm %> $SurveyForm <%
|
||||||
$Content
|
end_if %> <% if $Form %> $Form <% end_if %>
|
||||||
<% end_if %>
|
|
||||||
|
|
||||||
<% if $SurveyForm %>
|
|
||||||
$SurveyForm
|
|
||||||
<% end_if %>
|
|
||||||
|
|
||||||
<% if $Form %>
|
|
||||||
$Form
|
|
||||||
<% end_if %>
|
|
||||||
</div>
|
</div>
|
||||||
```
|
```
|
||||||
|
|
||||||
In this case, the above template example is a *sub-template* inside the *Layout*
|
In this case, the above template example is a _sub-template_ inside the _Layout_
|
||||||
directory for the templates. Note that we have also included `$Form`, so
|
directory for the templates. Note that we have also included `$Form`, so
|
||||||
standard forms are still able to be used alongside our multi-step form.
|
standard forms are still able to be used alongside our multi-step form.
|
||||||
|
|
||||||
@ -264,8 +255,8 @@ useful, out of the box.
|
|||||||
|
|
||||||
Two of them, as of the time of writing this are:
|
Two of them, as of the time of writing this are:
|
||||||
|
|
||||||
* Progress list (multiform/templates/Includes/MultiFormProgressList.ss)
|
- Progress list (multiform/templates/Includes/MultiFormProgressList.ss)
|
||||||
* Progress complete percent (multiform/templates/Includes/MultiFormProgressPercent.ss)
|
- Progress complete percent (multiform/templates/Includes/MultiFormProgressPercent.ss)
|
||||||
|
|
||||||
They are designed to be used either by themselves, or alongside each other.
|
They are designed to be used either by themselves, or alongside each other.
|
||||||
For example, the percentage could compliment the progress list to give an
|
For example, the percentage could compliment the progress list to give an
|
||||||
@ -277,9 +268,7 @@ To include these with our instance of multiform, we just need to add an
|
|||||||
For example:
|
For example:
|
||||||
|
|
||||||
```html
|
```html
|
||||||
<% with $SurveyForm %>
|
<% with $SurveyForm %> <% include MultiFormProgressList %> <% end_with %>
|
||||||
<% include MultiFormProgressList %>
|
|
||||||
<% end_with %>
|
|
||||||
```
|
```
|
||||||
|
|
||||||
This means the included template is rendered within the scope of the
|
This means the included template is rendered within the scope of the
|
||||||
@ -290,20 +279,9 @@ Putting it together, we might have something looking like this:
|
|||||||
|
|
||||||
```html
|
```html
|
||||||
<div id="content">
|
<div id="content">
|
||||||
<% if $Content %>
|
<% if $Content %> $Content <% end_if %> <% if $SurveyForm %> <% with
|
||||||
$Content
|
$SurveyForm %> <% include MultiFormProgressList %> <% end_with %>
|
||||||
<% end_if %>
|
$SurveyForm <% end_if %> <% if $Form %> $Form <% end_if %>
|
||||||
|
|
||||||
<% if $SurveyForm %>
|
|
||||||
<% with $SurveyForm %>
|
|
||||||
<% include MultiFormProgressList %>
|
|
||||||
<% end_with %>
|
|
||||||
|
|
||||||
$SurveyForm
|
|
||||||
<% end_if %>
|
|
||||||
<% if $Form %>
|
|
||||||
$Form
|
|
||||||
<% end_if %>
|
|
||||||
</div>
|
</div>
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -312,29 +290,27 @@ specific to your project, just create a new "Include" template inside your own
|
|||||||
project templates directory, and include that instead. Some helpful methods to
|
project templates directory, and include that instead. Some helpful methods to
|
||||||
use on the MultiForm would be:
|
use on the MultiForm would be:
|
||||||
|
|
||||||
|
- `AllStepsLinear()` (which also makes use of `getAllStepsRecursive()` to
|
||||||
* `AllStepsLinear()` (which also makes use of `getAllStepsRecursive()` to
|
produce a list of steps)
|
||||||
produce a list of steps)
|
- `getCompletedStepCount()`
|
||||||
* `getCompletedStepCount()`
|
- `getTotalStepCount()`
|
||||||
* `getTotalStepCount()`
|
- `getCompletedPercent()`
|
||||||
* `getCompletedPercent()`
|
|
||||||
|
|
||||||
The default progress indicators make use of the above functions in the
|
The default progress indicators make use of the above functions in the
|
||||||
templates.
|
templates.
|
||||||
|
|
||||||
To use a custom method of your own, simply create a new method on your subclass
|
To use a custom method of your own, simply create a new method on your subclass
|
||||||
of MultiForm. In this example, *SurveyForm* would be the one to customise.
|
of MultiForm. In this example, _SurveyForm_ would be the one to customise.
|
||||||
This new method you create would then become available in the progress indicator
|
This new method you create would then become available in the progress indicator
|
||||||
template.
|
template.
|
||||||
|
|
||||||
|
|
||||||
### 7. Loading values from other steps
|
### 7. Loading values from other steps
|
||||||
|
|
||||||
There are several use cases where you want to pre-populate a value based on the submission value of another step.
|
There are several use cases where you want to pre-populate a value based on the submission value of another step.
|
||||||
There are two methods supporting this:
|
There are two methods supporting this:
|
||||||
|
|
||||||
* `getValueFromOtherStep()` loads any submitted value from another step from the session
|
- `getValueFromOtherStep()` loads any submitted value from another step from the session
|
||||||
* `copyValueFromOtherStep()` saves you the repeated work of adding the same lines of code again and again.
|
- `copyValueFromOtherStep()` saves you the repeated work of adding the same lines of code again and again.
|
||||||
|
|
||||||
Here is an example of how to populate the email address from step 1 in step2 :
|
Here is an example of how to populate the email address from step 1 in step2 :
|
||||||
|
|
||||||
@ -387,9 +363,9 @@ progress through successfully, we need to customise what happens at the end of
|
|||||||
the last step.
|
the last step.
|
||||||
|
|
||||||
On the final step, the `finish()` method is called to finalise all the data
|
On the final step, the `finish()` method is called to finalise all the data
|
||||||
from the steps we completed. This method can be found on *MultiForm*. However,
|
from the steps we completed. This method can be found on _MultiForm_. However,
|
||||||
we cannot automatically save each step, because we don't know where to save it.
|
we cannot automatically save each step, because we don't know where to save it.
|
||||||
So, we must write some code on our subclass of *MultiForm*, overloading
|
So, we must write some code on our subclass of _MultiForm_, overloading
|
||||||
`finish()` to tell it what to do at the end.
|
`finish()` to tell it what to do at the end.
|
||||||
|
|
||||||
Here is an example of what we could do here:
|
Here is an example of what we could do here:
|
||||||
@ -467,6 +443,7 @@ class Organisation extends DataObject
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Warning
|
#### Warning
|
||||||
|
|
||||||
If you're dealing with sensitive data, it's best to delete the session and step
|
If you're dealing with sensitive data, it's best to delete the session and step
|
||||||
@ -498,18 +475,18 @@ In order, when you have a page with a multi-form rendering into it, it chooses
|
|||||||
which template to render that form in this order, within the context of the
|
which template to render that form in this order, within the context of the
|
||||||
MultiForm class:
|
MultiForm class:
|
||||||
|
|
||||||
* $this->getCurrentStep()->class (the current step class)
|
- $this->getCurrentStep()->class (the current step class)
|
||||||
* MultiFormStep
|
- MultiFormStep
|
||||||
* $this->class (your subclass of MultiForm)
|
- $this->class (your subclass of MultiForm)
|
||||||
* MultiForm
|
- MultiForm
|
||||||
* Form
|
- Form
|
||||||
|
|
||||||
More than likely, you'll want the first one to be available when the form
|
More than likely, you'll want the first one to be available when the form
|
||||||
renders. To that effect, you can start placing templates in the
|
renders. To that effect, you can start placing templates in the
|
||||||
*templates/Includes* directory for your project. You need to name them the same
|
_templates/Includes_ directory for your project. You need to name them the same
|
||||||
as the class name for each step. For example, if you want *MembershipForm*, a
|
as the class name for each step. For example, if you want _MembershipForm_, a
|
||||||
subclass of *MultiFormStep* to have it's own template, you would put
|
subclass of _MultiFormStep_ to have it's own template, you would put
|
||||||
*MembershipForm.ss* into that directory, and run *?flush=1*.
|
_MembershipForm.ss_ into that directory, and run _?flush=1_.
|
||||||
|
|
||||||
If you'd like a pre-existing template on how to customise the form step, have a
|
If you'd like a pre-existing template on how to customise the form step, have a
|
||||||
look at Form.ss that's found within the framework module. Use that template, as
|
look at Form.ss that's found within the framework module. Use that template, as
|
||||||
@ -542,6 +519,7 @@ class MyStep extends MultiFormStep
|
|||||||
...
|
...
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### Validation
|
### Validation
|
||||||
|
|
||||||
To define validation on a step-by-step basis, please define getValidator() and
|
To define validation on a step-by-step basis, please define getValidator() and
|
||||||
@ -571,10 +549,10 @@ class MyStep extends MultiFormStep
|
|||||||
|
|
||||||
`finish()` is the final call in the process. At this step, all the form data
|
`finish()` is the final call in the process. At this step, all the form data
|
||||||
would most likely be unserialized, and saved to the database in whatever way the
|
would most likely be unserialized, and saved to the database in whatever way the
|
||||||
developer sees fit. By default, we have a `finish()` method on *MultiForm* which
|
developer sees fit. By default, we have a `finish()` method on _MultiForm_ which
|
||||||
serializes the last step form data into the database, and that's it.
|
serializes the last step form data into the database, and that's it.
|
||||||
|
|
||||||
`finish()` should be overloaded onto your subclass of *MultiForm*, and
|
`finish()` should be overloaded onto your subclass of _MultiForm_, and
|
||||||
`parent::finish()` should be called first, otherwise the last step form data
|
`parent::finish()` should be called first, otherwise the last step form data
|
||||||
won't be saved.
|
won't be saved.
|
||||||
|
|
||||||
@ -627,38 +605,39 @@ $this->session->delete();
|
|||||||
|
|
||||||
### Expiring old session data
|
### Expiring old session data
|
||||||
|
|
||||||
Included with the MultiForm module is a class called *MultiFormPurgeTask*. This
|
Included with the MultiForm module is a class called _MultiFormPurgeTask_. This
|
||||||
task can be used to purge expired session data on a regular basis. The date of
|
task can be used to purge expired session data on a regular basis. The date of
|
||||||
expiry can be customised, and is given a default of 7 days to delete sessions
|
expiry can be customised, and is given a default of 7 days to delete sessions
|
||||||
after their creation.
|
after their creation.
|
||||||
|
|
||||||
You can run the task from the URL, by using http://mysite.com/dev/tasks/MultiFormPurgeTask?flush=1
|
You can run the task from the URL, by using http://mysite.com/dev/tasks/MultiFormPurgeTask?flush=1
|
||||||
|
|
||||||
MultiFormPurgeTask is a subclass of *BuildTask*, so can be run using the [SilverStripe CLI tools](http://doc.silverstripe.org/framework/en/topics/commandline).
|
MultiFormPurgeTask is a subclass of _BuildTask_, so can be run using the [SilverStripe CLI tools](http://doc.silverstripe.org/framework/en/topics/commandline).
|
||||||
|
|
||||||
One way of automatically running this on a UNIX based machine is by cron.
|
One way of automatically running this on a UNIX based machine is by cron.
|
||||||
|
|
||||||
## TODO
|
## TODO
|
||||||
|
|
||||||
* Code example on how to use `$form->saveInto()` with MultiForm, as it doesn't have all steps in the $form context at `finish()`
|
- Code example on how to use `$form->saveInto()` with MultiForm, as it doesn't have all steps in the $form context at `finish()`
|
||||||
|
|
||||||
* Allowing a user to click a link, and have an email sent to them with the current state, so they can come back and use the form exactly where they left off
|
- Allowing a user to click a link, and have an email sent to them with the current state, so they can come back and use the form exactly where they left off
|
||||||
|
|
||||||
* Possibly allow for different means to persist data, such as the browser session cache instead of the database.
|
- Possibly allow for different means to persist data, such as the browser session cache instead of the database.
|
||||||
|
|
||||||
* Different presentation of the URL to identify each step.
|
- Different presentation of the URL to identify each step.
|
||||||
|
|
||||||
* Allow customisation of `prev()` and `next()` on each step. Currently you can only customise for the entire MultiForm subclass. There is a way to customise on a per step basis, which could be described in a small recipe.
|
- Allow customisation of `prev()` and `next()` on each step. Currently you can only customise for the entire MultiForm subclass. There is a way to customise on a per step basis, which could be described in a small recipe.
|
||||||
|
|
||||||
* More detailed explanation, and recipe example on how to make branched multistep forms. For example, clicking a different action takes you to an alternative next step than the one defined in `$next_steps`
|
|
||||||
|
|
||||||
|
- More detailed explanation, and recipe example on how to make branched multistep forms. For example, clicking a different action takes you to an alternative next step than the one defined in `$next_steps`
|
||||||
|
|
||||||
## Related
|
## Related
|
||||||
|
|
||||||
* [Form](/form)
|
- [Form](/form)
|
||||||
* [Form field types](http://doc.silverstripe.org/form-field-types)
|
|
||||||
|
|
||||||
* [Tutorials](/tutorials)
|
- [Form field types](http://doc.silverstripe.org/form-field-types)
|
||||||
* [Tutorial 3 - Forms](http://doc.silverstripe.org/framework/en/tutorials/3-forms)
|
|
||||||
|
|
||||||
* [Templates](http://doc.silverstripe.org/framework/en/reference/templates)
|
- [Tutorials](/tutorials)
|
||||||
|
|
||||||
|
- [Tutorial 3 - Forms](http://doc.silverstripe.org/framework/en/tutorials/3-forms)
|
||||||
|
|
||||||
|
- [Templates](http://doc.silverstripe.org/framework/en/reference/templates)
|
||||||
|
@ -1 +0,0 @@
|
|||||||
<?php
|
|
@ -18,16 +18,14 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"require": {
|
"require": {
|
||||||
"silverstripe/framework": "^4"
|
"silverstripe/framework": "^5"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"phpunit/phpunit": "^5.7",
|
"phpunit/phpunit": "^9.6"
|
||||||
"squizlabs/php_codesniffer": "^3.0",
|
|
||||||
"silverstripe/versioned": "^1"
|
|
||||||
},
|
},
|
||||||
"extra": {
|
"extra": {
|
||||||
"branch-alias": {
|
"branch-alias": {
|
||||||
"dev-master": "2.x-dev"
|
"dev-main": "3.x-dev"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"autoload": {
|
"autoload": {
|
||||||
|
@ -1,7 +1,10 @@
|
|||||||
<phpunit bootstrap="vendor/silverstripe/framework/tests/bootstrap.php" colors="true">
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<phpunit bootstrap="vendor/silverstripe/cms/tests/bootstrap.php" colors="true">
|
||||||
|
<testsuites>
|
||||||
<testsuite name="Default">
|
<testsuite name="Default">
|
||||||
<directory>tests/</directory>
|
<directory>tests/</directory>
|
||||||
</testsuite>
|
</testsuite>
|
||||||
|
</testsuites>
|
||||||
<filter>
|
<filter>
|
||||||
<whitelist addUncoveredFilesFromWhitelist="true">
|
<whitelist addUncoveredFilesFromWhitelist="true">
|
||||||
<directory suffix=".php">src/</directory>
|
<directory suffix=".php">src/</directory>
|
||||||
|
@ -44,7 +44,7 @@ class MultiFormTest extends FunctionalTest
|
|||||||
*/
|
*/
|
||||||
protected $form;
|
protected $form;
|
||||||
|
|
||||||
protected function setUp()
|
protected function setUp(): void
|
||||||
{
|
{
|
||||||
parent::setUp();
|
parent::setUp();
|
||||||
|
|
||||||
@ -122,17 +122,17 @@ class MultiFormTest extends FunctionalTest
|
|||||||
Config::modify()->set(MultiForm::class, 'get_var', 'SuperSessionID');
|
Config::modify()->set(MultiForm::class, 'get_var', 'SuperSessionID');
|
||||||
|
|
||||||
$form = $this->controller->Form();
|
$form = $this->controller->Form();
|
||||||
$this->assertContains(
|
$this->assertStringContainsString(
|
||||||
'SuperSessionID',
|
'SuperSessionID',
|
||||||
$form->config()->get('ignored_fields'),
|
$form->config()->get('ignored_fields'),
|
||||||
'GET var wasn\'t added to ignored fields'
|
'GET var wasn\'t added to ignored fields'
|
||||||
);
|
);
|
||||||
$this->assertContains(
|
$this->assertStringContainsString(
|
||||||
'SuperSessionID',
|
'SuperSessionID',
|
||||||
$form->FormAction(),
|
$form->FormAction(),
|
||||||
"Form action doesn't contain correct session ID parameter"
|
"Form action doesn't contain correct session ID parameter"
|
||||||
);
|
);
|
||||||
$this->assertContains(
|
$this->assertStringContainsString(
|
||||||
'SuperSessionID',
|
'SuperSessionID',
|
||||||
$form->getCurrentStep()->Link(),
|
$form->getCurrentStep()->Link(),
|
||||||
"Form step doesn't contain correct session ID parameter"
|
"Form step doesn't contain correct session ID parameter"
|
||||||
|
Loading…
Reference in New Issue
Block a user