Merge pull request #65 from creative-commoners/pulls/2.0/further-ss4-updates

Regression testing fixes and docs updates
This commit is contained in:
Will Rossiter 2017-09-12 09:57:41 +12:00 committed by GitHub
commit adda533de7
7 changed files with 121 additions and 114 deletions

171
README.md
View File

@ -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*
```php
use SilverStripe\MultiForm\Models\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:
```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.
```php
class SurveyForm extends MultiForm {
private static $start_step = 'SurveyFormPersonalDetailsStep';
use SilverStripe\MultiForm\Models\MultiForm;
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`.
```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() {
return new FieldList(
new TextField('FirstName', 'First name'),
new TextField('Surname', 'Surname')
public function getFields()
{
return FieldList::create(
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:
```php
class SurveyFormOrganisationDetailsStep extends MultiFormStep {
use SilverStripe\MultiForm\Models\MultiFormStep;
class OrganisationDetailsStep extends MultiFormStep
{
private static $is_final_step = true;
}
```
### 5. Run database integrity check
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.
*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:
```php
class Page extends SiteTree {
use SilverStripe\CMS\Controllers\ContentController;
// ...
}
class Page_Controller extends ContentController {
// ...
//
private static $allowed_actions = array(
class PageController extends ContentController
{
private static $allowed_actions = [
'SurveyForm',
'finished'
);
];
public function SurveyForm() {
return new SurveyForm($this, 'Form');
public function SurveyForm()
{
return SurveyForm::create($this, 'SurveyForm');
}
public function finished() {
return array(
public function finished()
{
return [
'Title' => 'Thank you for your submission',
'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 :
```php
use SilverStripe\MultiForm\Models\MultiFormStep;
use SilverStripe\Forms\FieldList;
use SilverStripe\Forms\EmailField;
class Step1 extends MultiFormStep
{
private static $next_steps = 'Step2';
private static $next_steps = Step2::class;
public function getFields() {
return new FieldList(
new EmailField('Email', 'Your email')
public function getFields()
{
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
{
private static $next_steps = 'Step3';
private static $next_steps = Step3::class;
public function getFields() {
$fields = new FieldList(
new EmailField('Email', 'E-mail'),
new EmailField('Email2', 'Verify E-Mail')
public function getFields()
{
$fields = FieldList::create(
EmailField::create('Email', 'E-mail'),
EmailField::create('Email2', 'Verify E-Mail')
);
// 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:
```php
class SurveyForm extends MultiForm {
use SilverStripe\MultiForm\Models\MultiForm;
use SilverStripe\Forms\FieldList;
use SilverStripe\Forms\EmailField;
class SurveyForm extends MultiForm
{
private static $start_step = PersonalDetailsStep::class;
private static $start_step = 'SurveyFormPersonalDetailsStep';
public function finish($data, $form) {
public function finish($data, $form)
{
parent::finish($data, $form);
$steps = DataObject::get(
@ -392,8 +412,8 @@ class SurveyForm extends MultiForm {
if($steps) {
foreach($steps as $step) {
if($step->class == 'SurveyFormPersonalDetailsStep') {
$member = new Member();
if($step->class == PersonalDetailsStep::class) {
$member = Member::create();
$data = $step->loadData();
if($data) {
@ -402,8 +422,8 @@ class SurveyForm extends MultiForm {
}
}
if($step->class == 'SurveyOrganisationDetailsStep') {
$organisation = new Organisation();
if($step->class == OrganisationDetailsStep::class) {
$organisation = Organisation::create();
$data = $step->loadData();
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.
```php
class Organisation extends DataObject {
use SilverStripe\ORM\DataObject;
class Organisation extends DataObject
{
private static $db = array(
// Add your Organisation fields here
);
@ -502,20 +524,20 @@ step should be. An example:
```php
class MyStep extends MultiFormStep
{
...
// ...
public function getNextStep() {
public function getNextStep()
{
$data = $this->loadData();
if(@$data['Gender'] == 'Male') {
return 'TestThirdCase1Step';
if($data['Gender'] == 'Male') {
return TestThirdCase1Step::class;
} else {
return 'TestThirdCase2Step';
return TestThirdCase2Step::class;
}
}
// ...
...
}
```
### Validation
@ -527,19 +549,19 @@ validation see [:form](http://doc.silverstripe.org/form-validation).
e.g.
```php
class MyStep extends MultiFormStep {
class MyStep extends MultiFormStep
{
...
public function getValidator() {
return new RequiredFields(array(
public function getValidator()
{
return RequiredFields::create(array(
'Name',
'Email'
));
}
...
}
```
@ -557,16 +579,19 @@ won't be saved.
For example:
```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);
$steps = MultiFormStep::get()->filter(array(
"SessionID" => $this->session->ID
));
$steps = MultiFormStep::get()->filter(['SessionID' => $this->session->ID]);
if($steps) {
foreach($steps as $step) {

View File

@ -180,7 +180,7 @@ abstract class MultiForm extends Form
// Disable security token - we tie a form to a session ID instead
$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
if (!isset($startStepClass)) {
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
);
}
@ -302,13 +302,9 @@ abstract class MultiForm extends Form
// If there was no session found, create a new one instead
if (!$this->session) {
$this->session = MultiFormSession::create();
}
// 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();
$session = MultiFormSession::create();
$session->write();
$this->session = $session;
}
}
@ -433,30 +429,6 @@ abstract class MultiForm extends Form
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.
* It should always be overloaded with parent::finish($data, $form)

View File

@ -78,4 +78,14 @@ class MultiFormSession extends DataObject
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();
}
}
}

View File

@ -63,7 +63,7 @@ class MultiFormStep extends DataObject
*
* @var boolean
*/
protected static $can_go_back = true;
private static $can_go_back = true;
/**
* Title of this step.
@ -249,7 +249,7 @@ class MultiFormStep extends DataObject
if (!isset($nextSteps)) {
user_error(
'MultiFormStep->getNextStep(): Please define at least one $next_steps on '
. $this->class,
. static::class,
E_USER_ERROR
);
}
@ -314,8 +314,8 @@ class MultiFormStep extends DataObject
$step->setForm($this->form);
if ($step->getNextStep()) {
if ($step->getNextStep() == $this->class) {
return $step->class;
if ($step->getNextStep() == static::class) {
return get_class($step);
}
}
}
@ -417,7 +417,7 @@ class MultiFormStep extends DataObject
*/
public function isCurrentStep()
{
return ($this->class == $this->getSession()->CurrentStep()->class) ? true : false;
return (static::class == get_class($this->getSession()->CurrentStep())) ? true : false;
}
/**

View File

@ -4,7 +4,7 @@
<% if $LinkingMode = current %>
<% else %>
<% if $ID %>
<a href="{$Top.URLSegment}/?${Top.GetVar}={$SessionID}&amp;StepID={$ID}">
<a href="{$Top.URLSegment}/?{$Top.GetVar}={$Session.Hash}&amp;StepID={$ID}">
<% end_if %>
<% end_if %>

View File

@ -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>

View File

@ -93,7 +93,7 @@ class MultiFormTest extends FunctionalTest
public function testParentForm()
{
$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()