Namespace changes and some more linting fixes

This commit is contained in:
Franco Springveldt 2017-09-07 11:32:55 +12:00
parent a3a9725d60
commit b739e6cc5f
24 changed files with 352 additions and 241 deletions

14
.upgrade.yml Normal file
View File

@ -0,0 +1,14 @@
mappings:
MultiFormObjectDecorator: SilverStripe\MultiForm\MultiFormObjectDecorator
MultiForm: SilverStripe\MultiForm\MultiForm
MultiFormSession: SilverStripe\MultiForm\MultiFormSession
MultiFormStep: SilverStripe\MultiForm\MultiFormStep
MultiFormPurgeTask: SilverStripe\MultiForm\MultiFormPurgeTask
MultiFormObjectDecoratorTest: SilverStripe\MultiForm\MultiFormObjectDecoratorTest
MultiFormObjectDecorator_DataObject: SilverStripe\MultiForm\MultiFormObjectDecorator_DataObject
MultiFormTest: SilverStripe\MultiForm\MultiFormTest
MultiFormTest_Controller: SilverStripe\MultiForm\MultiFormTest_Controller
MultiFormTest_Form: SilverStripe\MultiForm\MultiFormTest_Form
MultiFormTest_StepOne: SilverStripe\MultiForm\MultiFormTest_StepOne
MultiFormTest_StepTwo: SilverStripe\MultiForm\MultiFormTest_StepTwo
MultiFormTest_StepThree: SilverStripe\MultiForm\MultiFormTest_StepThree

3
_config/config.yml Normal file
View File

@ -0,0 +1,3 @@
---
Name: multisiteconfig
---

6
_config/legacy.yml Normal file
View File

@ -0,0 +1,6 @@
---
Name: multisitelegacy
---
SilverStripe\ORM\DatabaseAdmin:
classname_value_remapping:
MultiFormSession: SilverStripe\MultiForm\Model\MultiFormSession

1
codecov.yml Normal file
View File

@ -0,0 +1 @@
comment: false

View File

@ -1,4 +1,4 @@
Copyright (c) 2016, SilverStripe Limited Copyright (c) 2017, SilverStripe Limited
All rights reserved. All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

View File

