mirror of
https://github.com/silverstripe/silverstripe-multiform
synced 2024-10-22 11:05:49 +02:00
Merge pull request #65 from creative-commoners/pulls/2.0/further-ss4-updates
Regression testing fixes and docs updates
This commit is contained in:
commit
adda533de7
165
README.md
165
README.md
@ -94,6 +94,8 @@ 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\Models\MultiForm;
|
||||||
|
|
||||||
class SurveyForm extends MultiForm {
|
class SurveyForm extends MultiForm {
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -112,7 +114,10 @@ So, for example, if we were going to have a first step which collects the
|
|||||||
personal details of the form user, then we might have this class:
|
personal details of the form user, then we might have this class:
|
||||||
|
|
||||||
```php
|
```php
|
||||||
class SurveyFormPersonalDetailsStep extends MultiFormStep {
|
use SilverStripe\MultiForm\Models\MultiFormStep;
|
||||||
|
|
||||||
|
class PersonalDetailsStep extends MultiFormStep
|
||||||
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
@ -122,10 +127,11 @@ subclass of MultiForm, SurveyForm, and tell it that SurveyFormPersonalDetailsSte
|
|||||||
is the first step.
|
is the first step.
|
||||||
|
|
||||||
```php
|
```php
|
||||||
class SurveyForm extends MultiForm {
|
use SilverStripe\MultiForm\Models\MultiForm;
|
||||||
|
|
||||||
private static $start_step = 'SurveyFormPersonalDetailsStep';
|
|
||||||
|
|
||||||
|
class SurveyForm extends MultiForm
|
||||||
|
{
|
||||||
|
private static $start_step = PersonalDetailsStep::class;
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -141,17 +147,21 @@ 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
|
||||||
class SurveyFormPersonalDetailsStep extends MultiFormStep {
|
use SilverStripe\MultiForm\Models\MultiFormStep;
|
||||||
|
use SilverStripe\Forms\FieldList;
|
||||||
|
use SilverStripe\Forms\TextField;
|
||||||
|
|
||||||
private static $next_steps = 'SurveyFormOrganisationDetailsStep';
|
class PersonalDetailsStep extends MultiFormStep
|
||||||
|
{
|
||||||
|
private static $next_steps = OrganisationDetailsStep::class;
|
||||||
|
|
||||||
public function getFields() {
|
public function getFields()
|
||||||
return new FieldList(
|
{
|
||||||
new TextField('FirstName', 'First name'),
|
return FieldList::create(
|
||||||
new TextField('Surname', 'Surname')
|
TextField::create('FirstName', 'First name'),
|
||||||
|
TextField::create('Surname', 'Surname')
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -167,17 +177,18 @@ So, if we assume that the last step in our process is
|
|||||||
SurveyFormOrganisationDetailsStep, then we can do something like this:
|
SurveyFormOrganisationDetailsStep, then we can do something like this:
|
||||||
|
|
||||||
```php
|
```php
|
||||||
class SurveyFormOrganisationDetailsStep extends MultiFormStep {
|
use SilverStripe\MultiForm\Models\MultiFormStep;
|
||||||
|
|
||||||
|
class OrganisationDetailsStep extends MultiFormStep
|
||||||
|
{
|
||||||
private static $is_final_step = true;
|
private static $is_final_step = true;
|
||||||
|
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### 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 scratch
|
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
|
||||||
@ -190,35 +201,27 @@ 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
|
||||||
class Page extends SiteTree {
|
use SilverStripe\CMS\Controllers\ContentController;
|
||||||
|
|
||||||
// ...
|
class PageController extends ContentController
|
||||||
|
{
|
||||||
}
|
private static $allowed_actions = [
|
||||||
|
|
||||||
class Page_Controller extends ContentController {
|
|
||||||
|
|
||||||
// ...
|
|
||||||
|
|
||||||
//
|
|
||||||
private static $allowed_actions = array(
|
|
||||||
'SurveyForm',
|
'SurveyForm',
|
||||||
'finished'
|
'finished'
|
||||||
);
|
];
|
||||||
|
|
||||||
public function SurveyForm() {
|
public function SurveyForm()
|
||||||
return new SurveyForm($this, 'Form');
|
{
|
||||||
|
return SurveyForm::create($this, 'SurveyForm');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function finished() {
|
public function finished()
|
||||||
return array(
|
{
|
||||||
|
return [
|
||||||
'Title' => 'Thank you for your submission',
|
'Title' => 'Thank you for your submission',
|
||||||
'Content' => '<p>You have successfully submitted the form!</p>'
|
'Content' => '<p>You have successfully submitted the form!</p>'
|
||||||
);
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
// ...
|
|
||||||
|
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -334,25 +337,37 @@ based on the submission value of another step. There are two methods supporting
|
|||||||
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 :
|
||||||
|
|
||||||
```php
|
```php
|
||||||
|
use SilverStripe\MultiForm\Models\MultiFormStep;
|
||||||
|
use SilverStripe\Forms\FieldList;
|
||||||
|
use SilverStripe\Forms\EmailField;
|
||||||
|
|
||||||
class Step1 extends MultiFormStep
|
class Step1 extends MultiFormStep
|
||||||
{
|
{
|
||||||
private static $next_steps = 'Step2';
|
private static $next_steps = Step2::class;
|
||||||
|
|
||||||
public function getFields() {
|
public function getFields()
|
||||||
return new FieldList(
|
{
|
||||||
new EmailField('Email', 'Your email')
|
return FieldList::create(
|
||||||
|
EmailField::create('Email', 'Your email')
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
```php
|
||||||
|
use SilverStripe\MultiForm\Models\MultiFormStep;
|
||||||
|
use SilverStripe\Forms\FieldList;
|
||||||
|
use SilverStripe\Forms\EmailField;
|
||||||
|
|
||||||
class Step2 extends MultiFormStep
|
class Step2 extends MultiFormStep
|
||||||
{
|
{
|
||||||
private static $next_steps = 'Step3';
|
private static $next_steps = Step3::class;
|
||||||
|
|
||||||
public function getFields() {
|
public function getFields()
|
||||||
$fields = new FieldList(
|
{
|
||||||
new EmailField('Email', 'E-mail'),
|
$fields = FieldList::create(
|
||||||
new EmailField('Email2', 'Verify E-Mail')
|
EmailField::create('Email', 'E-mail'),
|
||||||
|
EmailField::create('Email2', 'Verify E-Mail')
|
||||||
);
|
);
|
||||||
|
|
||||||
// set the email field to the input from Step 1
|
// set the email field to the input from Step 1
|
||||||
@ -378,11 +393,16 @@ So, we must write some code on our subclass of *MultiForm*, overloading
|
|||||||
Here is an example of what we could do here:
|
Here is an example of what we could do here:
|
||||||
|
|
||||||
```php
|
```php
|
||||||
class SurveyForm extends MultiForm {
|
use SilverStripe\MultiForm\Models\MultiForm;
|
||||||
|
use SilverStripe\Forms\FieldList;
|
||||||
|
use SilverStripe\Forms\EmailField;
|
||||||
|
|
||||||
private static $start_step = 'SurveyFormPersonalDetailsStep';
|
class SurveyForm extends MultiForm
|
||||||
|
{
|
||||||
|
private static $start_step = PersonalDetailsStep::class;
|
||||||
|
|
||||||
public function finish($data, $form) {
|
public function finish($data, $form)
|
||||||
|
{
|
||||||
parent::finish($data, $form);
|
parent::finish($data, $form);
|
||||||
|
|
||||||
$steps = DataObject::get(
|
$steps = DataObject::get(
|
||||||
@ -392,8 +412,8 @@ class SurveyForm extends MultiForm {
|
|||||||
|
|
||||||
if($steps) {
|
if($steps) {
|
||||||
foreach($steps as $step) {
|
foreach($steps as $step) {
|
||||||
if($step->class == 'SurveyFormPersonalDetailsStep') {
|
if($step->class == PersonalDetailsStep::class) {
|
||||||
$member = new Member();
|
$member = Member::create();
|
||||||
$data = $step->loadData();
|
$data = $step->loadData();
|
||||||
|
|
||||||
if($data) {
|
if($data) {
|
||||||
@ -402,8 +422,8 @@ class SurveyForm extends MultiForm {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if($step->class == 'SurveyOrganisationDetailsStep') {
|
if($step->class == OrganisationDetailsStep::class) {
|
||||||
$organisation = new Organisation();
|
$organisation = Organisation::create();
|
||||||
$data = $step->loadData();
|
$data = $step->loadData();
|
||||||
|
|
||||||
if($data) {
|
if($data) {
|
||||||
@ -436,8 +456,10 @@ This example has been chosen as a separate DataObject but you may wish to change
|
|||||||
the code and add the data to the Member class instead.
|
the code and add the data to the Member class instead.
|
||||||
|
|
||||||
```php
|
```php
|
||||||
class Organisation extends DataObject {
|
use SilverStripe\ORM\DataObject;
|
||||||
|
|
||||||
|
class Organisation extends DataObject
|
||||||
|
{
|
||||||
private static $db = array(
|
private static $db = array(
|
||||||
// Add your Organisation fields here
|
// Add your Organisation fields here
|
||||||
);
|
);
|
||||||
@ -502,20 +524,20 @@ step should be. An example:
|
|||||||
|
|
||||||
```php
|
```php
|
||||||
class MyStep extends MultiFormStep
|
class MyStep extends MultiFormStep
|
||||||
|
{
|
||||||
|
...
|
||||||
|
|
||||||
// ...
|
public function getNextStep()
|
||||||
|
{
|
||||||
public function getNextStep() {
|
|
||||||
$data = $this->loadData();
|
$data = $this->loadData();
|
||||||
if(@$data['Gender'] == 'Male') {
|
if($data['Gender'] == 'Male') {
|
||||||
return 'TestThirdCase1Step';
|
return TestThirdCase1Step::class;
|
||||||
} else {
|
} else {
|
||||||
return 'TestThirdCase2Step';
|
return TestThirdCase2Step::class;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ...
|
...
|
||||||
|
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
### Validation
|
### Validation
|
||||||
@ -527,19 +549,19 @@ validation see [:form](http://doc.silverstripe.org/form-validation).
|
|||||||
e.g.
|
e.g.
|
||||||
|
|
||||||
```php
|
```php
|
||||||
class MyStep extends MultiFormStep {
|
class MyStep extends MultiFormStep
|
||||||
|
{
|
||||||
...
|
...
|
||||||
|
|
||||||
public function getValidator() {
|
public function getValidator()
|
||||||
return new RequiredFields(array(
|
{
|
||||||
|
return RequiredFields::create(array(
|
||||||
'Name',
|
'Name',
|
||||||
'Email'
|
'Email'
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
...
|
...
|
||||||
|
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -557,16 +579,19 @@ won't be saved.
|
|||||||
For example:
|
For example:
|
||||||
|
|
||||||
```php
|
```php
|
||||||
class SurveyForm extends MultiForm {
|
use SilverStripe\Dev\Debug;
|
||||||
|
use SilverStripe\MultiForm\Models\MultiForm;
|
||||||
|
use SilverStripe\MultiForm\Models\MultiFormStep;
|
||||||
|
|
||||||
private static $start_step = 'SurveyFormPersonalDetailsStep';
|
class SurveyForm extends MultiForm
|
||||||
|
{
|
||||||
|
private static $start_step = PersonalDetailsStep::class;
|
||||||
|
|
||||||
public function finish($data, $form) {
|
public function finish($data, $form)
|
||||||
|
{
|
||||||
parent::finish($data, $form);
|
parent::finish($data, $form);
|
||||||
|
|
||||||
$steps = MultiFormStep::get()->filter(array(
|
$steps = MultiFormStep::get()->filter(['SessionID' => $this->session->ID]);
|
||||||
"SessionID" => $this->session->ID
|
|
||||||
));
|
|
||||||
|
|
||||||
if($steps) {
|
if($steps) {
|
||||||
foreach($steps as $step) {
|
foreach($steps as $step) {
|
||||||
|
@ -180,7 +180,7 @@ abstract class MultiForm extends Form
|
|||||||
// Disable security token - we tie a form to a session ID instead
|
// Disable security token - we tie a form to a session ID instead
|
||||||
$this->disableSecurityToken();
|
$this->disableSecurityToken();
|
||||||
|
|
||||||
$this->config()->merge('ignored_fields', $getVar);
|
$this->config()->merge('ignored_fields', [$getVar]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -220,7 +220,7 @@ abstract class MultiForm extends Form
|
|||||||
// Check if there was a start step defined on the subclass of MultiForm
|
// Check if there was a start step defined on the subclass of MultiForm
|
||||||
if (!isset($startStepClass)) {
|
if (!isset($startStepClass)) {
|
||||||
user_error(
|
user_error(
|
||||||
'MultiForm::init(): Please define a $start_step on ' . $this->class,
|
'MultiForm::init(): Please define a $start_step on ' . static::class,
|
||||||
E_USER_ERROR
|
E_USER_ERROR
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -302,13 +302,9 @@ abstract class MultiForm extends Form
|
|||||||
|
|
||||||
// If there was no session found, create a new one instead
|
// If there was no session found, create a new one instead
|
||||||
if (!$this->session) {
|
if (!$this->session) {
|
||||||
$this->session = MultiFormSession::create();
|
$session = MultiFormSession::create();
|
||||||
}
|
$session->write();
|
||||||
|
$this->session = $session;
|
||||||
// Create encrypted identification to the session instance if it doesn't exist
|
|
||||||
if (!$this->session->Hash) {
|
|
||||||
$this->session->Hash = sha1($this->session->ID . '-' . microtime());
|
|
||||||
$this->session->write();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -433,30 +429,6 @@ abstract class MultiForm extends Form
|
|||||||
return $actions;
|
return $actions;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Return a rendered version of this form, with a specific template.
|
|
||||||
* Looks through the step ancestory templates (MultiFormStep, current step
|
|
||||||
* subclass template) to see if one is available to render the form with. If
|
|
||||||
* any of those don't exist, look for a default Form template to render
|
|
||||||
* with instead.
|
|
||||||
*
|
|
||||||
* @return SSViewer object to render the template with
|
|
||||||
*/
|
|
||||||
public function forTemplate()
|
|
||||||
{
|
|
||||||
$return = $this->renderWith([
|
|
||||||
$this->getCurrentStep()->class,
|
|
||||||
'MultiFormStep',
|
|
||||||
$this->class,
|
|
||||||
'MultiForm',
|
|
||||||
'Form'
|
|
||||||
]);
|
|
||||||
|
|
||||||
$this->clearMessage();
|
|
||||||
|
|
||||||
return $return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method saves the data on the final step, after submitting.
|
* This method saves the data on the final step, after submitting.
|
||||||
* It should always be overloaded with parent::finish($data, $form)
|
* It should always be overloaded with parent::finish($data, $form)
|
||||||
|
@ -78,4 +78,14 @@ class MultiFormSession extends DataObject
|
|||||||
|
|
||||||
parent::onBeforeDelete();
|
parent::onBeforeDelete();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function onAfterWrite()
|
||||||
|
{
|
||||||
|
parent::onAfterWrite();
|
||||||
|
// Create encrypted identification to the session instance if it doesn't exist
|
||||||
|
if (!$this->Hash) {
|
||||||
|
$this->Hash = sha1($this->ID . '-' . microtime());
|
||||||
|
$this->write();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -63,7 +63,7 @@ class MultiFormStep extends DataObject
|
|||||||
*
|
*
|
||||||
* @var boolean
|
* @var boolean
|
||||||
*/
|
*/
|
||||||
protected static $can_go_back = true;
|
private static $can_go_back = true;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Title of this step.
|
* Title of this step.
|
||||||
@ -249,7 +249,7 @@ class MultiFormStep extends DataObject
|
|||||||
if (!isset($nextSteps)) {
|
if (!isset($nextSteps)) {
|
||||||
user_error(
|
user_error(
|
||||||
'MultiFormStep->getNextStep(): Please define at least one $next_steps on '
|
'MultiFormStep->getNextStep(): Please define at least one $next_steps on '
|
||||||
. $this->class,
|
. static::class,
|
||||||
E_USER_ERROR
|
E_USER_ERROR
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -314,8 +314,8 @@ class MultiFormStep extends DataObject
|
|||||||
$step->setForm($this->form);
|
$step->setForm($this->form);
|
||||||
|
|
||||||
if ($step->getNextStep()) {
|
if ($step->getNextStep()) {
|
||||||
if ($step->getNextStep() == $this->class) {
|
if ($step->getNextStep() == static::class) {
|
||||||
return $step->class;
|
return get_class($step);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -417,7 +417,7 @@ class MultiFormStep extends DataObject
|
|||||||
*/
|
*/
|
||||||
public function isCurrentStep()
|
public function isCurrentStep()
|
||||||
{
|
{
|
||||||
return ($this->class == $this->getSession()->CurrentStep()->class) ? true : false;
|
return (static::class == get_class($this->getSession()->CurrentStep())) ? true : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
<% if $LinkingMode = current %>
|
<% if $LinkingMode = current %>
|
||||||
<% else %>
|
<% else %>
|
||||||
<% if $ID %>
|
<% if $ID %>
|
||||||
<a href="{$Top.URLSegment}/?${Top.GetVar}={$SessionID}&StepID={$ID}">
|
<a href="{$Top.URLSegment}/?{$Top.GetVar}={$Session.Hash}&StepID={$ID}">
|
||||||
<% end_if %>
|
<% end_if %>
|
||||||
<% end_if %>
|
<% end_if %>
|
||||||
|
|
||||||
|
@ -1 +1 @@
|
|||||||
<p><%t SilverStripe\\MultiForm\\MultiForm.ProgressPercent "You've completed {percent}% ({completedSteps}/{totalSteps})" percent=$CompletedPercent.Nice completedSteps=$CompletedStepCount totalSteps$TotalStepCount %></p>
|
<p><%t SilverStripe\\MultiForm\\MultiForm.ProgressPercent "You've completed {percent}% ({completedSteps}/{totalSteps})" percent=$CompletedPercent.Nice completedSteps=$CompletedStepCount totalSteps=$TotalStepCount %></p>
|
||||||
|
@ -93,7 +93,7 @@ class MultiFormTest extends FunctionalTest
|
|||||||
public function testParentForm()
|
public function testParentForm()
|
||||||
{
|
{
|
||||||
$currentStep = $this->form->getCurrentStep();
|
$currentStep = $this->form->getCurrentStep();
|
||||||
$this->assertEquals($currentStep->getForm()->class, $this->form->class);
|
$this->assertEquals(get_class($currentStep->getForm()), get_class($this->form));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testTotalStepCount()
|
public function testTotalStepCount()
|
||||||
|
Loading…
Reference in New Issue
Block a user