@ -1,5 +1,21 @@
<?php <?php
namespace SilverStripe\MultiForm\Models;
use SilverStripe\Control\Controller;
use SilverStripe\Control\HTTPResponse;
use SilverStripe\Control\Session;
use SilverStripe\Core\Convert;
use SilverStripe\Core\Injector\Injector;
use SilverStripe\Forms\FieldList;
use SilverStripe\Forms\Form;
use SilverStripe\Forms\FormAction;
use SilverStripe\Forms\HiddenField;
use SilverStripe\ORM\ArrayList;
use SilverStripe\ORM\DataList;
use SilverStripe\ORM\DataObject;
use SilverStripe\View\SSViewer;
/** /**
* MultiForm manages the loading of single form steps, and acts as a state * MultiForm manages the loading of single form steps, and acts as a state
* machine that connects to a {@link MultiFormSession} object as a persistence * machine that connects to a {@link MultiFormSession} object as a persistence
@ -16,7 +32,6 @@
*/ */
abstract class MultiForm extends Form abstract class MultiForm extends Form
{ {
/** /**
* A session object stored in the database, to identify and store * A session object stored in the database, to identify and store
* data for this MultiForm instance. * data for this MultiForm instance.
@ -45,11 +60,11 @@ abstract class MultiForm extends Form
* *
* @var array * @var array
*/ */
private static $casting = array( private static $casting = [
'CompletedStepCount' => 'Int', 'CompletedStepCount' => 'Int',
'TotalStepCount' => 'Int', 'TotalStepCount' => 'Int',
'CompletedPercent' => 'Float' 'CompletedPercent' => 'Float'
); ];
/** /**
* @var string * @var string
@ -63,11 +78,11 @@ abstract class MultiForm extends Form
* *
* @var array * @var array
*/ */
public static $ignored_fields = array( public static $ignored_fields = [
'url', 'url',
'executeForm', 'executeForm',
'SecurityID' 'SecurityID'
); ];
/** /**
* Any of the actions defined in this variable are exempt from * Any of the actions defined in this variable are exempt from
@ -79,9 +94,9 @@ abstract class MultiForm extends Form
* *
* @var array * @var array
*/ */
public static $actions_exempt_from_validation = array( public static $actions_exempt_from_validation = [
'action_prev' 'action_prev'
); ];
/** /**
* @var string * @var string
@ -98,7 +113,7 @@ abstract class MultiForm extends Form
/** /**
* Start the MultiForm instance. * Start the MultiForm instance.
* *
* @param Controller instance $controller Controller this form is created on * @param Controller $controller Controller instance this form is created on
* @param string $name The form name, typically the same as the method name * @param string $name The form name, typically the same as the method name
*/ */
public function __construct($controller, $name) public function __construct($controller, $name)
@ -155,7 +170,7 @@ abstract class MultiForm extends Form
$getVar = $this->config()->get_var; $getVar = $this->config()->get_var;
// Set a hidden field in our form with an encrypted hash to identify this session. // Set a hidden field in our form with an encrypted hash to identify this session.
$this->fields->push(new HiddenField($getVar, false, $this->session->Hash)); $this->fields->push(HiddenField::create($getVar, false, $this->session->Hash));
// If there is saved data for the current step, we load it into the form it here // If there is saved data for the current step, we load it into the form it here
//(CAUTION: loadData() MUST unserialize first!) //(CAUTION: loadData() MUST unserialize first!)
@ -213,14 +228,14 @@ abstract class MultiForm extends Form
// Determine whether we use the current step, or create one if it doesn't exist // Determine whether we use the current step, or create one if it doesn't exist
$currentStep = null; $currentStep = null;
$StepID = $this->controller->request->getVar('StepID'); $StepID = $this->controller->getRequest()->getVar('StepID');
if (isset($StepID)) { if (isset($StepID)) {
$currentStep = DataObject::get_one( $currentStep = DataObject::get_one(
'MultiFormStep', 'MultiFormStep',
array( [
'SessionID' => $this->session->ID, 'SessionID' => $this->session->ID,
'ID' => $StepID 'ID' => $StepID
) ]
); );
} elseif ($this->session->CurrentStepID) { } elseif ($this->session->CurrentStepID) {
$currentStep = $this->session->CurrentStep(); $currentStep = $this->session->CurrentStep();
@ -228,7 +243,7 @@ abstract class MultiForm extends Form
// Always fall back to creating a new step (in case the session or request data is invalid) // Always fall back to creating a new step (in case the session or request data is invalid)
if (!$currentStep || !$currentStep->ID) { if (!$currentStep || !$currentStep->ID) {
$currentStep = Object::create($startStepClass); $currentStep = Injector::inst()->create($startStepClass);
$currentStep->SessionID = $this->session->ID; $currentStep->SessionID = $this->session->ID;
$currentStep->write(); $currentStep->write();
$this->session->CurrentStepID = $currentStep->ID; $this->session->CurrentStepID = $currentStep->ID;
@ -314,17 +329,17 @@ abstract class MultiForm extends Form
public function getCurrentSession() public function getCurrentSession()
{ {
if (!$this->currentSessionHash) { if (!$this->currentSessionHash) {
$this->currentSessionHash = $this->controller->request->getVar($this->config()->get_var); $this->currentSessionHash = $this->controller->getRequest()->getVar($this->config()->get_var);
if (!$this->currentSessionHash) { if (!$this->currentSessionHash) {
return false; return false;
} }
} }
$this->session = MultiFormSession::get()->filter(array( $this->session = MultiFormSession::get()->filter([
"Hash" => $this->currentSessionHash, "Hash" => $this->currentSessionHash,
"IsComplete" => 0 "IsComplete" => 0
))->first(); ])->first();
return $this->session; return $this->session;
} }
@ -336,7 +351,7 @@ abstract class MultiForm extends Form
* to the database, use {@link getAllStepsLinear()}. * to the database, use {@link getAllStepsLinear()}.
* *
* @param string $filter SQL WHERE statement * @param string $filter SQL WHERE statement
* @return DataObjectSet|boolean A set of MultiFormStep subclasses * @return DataList|boolean A set of MultiFormStep subclasses
*/ */
public function getSavedSteps($filter = null) public function getSavedSteps($filter = null)
{ {
@ -351,7 +366,7 @@ abstract class MultiForm extends Form
* in your chain with the same classname. * in your chain with the same classname.
* *
* @param string $className Classname of a {@link MultiFormStep} subclass * @param string $className Classname of a {@link MultiFormStep} subclass
* @return MultiFormStep * @return DataObject
*/ */
public function getSavedStepByClass($className) public function getSavedStepByClass($className)
{ {
@ -381,30 +396,30 @@ abstract class MultiForm extends Form
* then that set of actions is appended to the end of the actions FieldSet we * then that set of actions is appended to the end of the actions FieldSet we
* have created in this method. * have created in this method.
* *
* @param $currentStep Subclass of MultiFormStep * @param MultiFormStep $step Subclass of MultiFormStep
* @return FieldList of FormAction objects * @return FieldList of FormAction objects
*/ */
public function actionsFor($step) public function actionsFor($step)
{ {
// Create default multi step actions (next, prev), and merge with extra actions, if any // Create default multi step actions (next, prev), and merge with extra actions, if any
$actions = (class_exists('FieldList')) ? new FieldList() : new FieldSet(); $actions = FieldList::create();
// If the form is at final step, create a submit button to perform final actions // If the form is at final step, create a submit button to perform final actions
// The last step doesn't have a next button, so add that action to any step that isn't the final one // The last step doesn't have a next button, so add that action to any step that isn't the final one
if ($step->isFinalStep()) { if ($step->isFinalStep()) {
$actions->push(new FormAction('finish', $step->getSubmitText())); $actions->push(FormAction::create('finish', $step->getSubmitText()));
} else { } else {
$actions->push(new FormAction('next', $step->getNextText())); $actions->push(FormAction::create('next', $step->getNextText()));
} }
// If there is a previous step defined, add the back button // If there is a previous step defined, add the back button
if ($step->getPreviousStep() && $step->canGoBack()) { if ($step->getPreviousStep() && $step->canGoBack()) {
// If there is a next step, insert the action before the next action // If there is a next step, insert the action before the next action
if ($step->getNextStep()) { if ($step->getNextStep()) {
$actions->insertBefore($prev = new FormAction('prev', $step->getPrevText()), 'action_next'); $actions->insertBefore($prev = FormAction::create('prev', $step->getPrevText()), 'action_next');
// Assume that this is the last step, insert the action before the finish action // Assume that this is the last step, insert the action before the finish action
} else { } else {
$actions->insertBefore($prev = new FormAction('prev', $step->getPrevText()), 'action_finish'); $actions->insertBefore($prev = FormAction::create('prev', $step->getPrevText()), 'action_finish');
} }
//remove browser validation from prev action //remove browser validation from prev action
$prev->setAttribute("formnovalidate", "formnovalidate"); $prev->setAttribute("formnovalidate", "formnovalidate");
@ -427,13 +442,13 @@ abstract class MultiForm extends Form
*/ */
public function forTemplate() public function forTemplate()
{ {
$return = $this->renderWith(array( $return = $this->renderWith([
$this->getCurrentStep()->class, $this->getCurrentStep()->class,
'MultiFormStep', 'MultiFormStep',
$this->class, $this->class,
'MultiForm', 'MultiForm',
'Form' 'Form'
)); ]);
$this->clearMessage(); $this->clearMessage();
@ -447,7 +462,8 @@ abstract class MultiForm extends Form
* of all the data collected through each step of the form. * of all the data collected through each step of the form.
* *
* @param array $data The request data returned from the form * @param array $data The request data returned from the form
* @param object $form The form that the action was called on * @param Form $form The form that the action was called on
* @return bool
*/ */
public function finish($data, $form) public function finish($data, $form)
{ {
@ -460,7 +476,7 @@ abstract class MultiForm extends Form
} }
if (!$this->getCurrentStep()->validateStep($data, $form)) { if (!$this->getCurrentStep()->validateStep($data, $form)) {
Session::set("FormInfo.{$form->FormName()}.data", $form->getData()); Injector::inst()->get(Session::class)->set("FormInfo.{$form->FormName()}.data", $form->getData());
$this->controller->redirectBack(); $this->controller->redirectBack();
return false; return false;
} }
@ -475,7 +491,8 @@ abstract class MultiForm extends Form
* then redirects to the newly set step. * then redirects to the newly set step.
* *
* @param array $data The request data returned from the form * @param array $data The request data returned from the form
* @param object $form The form that the action was called on * @param Form $form The form that the action was called on
* @return bool
*/ */
public function next($data, $form) public function next($data, $form)
{ {
@ -494,17 +511,17 @@ abstract class MultiForm extends Form
// built-in functionality). The data needs to be manually saved on error // built-in functionality). The data needs to be manually saved on error
// so the form is re-populated. // so the form is re-populated.
if (!$this->getCurrentStep()->validateStep($data, $form)) { if (!$this->getCurrentStep()->validateStep($data, $form)) {
Session::set("FormInfo.{$form->FormName()}.data", $form->getData()); Injector::inst()->get(Session::class)->set("FormInfo.{$form->FormName()}.data", $form->getData());
$this->controller->redirectBack(); $this->controller->redirectBack();
return false; return false;
} }
// validation succeeded so we reset it to remove errors and messages // validation succeeded so we reset it to remove errors and messages
$this->resetValidation(); $this->clearFormState();
// Determine whether we can use a step already in the DB, or have to create a new one // Determine whether we can use a step already in the DB, or have to create a new one
if (!$nextStep = DataObject::get_one($nextStepClass, "\"SessionID\" = {$this->session->ID}")) { if (!$nextStep = DataObject::get_one($nextStepClass, "\"SessionID\" = {$this->session->ID}")) {
$nextStep = Object::create($nextStepClass); $nextStep = Injector::inst()->create($nextStepClass);
$nextStep->SessionID = $this->session->ID; $nextStep->SessionID = $this->session->ID;
$nextStep->write(); $nextStep->write();
} }
@ -524,7 +541,8 @@ abstract class MultiForm extends Form
* Finally, it redirects to that step. * Finally, it redirects to that step.
* *
* @param array $data The request data returned from the form * @param array $data The request data returned from the form
* @param object $form The form that the action was called on * @param Form $form The form that the action was called on
* @return bool|HTTPResponse
*/ */
public function prev($data, $form) public function prev($data, $form)
{ {
@ -546,7 +564,7 @@ abstract class MultiForm extends Form
$this->setCurrentStep($prevStep); $this->setCurrentStep($prevStep);
// Redirect to the previous step // Redirect to the previous step
$this->controller->redirect($prevStep->Link()); return $this->controller->redirect($prevStep->Link());
} }
/** /**
@ -620,11 +638,11 @@ abstract class MultiForm extends Form
* first step. We run {@link getAllStepsRecursive} passing the steps found * first step. We run {@link getAllStepsRecursive} passing the steps found
* by reference to get a listing of the steps. * by reference to get a listing of the steps.
* *
* @return DataObjectSet of MultiFormStep instances * @return ArrayList of MultiFormStep instances
*/ */
public function getAllStepsLinear() public function getAllStepsLinear()
{ {
$stepsFound = (class_exists('ArrayList')) ? new ArrayList() : new DataObjectSet(); $stepsFound = ArrayList::create();
$firstStep = DataObject::get_one(static::$start_step, "\"SessionID\" = {$this->session->ID}"); $firstStep = DataObject::get_one(static::$start_step, "\"SessionID\" = {$this->session->ID}");
$firstStep->LinkingMode = ($firstStep->ID == $this->getCurrentStep()->ID) ? 'current' : 'link'; $firstStep->LinkingMode = ($firstStep->ID == $this->getCurrentStep()->ID) ? 'current' : 'link';
@ -651,9 +669,9 @@ abstract class MultiForm extends Form
* session, its used - otherwise a singleton of this step is used. * session, its used - otherwise a singleton of this step is used.
* Caution: Doesn't consider branching for steps which aren't in the database yet. * Caution: Doesn't consider branching for steps which aren't in the database yet.
* *
* @param $step Subclass of MultiFormStep to find the next step of * @param MultiFormStep $step Subclass of MultiFormStep to find the next step of
* @param $stepsFound $stepsFound DataObjectSet reference, the steps found to call back on * @param $stepsFound $stepsFound DataObjectSet reference, the steps found to call back on
* @return DataObjectSet of MultiFormStep instances * @return DataList of MultiFormStep instances
*/ */
protected function getAllStepsRecursive($step, &$stepsFound) protected function getAllStepsRecursive($step, &$stepsFound)
{ {

View File

@ -1,5 +1,10 @@
<?php <?php
namespace SilverStripe\MultiForm\Models;
use SilverStripe\ORM\DataObject;
use SilverStripe\Security\Security;
/** /**
* Serializes one or more {@link MultiFormStep}s into * Serializes one or more {@link MultiFormStep}s into
* a database object. * a database object.
@ -12,20 +17,21 @@
*/ */
class MultiFormSession extends DataObject class MultiFormSession extends DataObject
{ {
private static $db = [
private static $db = array(
'Hash' => 'Varchar(40)', // cryptographic hash identification to this session 'Hash' => 'Varchar(40)', // cryptographic hash identification to this session
'IsComplete' => 'Boolean' // flag to determine if this session is marked completed 'IsComplete' => 'Boolean' // flag to determine if this session is marked completed
); ];
private static $has_one = array( private static $has_one = [
'Submitter' => 'Member', 'Submitter' => 'Member',
'CurrentStep' => 'MultiFormStep' 'CurrentStep' => 'MultiFormStep'
); ];
private static $has_many = array( private static $has_many = [
'FormSteps' => 'MultiFormStep' 'FormSteps' => 'MultiFormStep'
); ];
private static $table_name = 'MultiFormSession';
/** /**
* Mark this session as completed. * Mark this session as completed.
@ -45,8 +51,8 @@ class MultiFormSession extends DataObject
public function onBeforeWrite() public function onBeforeWrite()
{ {
// save submitter if a Member is logged in // save submitter if a Member is logged in
$currentMember = Member::currentUser(); $currentMember = Security::getCurrentUser();
if (!$this->SubmitterID && $currentMember) { if (!$this->SubmitterID && $currentMember->ID) {
$this->SubmitterID = $currentMember->ID; $this->SubmitterID = $currentMember->ID;
} }

View File

@ -1,5 +1,13 @@
<?php <?php
namespace SilverStripe\MultiForm\Models;
use SilverStripe\Control\Controller;
use SilverStripe\Forms\FieldList;
use SilverStripe\Forms\Form;
use SilverStripe\Forms\Validator;
use SilverStripe\ORM\DataObject;
/** /**
* MultiFormStep controls the behaviour of a single form step in the MultiForm * MultiFormStep controls the behaviour of a single form step in the MultiForm
* process. All form steps are required to be subclasses of this class, as it * process. All form steps are required to be subclasses of this class, as it
@ -11,14 +19,15 @@
*/ */
class MultiFormStep extends DataObject class MultiFormStep extends DataObject
{ {
private static $db = [
private static $db = array(
'Data' => 'Text' // stores serialized maps with all session information 'Data' => 'Text' // stores serialized maps with all session information
); ];
private static $has_one = array( private static $has_one = [
'Session' => 'MultiFormSession' 'Session' => 'MultiFormSession'
); ];
private static $table_name = 'MultiFormStep';
/** /**
* Centerpiece of the flow control for the form. * Centerpiece of the flow control for the form.
@ -78,14 +87,14 @@ class MultiFormStep extends DataObject
* *
* @var array $extraClasses * @var array $extraClasses
*/ */
protected $extraClasses = array(); protected $extraClasses = [];
/** /**
* Temporary cache to increase the performance for repeated look ups. * Temporary cache to increase the performance for repeated look ups.
* *
* @var array $cache * @var array $cache
*/ */
protected $step_data_cache = array(); protected $step_data_cache = [];
/** /**
* Form fields to be rendered with this step. * Form fields to be rendered with this step.
@ -112,14 +121,14 @@ class MultiFormStep extends DataObject
*/ */
public function getExtraActions() public function getExtraActions()
{ {
return (class_exists('FieldList')) ? new FieldList() : new FieldSet(); return FieldList::create();
} }
/** /**
* Get a validator specific to this form. * Get a validator specific to this form.
* The form is automatically validated in {@link Form->httpSubmission()}. * The form is automatically validated in {@link Form->httpSubmission()}.
* *
* @return Validator * @return bool|Validator
*/ */
public function getValidator() public function getValidator()
{ {
@ -147,7 +156,10 @@ class MultiFormStep extends DataObject
public function Link() public function Link()
{ {
$form = $this->form; $form = $this->form;
return Controller::join_links($form->getDisplayLink(), "?{$form->config()->get_var}={$this->Session()->Hash}"); return Controller::join_links(
$form->getDisplayLink(),
"?{$form->config()->get_var}={$this->getSession()->Hash}"
);
} }
/** /**
@ -164,7 +176,7 @@ class MultiFormStep extends DataObject
*/ */
public function loadData() public function loadData()
{ {
return ($this->Data && is_string($this->Data)) ? unserialize($this->Data) : array(); return ($this->Data && is_string($this->Data)) ? unserialize($this->Data) : [];
} }
/** /**
@ -191,14 +203,15 @@ class MultiFormStep extends DataObject
* as a simple value outside of the original FormField context. * as a simple value outside of the original FormField context.
* *
* @param DataObject $obj * @param DataObject $obj
* @return DataObject
*/ */
public function saveInto($obj) public function saveInto($obj)
{ {
$form = new Form( $form = Form::create(
Controller::curr(), Controller::curr(),
'Form', 'Form',
$this->getFields(), $this->getFields(),
((class_exists('FieldList')) ? new FieldList() : new FieldSet()) FieldList::create()
); );
$form->loadDataFrom($this->loadData()); $form->loadDataFrom($this->loadData());
$form->saveInto($obj); $form->saveInto($obj);
@ -235,7 +248,11 @@ class MultiFormStep extends DataObject
// Check if next_steps have been implemented properly if not the final step // Check if next_steps have been implemented properly if not the final step
if (!$this->isFinalStep()) { if (!$this->isFinalStep()) {
if (!isset($nextSteps)) { if (!isset($nextSteps)) {
user_error('MultiFormStep->getNextStep(): Please define at least one $next_steps on ' . $this->class, E_USER_ERROR); user_error(
'MultiFormStep->getNextStep(): Please define at least one $next_steps on '
. $this->class,
E_USER_ERROR
);
} }
} }
@ -326,7 +343,7 @@ class MultiFormStep extends DataObject
*/ */
public function getPrevText() public function getPrevText()
{ {
return _t('MultiForm.BACK', 'Back'); return _t(__CLASS__ . '.BACK', 'Back');
} }
/** /**
@ -335,7 +352,7 @@ class MultiFormStep extends DataObject
*/ */
public function getNextText() public function getNextText()
{ {
return _t('MultiForm.NEXT', 'Next'); return _t(__CLASS__ . '.NEXT', 'Next');
} }
/** /**
@ -344,13 +361,13 @@ class MultiFormStep extends DataObject
*/ */
public function getSubmitText() public function getSubmitText()
{ {
return _t('MultiForm.SUBMIT', 'Submit'); return _t(__CLASS__ . '.SUBMIT', 'Submit');
} }
/** /**
* Sets the form that this step is directly related to. * Sets the form that this step is directly related to.
* *
* @param MultiForm subclass $form * @param MultiForm $form subclass
*/ */
public function setForm($form) public function setForm($form)
{ {
@ -401,7 +418,7 @@ class MultiFormStep extends DataObject
*/ */
public function isCurrentStep() public function isCurrentStep()
{ {
return ($this->class == $this->Session()->CurrentStep()->class) ? true : false; return ($this->class == $this->getSession()->CurrentStep()->class) ? true : false;
} }
/** /**
@ -458,7 +475,7 @@ class MultiFormStep extends DataObject
{ {
// load the steps in the cache, if this one doesn't exist // load the steps in the cache, if this one doesn't exist
if (!array_key_exists('steps_' . $fromStep, $this->step_data_cache)) { if (!array_key_exists('steps_' . $fromStep, $this->step_data_cache)) {
$steps = MultiFormStep::get()->filter('SessionID', $this->form->session->ID); $steps = self::get()->filter('SessionID', $this->form->session->ID);
if ($steps) { if ($steps) {
foreach ($steps as $step) { foreach ($steps as $step) {
@ -494,4 +511,13 @@ class MultiFormStep extends DataObject
$fields->fieldByName($fieldNameTarget)->setValue($this->getValueFromOtherStep($formStep, $fieldName)); $fields->fieldByName($fieldNameTarget)->setValue($this->getValueFromOtherStep($formStep, $fieldName));
} }
/**
* Gets the linked MultiFormSession
* @return MultiFormSession
*/
public function getSession()
{
return $this->Session();
}
} }

View File

@ -1,5 +1,11 @@
<?php <?php
namespace SilverStripe\MultiForm\Extensions;
use SilverStripe\ORM\DataExtension;
use SilverStripe\ORM\DataQuery;
use SilverStripe\ORM\Queries\SQLSelect;
/** /**
* Decorate {@link DataObject}s which are required to be saved * Decorate {@link DataObject}s which are required to be saved
* to the database directly by a {@link MultiFormStep}. * to the database directly by a {@link MultiFormStep}.
@ -17,19 +23,21 @@
class MultiFormObjectDecorator extends DataExtension class MultiFormObjectDecorator extends DataExtension
{ {
private static $db = array( private static $db = [
'MultiFormIsTemporary' => 'Boolean', 'MultiFormIsTemporary' => 'Boolean',
); ];
private static $has_one = array( private static $has_one = [
'MultiFormSession' => 'MultiFormSession', 'MultiFormSession' => 'MultiFormSession',
); ];
/** /**
* Augment any queries to MultiFormObjectDecorator and only * Augment any queries to MultiFormObjectDecorator and only
* return anything that isn't considered temporary. * return anything that isn't considered temporary.
* @param SQLSelect $query
* @param DataQuery|null $dataQuery
*/ */
public function augmentSQL(SQLQuery &$query) public function augmentSQL(SQLSelect $query, DataQuery $dataQuery = null)
{ {
$where = $query->getWhere(); $where = $query->getWhere();
if (!$where && !$this->wantsTemporary($query)) { if (!$where && !$this->wantsTemporary($query)) {
@ -53,7 +61,7 @@ class MultiFormObjectDecorator extends DataExtension
* to be exempt from the automatic filtering out * to be exempt from the automatic filtering out
* of temporary records. * of temporary records.
* *
* @param SQLQuery $query * @param SQLSelect $query
* @return boolean * @return boolean
*/ */
protected function wantsTemporary($query) protected function wantsTemporary($query)

View File

@ -1,5 +1,11 @@
<?php <?php
namespace SilverStripe\MultiForm;
use SilverStripe\Dev\BuildTask;
use SilverStripe\ORM\DataList;
use SilverStripe\ORM\DataObject;
/** /**
* Task to clean out all {@link MultiFormSession} objects from the database. * Task to clean out all {@link MultiFormSession} objects from the database.
* *
@ -14,7 +20,6 @@
*/ */
class MultiFormPurgeTask extends BuildTask class MultiFormPurgeTask extends BuildTask
{ {
/** /**
* Days after which sessions expire and * Days after which sessions expire and
* are automatically deleted. * are automatically deleted.
@ -47,12 +52,12 @@ class MultiFormPurgeTask extends BuildTask
* Return all MultiFormSession database records that are older than * Return all MultiFormSession database records that are older than
* the days specified in $session_expiry_days * the days specified in $session_expiry_days
* *
* @return DataObjectSet * @return DataList
*/ */
protected function getExpiredSessions() protected function getExpiredSessions()
{ {
return DataObject::get( return DataObject::get(
'MultiFormSession', MultiFormSession::class,
"DATEDIFF(NOW(), \"MultiFormSession\".\"Created\") > " . self::$session_expiry_days "DATEDIFF(NOW(), \"MultiFormSession\".\"Created\") > " . self::$session_expiry_days
); );
} }

View File

@ -1,9 +1,19 @@
<ul class="stepIndicator current-$CurrentStep.class"> <ul class="stepIndicator current-$CurrentStep.class">
<% loop AllStepsLinear %> <% loop $AllStepsLinear %>
<li class="$ClassName<% if LinkingMode %> $LinkingMode<% end_if %><% if FirstLast %> $FirstLast<% end_if %><% if $ExtraClasses %> $ExtraClasses<% end_if %>"> <li class="$ClassName<% if $LinkingMode %> $LinkingMode<% end_if %><% if $FirstLast %> $FirstLast<% end_if %><% if $ExtraClasses %> $ExtraClasses<% end_if %>">
<% if LinkingMode = current %><% else %><% if ID %><a href="{$Top.URLSegment}/?${Top.GetVar}={$SessionID}&amp;StepID={$ID}"><% end_if %><% end_if %> <% if $LinkingMode = current %>
<% if Title %>$Title<% else %>$ClassName<% end_if %> <% else %>
<% if LinkingMode = current %><% else %><% if ID %></a><% end_if %><% end_if %> <% if $ID %>
<a href="{$Top.URLSegment}/?${Top.GetVar}={$SessionID}&amp;StepID={$ID}">
<% end_if %>
<% end_if %>
<% if $Title %>$Title<% else %>$ClassName<% end_if %>
<% if $LinkingMode = current %>
<% else %>
<% if $ID %></a><% end_if %>
<% end_if %>
</li> </li>
<% end_loop %> <% end_loop %>
</ul> </ul>

View File

@ -1 +1 @@
<p>You've completed {$CompletedPercent.Nice}% ($CompletedStepCount/$TotalStepCount)</p> <p><%t MULTIFORM.ProgressPercent "You've completed {percent}% ({completedSteps}/{totalSteps})" percent=$CompletedPercent.Nice completedSteps=$CompletedStepCount totalSteps$TotalStepCount %></p>

View File

@ -1,20 +1,24 @@
<?php <?php
namespace SilverStripe\MultiForm\Tests;
use SilverStripe\Dev\SapphireTest;
class MultiFormObjectDecoratorTest extends SapphireTest class MultiFormObjectDecoratorTest extends SapphireTest
{ {
protected static $fixture_file = 'MultiFormObjectDecoratorTest.yml'; protected static $fixture_file = 'MultiFormObjectDecoratorTest.yml';
protected $requiredExtensions = array( protected $requiredExtensions = [
'MultiFormObjectDecorator_DataObject' => array('MultiFormObjectDecorator') 'MultiFormObjectDecoratorDataObject' => ['MultiFormObjectDecorator']
); ];
protected $extraDataObjects = array( protected $extraDataObjects = [
'MultiFormObjectDecorator_DataObject' 'MultiFormObjectDecoratorDataObject'
); ];
public function testTemporaryDataFilteredQuery() public function testTemporaryDataFilteredQuery()
{ {
$records = MultiFormObjectDecorator_DataObject::get() $records = MultiFormObjectDecoratorDataObject::get()
->map('Name') ->map('Name')
->toArray(); ->toArray();
@ -25,8 +29,8 @@ class MultiFormObjectDecoratorTest extends SapphireTest
public function testTemporaryDataQuery() public function testTemporaryDataQuery()
{ {
$records = MultiFormObjectDecorator_DataObject::get() $records = MultiFormObjectDecoratorDataObject::get()
->filter(array('MultiFormIsTemporary' => 1)) ->filter(['MultiFormIsTemporary' => 1])
->map('Name') ->map('Name')
->toArray(); ->toArray();
@ -35,11 +39,3 @@ class MultiFormObjectDecoratorTest extends SapphireTest
$this->assertContains('Test 3', $records); $this->assertContains('Test 3', $records);
} }
} }
class MultiFormObjectDecorator_DataObject extends DataObject
{
private static $db = array(
'Name' => 'Varchar'
);
}

View File

@ -1,4 +1,4 @@
MultiFormObjectDecorator_DataObject: SilverStripe\MultiForm\Tests\MultiFormObjectDecoratorDataObject:
test-data-1: test-data-1:
Name: Test 1 Name: Test 1
MultiFormIsTemporary: 0 MultiFormIsTemporary: 0

View File

@ -1,16 +1,22 @@
<?php <?php
namespace SilverStripe\MultiForm\Tests;
use SilverStripe\Core\Config\Config;
use SilverStripe\Dev\FunctionalTest;
/** /**
* MultiFormTest * MultiFormTest
* For testing purposes, we have some test classes: * For testing purposes, we have some test classes:
* *
* - MultiFormTest_Controller (simulation of a real Controller class) * - MultiFormTestController (simulation of a real Controller class)
* - MultiFormTest_Form (subclass of MultiForm) * - MultiFormTestForm (subclass of MultiForm)
* - MultiFormTest_StepOne (subclass of MultiFormStep) * - MultiFormTestStepOne (subclass of MultiFormStep)
* - MultiFormTest_StepTwo (subclass of MultiFormStep) * - MultiFormTestStepTwo (subclass of MultiFormStep)
* - MultiFormTest_StepThree (subclass of MultiFormStep) * - MultiFormTestStepThree (subclass of MultiFormStep)
* *
* The above classes are used to simulate real-world behaviour * The above classes are used to simulate real-world behaviour
* of the multiform module - for example, MultiFormTest_Controller * of the multiform module - for example, MultiFormTestController
* is a simulation of a page where MultiFormTest_Form is a simple * is a simulation of a page where MultiFormTest_Form is a simple
* multi-step contact form it belongs to. * multi-step contact form it belongs to.
* *
@ -20,15 +26,20 @@
class MultiFormTest extends FunctionalTest class MultiFormTest extends FunctionalTest
{ {
public static $fixture_file = 'multiform/tests/MultiFormTest.yml'; public static $fixture_file = 'MultiFormTest.yml';
protected $controller; protected $controller;
/**
* @var MultiFormTestForm
*/
protected $form;
public function setUp() public function setUp()
{ {
parent::setUp(); parent::setUp();
$this->controller = new MultiFormTest_Controller(); $this->controller = new MultiFormTestController();
$this->form = $this->controller->Form(); $this->form = $this->controller->Form();
} }
@ -36,22 +47,22 @@ class MultiFormTest extends FunctionalTest
{ {
$this->assertTrue(is_numeric($this->form->getCurrentStep()->ID) && ($this->form->getCurrentStep()->ID > 0)); $this->assertTrue(is_numeric($this->form->getCurrentStep()->ID) && ($this->form->getCurrentStep()->ID > 0));
$this->assertTrue(is_numeric($this->form->getSession()->ID) && ($this->form->getSession()->ID > 0)); $this->assertTrue(is_numeric($this->form->getSession()->ID) && ($this->form->getSession()->ID > 0));
$this->assertEquals('MultiFormTest_StepOne', $this->form->getStartStep()); $this->assertEquals(MultiFormTestStepOne::class, $this->form->getStartStep());
} }
public function testSessionGeneration() public function testSessionGeneration()
{ {
$this->assertTrue($this->form->session->ID > 0); $this->assertTrue($this->form->getSession()->ID > 0);
} }
public function testMemberLogging() public function testMemberLogging()
{ {
// Grab any user to fake being logged in as, and ensure that after a session is written it has // Grab any user to fake being logged in as, and ensure that after a session is written it has
// that user as the submitter. // that user as the submitter.
$userId = Member::get_one("Member")->ID;
$this->session()->inst_set('loggedInAs', $userId);
$session = $this->form->session; $userId = $this->logInWithPermission('ADMIN');
$session = $this->form->getSession();
$session->write(); $session->write();
$this->assertEquals($userId, $session->SubmitterID); $this->assertEquals($userId, $session->SubmitterID);
@ -59,7 +70,7 @@ class MultiFormTest extends FunctionalTest
public function testSecondStep() public function testSecondStep()
{ {
$this->assertEquals('MultiFormTest_StepTwo', $this->form->getCurrentStep()->getNextStep()); $this->assertEquals(MultiFormTestStepTwo::class, $this->form->getCurrentStep()->getNextStep());
} }
public function testParentForm() public function testParentForm()
@ -75,9 +86,9 @@ class MultiFormTest extends FunctionalTest
public function testCompletedSession() public function testCompletedSession()
{ {
$this->form->setCurrentSessionHash($this->form->session->Hash); $this->form->setCurrentSessionHash($this->form->getSession()->Hash);
$this->assertInstanceOf('MultiFormSession', $this->form->getCurrentSession()); $this->assertInstanceOf('MultiFormSession', $this->form->getCurrentSession());
$this->form->session->markCompleted(); $this->form->getSession()->markCompleted();
$this->assertNull($this->form->getCurrentSession()); $this->assertNull($this->form->getCurrentSession());
} }
@ -86,112 +97,27 @@ class MultiFormTest extends FunctionalTest
$this->form->setCurrentSessionHash('sdfsdf3432325325sfsdfdf'); // made up! $this->form->setCurrentSessionHash('sdfsdf3432325325sfsdfdf'); // made up!
// A new session is generated, even though we made up the identifier // A new session is generated, even though we made up the identifier
$this->assertInstanceOf('MultiFormSession', $this->form->session); $this->assertInstanceOf('MultiFormSession', $this->form->getSession());
} }
function testCustomGetVar() public function testCustomGetVar()
{ {
Config::nest(); Config::nest();
Config::inst()->update('MultiForm', 'get_var', 'SuperSessionID'); Config::modify()->set('MultiForm', 'get_var', 'SuperSessionID');
$form = $this->controller->Form(); $form = $this->controller->Form();
$this->assertContains('SuperSessionID', $form::$ignored_fields, "GET var wasn't added to ignored fields"); $this->assertContains('SuperSessionID', $form::$ignored_fields, "GET var wasn't added to ignored fields");
$this->assertContains('SuperSessionID', $form->FormAction(), "Form action doesn't contain correct session $this->assertContains(
ID parameter"); 'SuperSessionID',
$this->assertContains('SuperSessionID', $form->getCurrentStep()->Link(), "Form step doesn't contain correct $form->FormAction(),
session ID parameter"); "Form action doesn't contain correct session ID parameter"
);
$this->assertContains(
'SuperSessionID',
$form->getCurrentStep()->Link(),
"Form step doesn't contain correct session ID parameter"
);
Config::unnest(); Config::unnest();
} }
} }
/**
* @package multiform
* @subpackage tests
*/
class MultiFormTest_Controller extends Controller implements TestOnly
{
public function Link()
{
return 'MultiFormTest_Controller';
}
public function Form($request = null)
{
$form = new MultiFormTest_Form($this, 'Form');
$form->setHTMLID('MultiFormTest_Form');
return $form;
}
}
/**
* @package multiform
* @subpackage tests
*/
class MultiFormTest_Form extends MultiForm implements TestOnly
{
public static $start_step = 'MultiFormTest_StepOne';
public function getStartStep()
{
return self::$start_step;
}
}
/**
* @package multiform
* @subpackage tests
*/
class MultiFormTest_StepOne extends MultiFormStep implements TestOnly
{
public static $next_steps = 'MultiFormTest_StepTwo';
public function getFields()
{
$class = (class_exists('FieldList')) ? 'FieldList' : 'FieldSet';
return new $class(
new TextField('FirstName', 'First name'),
new TextField('Surname', 'Surname'),
new EmailField('Email', 'Email address')
);
}
}
/**
* @package multiform
* @subpackage tests
*/
class MultiFormTest_StepTwo extends MultiFormStep implements TestOnly
{
public static $next_steps = 'MultiFormTest_StepThree';
public function getFields()
{
$class = (class_exists('FieldList')) ? 'FieldList' : 'FieldSet';
return new $class(
new TextareaField('Comments', 'Tell us a bit about yourself...')
);
}
}
/**
* @package multiform
* @subpackage tests
*/
class MultiFormTest_StepThree extends MultiFormStep implements TestOnly
{
public static $is_final_step = true;
public function getFields()
{
$class = (class_exists('FieldList')) ? 'FieldList' : 'FieldSet';
return new $class(
new TextField('Test', 'Anything else you\'d like to tell us?')
);
}
}

View File

@ -1,4 +1,4 @@
Member: SilverStripe\Security\Member:
admin: admin:
FirstName: Admin FirstName: Admin
Surname: Admin Surname: Admin

View File

@ -0,0 +1,13 @@
<?php
namespace SilverStripe\MultiForm\Tests;
use SilverStripe\Dev\TestOnly;
use SilverStripe\ORM\DataObject;
class MultiFormObjectDecoratorDataObject extends DataObject implements TestOnly
{
private static $db = [
'Name' => 'Varchar'
];
}

View File

@ -1,8 +0,0 @@
<?php
namespace SilverStripe\multiform\tests\Stubs;
class MultiFormObjectDecorator_DataObject
{
}

View File

@ -1,8 +1,27 @@
<?php <?php
namespace SilverStripe\MultiForm\Tests\Stubs; namespace SilverStripe\MultiForm\Tests;
class MultiFormStepOne use SilverStripe\Dev\TestOnly;
use SilverStripe\Forms\EmailField;
use SilverStripe\Forms\FieldList;
use SilverStripe\Forms\TextField;
use SilverStripe\MultiForm\Models\MultiFormStep;
/**
* @package multiform
* @subpackage tests
*/
class MultiFormTestStepOne extends MultiFormStep implements TestOnly
{ {
public static $next_steps = MultiFormTestStepTwo::class;
public function getFields()
{
return FieldList::create(
new TextField('FirstName', 'First name'),
new TextField('Surname', 'Surname'),
new EmailField('Email', 'Email address')
);
}
} }

View File

@ -0,0 +1,25 @@
<?php
namespace SilverStripe\MultiForm\Tests;
use SilverStripe\Control\Controller;
use SilverStripe\Dev\TestOnly;
/**
* @package multiform
* @subpackage tests
*/
class MultiFormTestController extends Controller implements TestOnly
{
public function Link()
{
return self::class;
}
public function Form($request = null)
{
$form = new MultiFormTestForm($this, 'Form');
$form->setHTMLID(self::class);
return $form;
}
}

View File

@ -1,8 +1,20 @@
<?php <?php
namespace SilverStripe\multiform\tests\Stubs; namespace SilverStripe\MultiForm\Tests;
class MultiFormTestForm use SilverStripe\Dev\TestOnly;
use SilverStripe\MultiForm\Models\MultiForm;
/**
* @package multiform
* @subpackage tests
*/
class MultiFormTestForm extends MultiForm implements TestOnly
{ {
public static $start_step = MultiFormTestStepOne::class;
public function getStartStep()
{
return self::$start_step;
}
} }

View File

@ -1,8 +1,24 @@
<?php <?php
namespace SilverStripe\multiform\tests\Stubs; namespace SilverStripe\MultiForm\Tests;
class MultiFormTestStepThree use SilverStripe\Dev\TestOnly;
use SilverStripe\Forms\FieldList;
use SilverStripe\Forms\TextField;
use SilverStripe\MultiForm\Models\MultiFormStep;
/**
* @package multiform
* @subpackage tests
*/
class MultiFormTestStepThree extends MultiFormStep implements TestOnly
{ {
public static $is_final_step = true;
public function getFields()
{
return FieldList::create(
new TextField('Test', 'Anything else you\'d like to tell us?')
);
}
} }

View File

@ -0,0 +1,23 @@
<?php
namespace SilverStripe\MultiForm\Tests;
use SilverStripe\Dev\TestOnly;
use SilverStripe\Forms\FieldList;
use SilverStripe\Forms\TextareaField;
use SilverStripe\MultiForm\Models\MultiFormStep;
/**
* @package multiform
* @subpackage tests
*/
class MultiFormTestStepTwo extends MultiFormStep implements TestOnly
{
public static $next_steps = MultiFormTestStepThree::class;
public function getFields()
{
return new FieldList(
new TextareaField('Comments', 'Tell us a bit about yourself...')
);
}
}

View File

@ -1,8 +0,0 @@
<?php
namespace SilverStripe\multiform\tests\Stubs;
class MultiFormTest_Controller
{
}