remove trailing spaces in the codebase

This commit is contained in:
Peter Thaleikis 2015-11-02 13:38:50 +13:00
parent bc49ac35e7
commit f96a9832d9
6 changed files with 164 additions and 164 deletions

View File

@ -5,7 +5,7 @@
* to the database directly by a {@link MultiFormStep}. * to the database directly by a {@link MultiFormStep}.
* Only needed for objects which aren't stored in the session, * Only needed for objects which aren't stored in the session,
* which is the default. * which is the default.
* *
* This decorator also augments get() requests to the datalayer * This decorator also augments get() requests to the datalayer
* by automatically filtering out temporary objects. * by automatically filtering out temporary objects.
* You can override this filter by putting the following statement * You can override this filter by putting the following statement
@ -15,27 +15,27 @@
* @package multiform * @package multiform
*/ */
class MultiFormObjectDecorator extends DataExtension { class MultiFormObjectDecorator extends DataExtension {
private static $db = array( private static $db = array(
'MultiFormIsTemporary' => 'Boolean', 'MultiFormIsTemporary' => 'Boolean',
); );
private static $has_one = array( private static $has_one = array(
'MultiFormSession' => 'MultiFormSession', 'MultiFormSession' => 'MultiFormSession',
); );
public function augmentSQL(SQLSelect $query) { public function augmentSQL(SQLSelect $query) {
// If you're querying by ID, ignore the sub-site - this is a bit ugly... // If you're querying by ID, ignore the sub-site - this is a bit ugly...
if( if(
strpos($query->where[0], ".`ID` = ") === false strpos($query->where[0], ".`ID` = ") === false
&& strpos($query->where[0], ".ID = ") === false && strpos($query->where[0], ".ID = ") === false
&& strpos($query->where[0], "ID = ") !== 0 && strpos($query->where[0], "ID = ") !== 0
&& !$this->wantsTemporary($query) && !$this->wantsTemporary($query)
) { ) {
$query->where[] = "\"{$query->from[0]}\".\"MultiFormIsTemporary\" = 0"; $query->where[] = "\"{$query->from[0]}\".\"MultiFormIsTemporary\" = 0";
} }
} }
/** /**
* Determines if the current query is supposed * Determines if the current query is supposed
* to be exempt from the automatic filtering out * to be exempt from the automatic filtering out

View File

@ -4,18 +4,18 @@
* 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
* layer. * layer.
* *
* CAUTION: If you're using controller permission control, * CAUTION: If you're using controller permission control,
* you have to allow the following methods: * you have to allow the following methods:
* *
* <code> * <code>
* private static $allowed_actions = array('next','prev'); * private static $allowed_actions = array('next','prev');
* </code> * </code>
* *
* @package multiform * @package multiform
*/ */
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.
@ -23,13 +23,13 @@ abstract class MultiForm extends Form {
* @var MultiFormSession * @var MultiFormSession
*/ */
protected $session; protected $session;
/** /**
* The current encrypted MultiFormSession identification. * The current encrypted MultiFormSession identification.
* @var string * @var string
*/ */
protected $currentSessionHash; protected $currentSessionHash;
/** /**
* Defines which subclass of {@link MultiFormStep} should be the first * Defines which subclass of {@link MultiFormStep} should be the first
* step in the multi-step process. * step in the multi-step process.
@ -37,7 +37,7 @@ abstract class MultiForm extends Form {
* @var string Classname of a {@link MultiFormStep} subclass * @var string Classname of a {@link MultiFormStep} subclass
*/ */
public static $start_step; public static $start_step;
/** /**
* Set the casting for these fields. * Set the casting for these fields.
* *
@ -48,7 +48,7 @@ abstract class MultiForm extends Form {
'TotalStepCount' => 'Int', 'TotalStepCount' => 'Int',
'CompletedPercent' => 'Float' 'CompletedPercent' => 'Float'
); );
/** /**
* These fields are ignored when saving the raw form data into session. * These fields are ignored when saving the raw form data into session.
* This ensures only field data is saved, and nothing else that's useless * This ensures only field data is saved, and nothing else that's useless
@ -62,15 +62,15 @@ abstract class MultiForm extends Form {
'MultiFormSessionID', 'MultiFormSessionID',
'SecurityID' 'SecurityID'
); );
/** /**
* Any of the actions defined in this variable are exempt from * Any of the actions defined in this variable are exempt from
* being validated. * being validated.
* *
* This is most useful for the "Back" (action_prev) action, as * This is most useful for the "Back" (action_prev) action, as
* you typically don't validate the form when the user is going * you typically don't validate the form when the user is going
* back a step. * back a step.
* *
* @var array * @var array
*/ */
public static $actions_exempt_from_validation = array( public static $actions_exempt_from_validation = array(
@ -124,7 +124,7 @@ abstract class MultiForm extends Form {
if(!empty($_REQUEST[$exemptAction])) { if(!empty($_REQUEST[$exemptAction])) {
$applyValidation = false; $applyValidation = false;
break; break;
} }
} }
} }
@ -134,19 +134,19 @@ abstract class MultiForm extends Form {
$validator = $currentStep->getValidator(); $validator = $currentStep->getValidator();
} }
} }
// Give the fields, actions, and validation for the current step back to the parent Form class // Give the fields, actions, and validation for the current step back to the parent Form class
parent::__construct($controller, $name, $fields, $actions, $validator); parent::__construct($controller, $name, $fields, $actions, $validator);
// 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('MultiFormSessionID', false, $this->session->Hash)); $this->fields->push(new HiddenField('MultiFormSessionID', 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!)
if($data = $currentStep->loadData()) { if($data = $currentStep->loadData()) {
$this->loadDataFrom($data); $this->loadDataFrom($data);
} }
// 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();
} }
@ -159,23 +159,23 @@ abstract class MultiForm extends Form {
public function getController() { public function getController() {
return $this->controller; return $this->controller;
} }
/** /**
* Get the current step. * Get the current step.
* *
* If StepID has been set in the URL, we attempt to get that record * If StepID has been set in the URL, we attempt to get that record
* by the ID. Otherwise, we check if there's a current step ID in * by the ID. Otherwise, we check if there's a current step ID in
* our session record. Failing those cases, we assume that the form has * our session record. Failing those cases, we assume that the form has
* just been started, and so we create the first step and return it. * just been started, and so we create the first step and return it.
* *
* @return MultiFormStep subclass * @return MultiFormStep subclass
*/ */
public function getCurrentStep() { public function getCurrentStep() {
$startStepClass = static::$start_step; $startStepClass = static::$start_step;
// 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)) user_error('MultiForm::init(): Please define a $start_step on ' . $this->class, E_USER_ERROR); if(!isset($startStepClass)) user_error('MultiForm::init(): Please define a $start_step on ' . $this->class, E_USER_ERROR);
// 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;
if(isset($_GET['StepID'])) { if(isset($_GET['StepID'])) {
@ -183,8 +183,8 @@ abstract class MultiForm extends Form {
$currentStep = DataObject::get_one('MultiFormStep', "\"SessionID\" = {$this->session->ID} AND \"ID\" = {$stepID}"); $currentStep = DataObject::get_one('MultiFormStep', "\"SessionID\" = {$this->session->ID} AND \"ID\" = {$stepID}");
} elseif($this->session->CurrentStepID) { } elseif($this->session->CurrentStepID) {
$currentStep = $this->session->CurrentStep(); $currentStep = $this->session->CurrentStep();
} }
// 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 = Object::create($startStepClass);
@ -194,15 +194,15 @@ abstract class MultiForm extends Form {
$this->session->write(); $this->session->write();
$this->session->flushCache(); $this->session->flushCache();
} }
if($currentStep) $currentStep->setForm($this); if($currentStep) $currentStep->setForm($this);
return $currentStep; return $currentStep;
} }
/** /**
* Set the step passed in as the current step. * Set the step passed in as the current step.
* *
* @param MultiFormStep $step A subclass of MultiFormStep * @param MultiFormStep $step A subclass of MultiFormStep
* @return boolean The return value of write() * @return boolean The return value of write()
*/ */
@ -212,54 +212,54 @@ abstract class MultiForm extends Form {
return $this->session->write(); return $this->session->write();
} }
/** /**
* Accessor method to $this->session. * Accessor method to $this->session.
* *
* @return MultiFormSession * @return MultiFormSession
*/ */
public function getSession() { public function getSession() {
return $this->session; return $this->session;
} }
/** /**
* Set up the session. * Set up the session.
* *
* If MultiFormSessionID isn't set, we assume that this is a new * If MultiFormSessionID isn't set, we assume that this is a new
* multiform that requires a new session record to be created. * multiform that requires a new session record to be created.
* *
* @TODO Fix the fact you can continually refresh and create new records * @TODO Fix the fact you can continually refresh and create new records
* if MultiFormSessionID isn't set. * if MultiFormSessionID isn't set.
* *
* @TODO Not sure if we should bake the session stuff directly into MultiForm. * @TODO Not sure if we should bake the session stuff directly into MultiForm.
* Perhaps it would be best dealt with on a separate class? * Perhaps it would be best dealt with on a separate class?
*/ */
protected function setSession() { protected function setSession() {
$this->session = $this->getCurrentSession(); $this->session = $this->getCurrentSession();
// 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 = new MultiFormSession(); $this->session = new MultiFormSession();
} }
// Create encrypted identification to the session instance if it doesn't exist // Create encrypted identification to the session instance if it doesn't exist
if(!$this->session->Hash) { if(!$this->session->Hash) {
$this->session->Hash = sha1($this->session->ID . '-' . microtime()); $this->session->Hash = sha1($this->session->ID . '-' . microtime());
$this->session->write(); $this->session->write();
} }
} }
/** /**
* Set the currently used encrypted hash to identify * Set the currently used encrypted hash to identify
* the MultiFormSession. * the MultiFormSession.
* *
* @param string $hash Encrypted identification to session * @param string $hash Encrypted identification to session
*/ */
public function setCurrentSessionHash($hash) { public function setCurrentSessionHash($hash) {
$this->currentSessionHash = $hash; $this->currentSessionHash = $hash;
$this->setSession(); $this->setSession();
} }
/** /**
* Return the currently used {@link MultiFormSession} * Return the currently used {@link MultiFormSession}
* @return MultiFormSession|boolean FALSE * @return MultiFormSession|boolean FALSE
@ -280,13 +280,13 @@ abstract class MultiForm extends Form {
return $this->session; return $this->session;
} }
/** /**
* Get all steps saved in the database for the currently active session, * Get all steps saved in the database for the currently active session,
* in the order they were saved, oldest to newest (automatically ordered by ID). * in the order they were saved, oldest to newest (automatically ordered by ID).
* If you want a full chain of steps regardless if they've already been saved * If you want a full chain of steps regardless if they've already been saved
* 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 DataObjectSet|boolean A set of MultiFormStep subclasses
*/ */
@ -295,18 +295,18 @@ abstract class MultiForm extends Form {
$filter .= sprintf("\"SessionID\" = '%s'", $this->session->ID); $filter .= sprintf("\"SessionID\" = '%s'", $this->session->ID);
return DataObject::get('MultiFormStep', $filter); return DataObject::get('MultiFormStep', $filter);
} }
/** /**
* Get a step which was previously saved to the database in the current session. * Get a step which was previously saved to the database in the current session.
* Caution: This might cause unexpected behaviour if you have multiple steps * Caution: This might cause unexpected behaviour if you have multiple steps
* 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 MultiFormStep
*/ */
function getSavedStepByClass($className) { function getSavedStepByClass($className) {
return DataObject::get_one( return DataObject::get_one(
'MultiFormStep', 'MultiFormStep',
sprintf("\"SessionID\" = '%s' AND \"ClassName\" = '%s'", sprintf("\"SessionID\" = '%s' AND \"ClassName\" = '%s'",
$this->session->ID, $this->session->ID,
Convert::raw2sql($className) Convert::raw2sql($className)
@ -336,7 +336,7 @@ abstract class MultiForm extends Form {
function actionsFor($step) { 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 = (class_exists('FieldList')) ? new FieldList() : new FieldSet();
// 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()) {
@ -344,7 +344,7 @@ abstract class MultiForm extends Form {
} else { } else {
$actions->push(new FormAction('next', $step->getNextText())); $actions->push(new FormAction('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
@ -358,10 +358,10 @@ abstract class MultiForm extends Form {
// Merge any extra action fields defined on the step // Merge any extra action fields defined on the step
$actions->merge($step->getExtraActions()); $actions->merge($step->getExtraActions());
return $actions; return $actions;
} }
/** /**
* Return a rendered version of this form, with a specific template. * Return a rendered version of this form, with a specific template.
* Looks through the step ancestory templates (MultiFormStep, current step * Looks through the step ancestory templates (MultiFormStep, current step
@ -384,13 +384,13 @@ abstract class MultiForm extends Form {
return $return; 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)
* so you can create your own functionality which handles saving * so you can create your own functionality which handles saving
* 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 object $form The form that the action was called on
*/ */
@ -410,15 +410,15 @@ abstract class MultiForm extends Form {
} }
} }
/** /**
* Determine what to do when the next action is called. * Determine what to do when the next action is called.
* *
* Saves the current step session data to the database, creates the * Saves the current step session data to the database, creates the
* new step based on getNextStep() of the current step (or fetches * new step based on getNextStep() of the current step (or fetches
* an existing one), resets the current step to the next step, * an existing one), resets the current step to the next step,
* 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 object $form The form that the action was called on
*/ */
@ -428,7 +428,7 @@ abstract class MultiForm extends Form {
// Get the next step class // Get the next step class
$nextStepClass = $this->getCurrentStep()->getNextStep(); $nextStepClass = $this->getCurrentStep()->getNextStep();
if(!$nextStepClass) { if(!$nextStepClass) {
$this->controller->redirectBack(); $this->controller->redirectBack();
return false; return false;
@ -455,18 +455,18 @@ abstract class MultiForm extends Form {
// Set the next step found as the current step // Set the next step found as the current step
$this->setCurrentStep($nextStep); $this->setCurrentStep($nextStep);
// Redirect to the next step // Redirect to the next step
$this->controller->redirect($nextStep->Link()); $this->controller->redirect($nextStep->Link());
} }
/** /**
* Determine what to do when the previous action is called. * Determine what to do when the previous action is called.
* *
* Retrieves the previous step class, finds the record for that * Retrieves the previous step class, finds the record for that
* class in the DB, and sets the current step to that step found. * class in the DB, and sets the current step to that step found.
* 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 object $form The form that the action was called on
*/ */
@ -484,21 +484,21 @@ abstract class MultiForm extends Form {
// Get the previous step of the class instance returned from $currentStep->getPreviousStep() // Get the previous step of the class instance returned from $currentStep->getPreviousStep()
$prevStep = DataObject::get_one($prevStepClass, "\"SessionID\" = {$this->session->ID}"); $prevStep = DataObject::get_one($prevStepClass, "\"SessionID\" = {$this->session->ID}");
// Set the current step as the previous step // Set the current step as the previous step
$this->setCurrentStep($prevStep); $this->setCurrentStep($prevStep);
// Redirect to the previous step // Redirect to the previous step
$this->controller->redirect($prevStep->Link()); $this->controller->redirect($prevStep->Link());
} }
/** /**
* Save the raw data given back from the form into session. * Save the raw data given back from the form into session.
* *
* Take the submitted form data for the current step, removing * Take the submitted form data for the current step, removing
* any key => value pairs that shouldn't be saved, then saves * any key => value pairs that shouldn't be saved, then saves
* the data into the session. * the data into the session.
* *
* @param array $data An array of data to save * @param array $data An array of data to save
*/ */
protected function save($data) { protected function save($data) {
@ -513,21 +513,21 @@ abstract class MultiForm extends Form {
} }
return; return;
} }
// ############ Misc ############ // ############ Misc ############
/** /**
* Add the MultiFormSessionID variable to the URL on form submission. * Add the MultiFormSessionID variable to the URL on form submission.
* This is a means to persist the session, by adding it's identification * This is a means to persist the session, by adding it's identification
* to the URL, which ties it back to this MultiForm instance. * to the URL, which ties it back to this MultiForm instance.
* *
* @return string * @return string
*/ */
function FormAction() { function FormAction() {
$action = parent::FormAction(); $action = parent::FormAction();
$action .= (strpos($action, '?')) ? '&amp;' : '?'; $action .= (strpos($action, '?')) ? '&amp;' : '?';
$action .= "MultiFormSessionID={$this->session->Hash}"; $action .= "MultiFormSessionID={$this->session->Hash}";
return $action; return $action;
} }
@ -563,17 +563,17 @@ abstract class MultiForm extends Form {
*/ */
public function getAllStepsLinear() { public function getAllStepsLinear() {
$stepsFound = (class_exists('ArrayList')) ? new ArrayList() : new DataObjectSet(); $stepsFound = (class_exists('ArrayList')) ? new ArrayList() : new DataObjectSet();
$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';
$firstStep->setForm($this); $firstStep->setForm($this);
$stepsFound->push($firstStep); $stepsFound->push($firstStep);
$this->getAllStepsRecursive($firstStep, $stepsFound); $this->getAllStepsRecursive($firstStep, $stepsFound);
return $stepsFound; return $stepsFound;
} }
/** /**
* Recursively run through steps using the getNextStep() method on each step * Recursively run through steps using the getNextStep() method on each step
* to determine what the next step is, gathering each step along the way. * to determine what the next step is, gathering each step along the way.
@ -581,7 +581,7 @@ abstract class MultiForm extends Form {
* If a step in the chain was already saved to the database in the current * If a step in the chain was already saved to the database in the current
* 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 $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 DataObjectSet of MultiFormStep instances
@ -595,7 +595,7 @@ abstract class MultiForm extends Form {
if(!$nextStep) { if(!$nextStep) {
// If it's not in the DB, we use a singleton instance of it instead - this step hasn't been accessed yet // If it's not in the DB, we use a singleton instance of it instead - this step hasn't been accessed yet
$nextStep = singleton($step->getNextStep()); $nextStep = singleton($step->getNextStep());
} }
$nextStep->LinkingMode = ($nextStep->ID == $this->getCurrentStep()->ID) ? 'current' : 'link'; $nextStep->LinkingMode = ($nextStep->ID == $this->getCurrentStep()->ID) ? 'current' : 'link';
$nextStep->setForm($this); $nextStep->setForm($this);
// Add the array data, and do a callback // Add the array data, and do a callback
@ -607,23 +607,23 @@ abstract class MultiForm extends Form {
return $stepsFound; return $stepsFound;
} }
} }
/** /**
* Number of steps already completed (excluding currently started step). * Number of steps already completed (excluding currently started step).
* The way we determine a step is complete is to check if it has the Data * The way we determine a step is complete is to check if it has the Data
* field filled out with a serialized value, then we know that the user has * field filled out with a serialized value, then we know that the user has
* clicked next on the given step, to proceed. * clicked next on the given step, to proceed.
* *
* @TODO Not sure if it's entirely appropriate to check if Data is set as a * @TODO Not sure if it's entirely appropriate to check if Data is set as a
* way to determine a step is "completed". * way to determine a step is "completed".
* *
* @return int * @return int
*/ */
public function getCompletedStepCount() { public function getCompletedStepCount() {
$steps = DataObject::get('MultiFormStep', "\"SessionID\" = {$this->session->ID} && \"Data\" IS NOT NULL"); $steps = DataObject::get('MultiFormStep', "\"SessionID\" = {$this->session->ID} && \"Data\" IS NOT NULL");
return $steps ? $steps->Count() : 0; return $steps ? $steps->Count() : 0;
} }
/** /**
* Total number of steps in the shortest path (only counting straight path without any branching) * Total number of steps in the shortest path (only counting straight path without any branching)
* The way we determine this is to check if each step has a next_step string variable set. If it's * The way we determine this is to check if each step has a next_step string variable set. If it's
@ -634,7 +634,7 @@ abstract class MultiForm extends Form {
public function getTotalStepCount() { public function getTotalStepCount() {
return $this->getAllStepsLinear() ? $this->getAllStepsLinear()->Count() : 0; return $this->getAllStepsLinear() ? $this->getAllStepsLinear()->Count() : 0;
} }
/** /**
* Percentage of steps completed (excluding currently started step) * Percentage of steps completed (excluding currently started step)
* *

View File

@ -1,22 +1,22 @@
<?php <?php
/** /**
* Serializes one or more {@link MultiFormStep}s into * Serializes one or more {@link MultiFormStep}s into
* a database object. * a database object.
* *
* MultiFormSession also stores the current step, so that * MultiFormSession also stores the current step, so that
* the {@link MultiForm} and {@link MultiFormStep} classes * the {@link MultiForm} and {@link MultiFormStep} classes
* know what the current step is. * know what the current step is.
* *
* @package multiform * @package multiform
*/ */
class MultiFormSession extends DataObject { class MultiFormSession extends DataObject {
private static $db = array( 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 = array(
'Submitter' => 'Member', 'Submitter' => 'Member',
'CurrentStep' => 'MultiFormStep' 'CurrentStep' => 'MultiFormStep'
@ -25,10 +25,10 @@ class MultiFormSession extends DataObject {
private static $has_many = array( private static $has_many = array(
'FormSteps' => 'MultiFormStep' 'FormSteps' => 'MultiFormStep'
); );
/** /**
* Mark this session as completed. * Mark this session as completed.
* *
* This sets the flag "IsComplete" to true, * This sets the flag "IsComplete" to true,
* and writes the session back. * and writes the session back.
*/ */
@ -36,7 +36,7 @@ class MultiFormSession extends DataObject {
$this->IsComplete = 1; $this->IsComplete = 1;
$this->write(); $this->write();
} }
/** /**
* These actions are performed when write() is called on this object. * These actions are performed when write() is called on this object.
*/ */
@ -44,7 +44,7 @@ class MultiFormSession extends DataObject {
// save submitter if a Member is logged in // save submitter if a Member is logged in
$currentMember = Member::currentUser(); $currentMember = Member::currentUser();
if(!$this->SubmitterID && $currentMember) $this->SubmitterID = $currentMember->ID; if(!$this->SubmitterID && $currentMember) $this->SubmitterID = $currentMember->ID;
parent::onBeforeWrite(); parent::onBeforeWrite();
} }
@ -61,7 +61,7 @@ class MultiFormSession extends DataObject {
$step->destroy(); $step->destroy();
} }
} }
parent::onBeforeDelete(); parent::onBeforeDelete();
} }

View File

@ -6,7 +6,7 @@
* encapsulates the functionality required for the step to be aware of itself * encapsulates the functionality required for the step to be aware of itself
* in the process by knowing what it's next step is, and if applicable, it's previous * in the process by knowing what it's next step is, and if applicable, it's previous
* step. * step.
* *
* @package multiform * @package multiform
*/ */
class MultiFormStep extends DataObject { class MultiFormStep extends DataObject {
@ -14,14 +14,14 @@ class MultiFormStep extends DataObject {
private static $db = array( 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 = array(
'Session' => 'MultiFormSession' 'Session' => 'MultiFormSession'
); );
/** /**
* Centerpiece of the flow control for the form. * Centerpiece of the flow control for the form.
* *
* If set to a string, you have a linear form flow * If set to a string, you have a linear form flow
* If set to an array, you should use {@link getNextStep()} * If set to an array, you should use {@link getNextStep()}
* to enact flow control and branching to different form * to enact flow control and branching to different form
@ -31,7 +31,7 @@ class MultiFormStep extends DataObject {
* @var array|string * @var array|string
*/ */
public static $next_steps; public static $next_steps;
/** /**
* Each {@link MultiForm} subclass needs at least * Each {@link MultiForm} subclass needs at least
* one step which is marked as the "final" one * one step which is marked as the "final" one
@ -45,7 +45,7 @@ class MultiFormStep extends DataObject {
/** /**
* This variable determines whether a user can use * This variable determines whether a user can use
* the "back" action from this step. * the "back" action from this step.
* *
* @TODO This does not check if the arbitrarily chosen step * @TODO This does not check if the arbitrarily chosen step
* using the step indicator is actually a previous step, so * using the step indicator is actually a previous step, so
* unless you remove the link from the indicator template, or * unless you remove the link from the indicator template, or
@ -55,23 +55,23 @@ class MultiFormStep extends DataObject {
* @var boolean * @var boolean
*/ */
protected static $can_go_back = true; protected static $can_go_back = true;
/** /**
* Title of this step. * Title of this step.
* *
* Used for the step indicator templates. * Used for the step indicator templates.
* *
* @var string * @var string
*/ */
protected $title; protected $title;
/** /**
* Form class that this step is directly related to. * Form class that this step is directly related to.
* *
* @var MultiForm subclass * @var MultiForm subclass
*/ */
protected $form; protected $form;
/** /**
* Form fields to be rendered with this step. * Form fields to be rendered with this step.
* (Form object is created in {@link MultiForm}. * (Form object is created in {@link MultiForm}.
@ -84,7 +84,7 @@ class MultiFormStep extends DataObject {
public function getFields() { public function getFields() {
user_error('Please implement getFields on your MultiFormStep subclass', E_USER_ERROR); user_error('Please implement getFields on your MultiFormStep subclass', E_USER_ERROR);
} }
/** /**
* Additional form actions to be added to this step. * Additional form actions to be added to this step.
* (Form object is created in {@link MultiForm}. * (Form object is created in {@link MultiForm}.
@ -97,26 +97,26 @@ class MultiFormStep extends DataObject {
public function getExtraActions() { public function getExtraActions() {
return (class_exists('FieldList')) ? new FieldList() : new FieldSet(); return (class_exists('FieldList')) ? new FieldList() : new FieldSet();
} }
/** /**
* 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 Validator
*/ */
public function getValidator() { public function getValidator() {
return false; return false;
} }
/** /**
* Accessor method for $this->title * Accessor method for $this->title
* *
* @return string Title of this step * @return string Title of this step
*/ */
public function getTitle() { public function getTitle() {
return $this->title ? $this->title : $this->class; return $this->title ? $this->title : $this->class;
} }
/** /**
* Gets a direct link to this step (only works * Gets a direct link to this step (only works
* if you're allowed to skip steps, or this step * if you're allowed to skip steps, or this step
@ -133,21 +133,21 @@ class MultiFormStep extends DataObject {
* Unserialize stored session data and return it. * Unserialize stored session data and return it.
* This is used for loading data previously saved * This is used for loading data previously saved
* in session back into the form. * in session back into the form.
* *
* You need to overload this method onto your own * You need to overload this method onto your own
* step if you require custom loading. An example * step if you require custom loading. An example
* would be selective loading specific fields, leaving * would be selective loading specific fields, leaving
* others that are not required. * others that are not required.
* *
* @return array * @return array
*/ */
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) : array();
} }
/** /**
* Save the data for this step into session, serializing it first. * Save the data for this step into session, serializing it first.
* *
* To selectively save fields, instead of it all, this * To selectively save fields, instead of it all, this
* method would need to be overloaded on your step class. * method would need to be overloaded on your step class.
* *
@ -157,7 +157,7 @@ class MultiFormStep extends DataObject {
$this->Data = serialize($data); $this->Data = serialize($data);
$this->write(); $this->write();
} }
/** /**
* Save the data on this step into an object, * Save the data on this step into an object,
* similiar to {@link Form->saveInto()} - by building * similiar to {@link Form->saveInto()} - by building
@ -180,7 +180,7 @@ class MultiFormStep extends DataObject {
$form->saveInto($obj); $form->saveInto($obj);
return $obj; return $obj;
} }
/** /**
* Custom validation for a step. In most cases, it should be sufficient * Custom validation for a step. In most cases, it should be sufficient
* to have built-in validation through the {@link Validator} class * to have built-in validation through the {@link Validator} class
@ -197,10 +197,10 @@ class MultiFormStep extends DataObject {
public function validateStep($data, $form) { public function validateStep($data, $form) {
return true; return true;
} }
/** /**
* Returns the first value of $next_step * Returns the first value of $next_step
* *
* @return String Classname of a {@link MultiFormStep} subclass * @return String Classname of a {@link MultiFormStep} subclass
*/ */
public function getNextStep() { public function getNextStep() {
@ -210,7 +210,7 @@ class MultiFormStep extends DataObject {
if(!$this->isFinalStep()) { if(!$this->isFinalStep()) {
if(!isset($nextSteps)) user_error('MultiFormStep->getNextStep(): Please define at least one $next_steps on ' . $this->class, E_USER_ERROR); if(!isset($nextSteps)) user_error('MultiFormStep->getNextStep(): Please define at least one $next_steps on ' . $this->class, E_USER_ERROR);
} }
if(is_string($nextSteps)) { if(is_string($nextSteps)) {
return $nextSteps; return $nextSteps;
} elseif(is_array($nextSteps) && count($nextSteps)) { } elseif(is_array($nextSteps) && count($nextSteps)) {
@ -223,10 +223,10 @@ class MultiFormStep extends DataObject {
/** /**
* Returns the next step to the current step in the database. * Returns the next step to the current step in the database.
* *
* This will only return something if you've previously visited * This will only return something if you've previously visited
* the step ahead of the current step, and then gone back a step. * the step ahead of the current step, and then gone back a step.
* *
* @return MultiFormStep|boolean * @return MultiFormStep|boolean
*/ */
public function getNextStepFromDatabase() { public function getNextStepFromDatabase() {
@ -242,22 +242,22 @@ class MultiFormStep extends DataObject {
} }
} }
} }
/** /**
* Accessor method for self::$next_steps * Accessor method for self::$next_steps
* *
* @return string|array * @return string|array
*/ */
public function getNextSteps() { public function getNextSteps() {
return static::$next_steps; return static::$next_steps;
} }
/** /**
* Returns the previous step, if there is one. * Returns the previous step, if there is one.
* *
* To determine if there is a previous step, we check the database to see if there's * To determine if there is a previous step, we check the database to see if there's
* a previous step for this multi form session ID. * a previous step for this multi form session ID.
* *
* @return String Classname of a {@link MultiFormStep} subclass * @return String Classname of a {@link MultiFormStep} subclass
*/ */
public function getPreviousStep() { public function getPreviousStep() {
@ -274,7 +274,7 @@ class MultiFormStep extends DataObject {
} }
} }
} }
/** /**
* Retrieves the previous step class record from the database. * Retrieves the previous step class record from the database.
* *
@ -320,26 +320,26 @@ class MultiFormStep extends DataObject {
public function setForm($form) { public function setForm($form) {
$this->form = $form; $this->form = $form;
} }
/** /**
* @return Form * @return Form
*/ */
public function getForm() { public function getForm() {
return $this->form; return $this->form;
} }
// ##################### Utility #################### // ##################### Utility ####################
/** /**
* Determines whether the user is able to go back using the "action_back" * Determines whether the user is able to go back using the "action_back"
* form action, based on the boolean value of $can_go_back. * form action, based on the boolean value of $can_go_back.
* *
* @return boolean * @return boolean
*/ */
public function canGoBack() { public function canGoBack() {
return static::$can_go_back; return static::$can_go_back;
} }
/** /**
* Determines whether this step is the final step in the multi-step process or not, * Determines whether this step is the final step in the multi-step process or not,
* based on the variable $is_final_step - which must be defined on at least one step. * based on the variable $is_final_step - which must be defined on at least one step.
@ -349,17 +349,17 @@ class MultiFormStep extends DataObject {
public function isFinalStep() { public function isFinalStep() {
return static::$is_final_step; return static::$is_final_step;
} }
/** /**
* Determines whether the currently viewed step is the current step set in the session. * Determines whether the currently viewed step is the current step set in the session.
* This assumes you are checking isCurrentStep() against a data record of a MultiFormStep * This assumes you are checking isCurrentStep() against a data record of a MultiFormStep
* subclass, otherwise it doesn't work. An example of this is using a singleton instance - it won't * subclass, otherwise it doesn't work. An example of this is using a singleton instance - it won't
* work because there's no data. * work because there's no data.
* *
* @return boolean * @return boolean
*/ */
public function isCurrentStep() { public function isCurrentStep() {
return ($this->class == $this->Session()->CurrentStep()->class) ? true : false; return ($this->class == $this->Session()->CurrentStep()->class) ? true : false;
} }
} }

View File

@ -2,29 +2,29 @@
/** /**
* Task to clean out all {@link MultiFormSession} objects from the database. * Task to clean out all {@link MultiFormSession} objects from the database.
* *
* Setup Instructions: * Setup Instructions:
* You need to create an automated task for your system (cronjobs on unix) * You need to create an automated task for your system (cronjobs on unix)
* which triggers the process() method through cli-script.php: * which triggers the process() method through cli-script.php:
* `php framework/cli-script.php MultiFormPurgeTask` * `php framework/cli-script.php MultiFormPurgeTask`
* or * or
* `framework/sake MultiFormPurgeTask` * `framework/sake MultiFormPurgeTask`
* *
* @package multiform * @package multiform
*/ */
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.
* *
* @var int * @var int
*/ */
public static $session_expiry_days = 7; public static $session_expiry_days = 7;
/** /**
* Run this cron task. * Run this cron task.
* *
* Go through all MultiFormSession records that * Go through all MultiFormSession records that
* are older than the days specified in $session_expiry_days * are older than the days specified in $session_expiry_days
* and delete them. * and delete them.
@ -51,5 +51,5 @@ class MultiFormPurgeTask extends BuildTask {
"DATEDIFF(NOW(), \"MultiFormSession\".\"Created\") > " . self::$session_expiry_days "DATEDIFF(NOW(), \"MultiFormSession\".\"Created\") > " . self::$session_expiry_days
); );
} }
} }

View File

@ -2,7 +2,7 @@
/** /**
* 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) * - MultiFormTest_Controller (simulation of a real Controller class)
* - MultiFormTest_Form (subclass of MultiForm) * - MultiFormTest_Form (subclass of MultiForm)
* - MultiFormTest_StepOne (subclass of MultiFormStep) * - MultiFormTest_StepOne (subclass of MultiFormStep)
@ -13,54 +13,54 @@
* of the multiform module - for example, MultiFormTest_Controller * of the multiform module - for example, MultiFormTest_Controller
* 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.
* *
* @package multiform * @package multiform
* @subpackage tests * @subpackage tests
*/ */
class MultiFormTest extends FunctionalTest { class MultiFormTest extends FunctionalTest {
public static $fixture_file = 'multiform/tests/MultiFormTest.yml'; public static $fixture_file = 'multiform/tests/MultiFormTest.yml';
protected $controller; protected $controller;
function setUp() { function setUp() {
parent::setUp(); parent::setUp();
$this->controller = new MultiFormTest_Controller(); $this->controller = new MultiFormTest_Controller();
$this->form = $this->controller->Form(); $this->form = $this->controller->Form();
} }
function testInitialisingForm() { function testInitialisingForm() {
$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('MultiFormTest_StepOne', $this->form->getStartStep());
} }
function testSessionGeneration() { function testSessionGeneration() {
$this->assertTrue($this->form->session->ID > 0); $this->assertTrue($this->form->session->ID > 0);
} }
function testMemberLogging() { 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; $userId = Member::get_one("Member")->ID;
$this->session()->inst_set('loggedInAs', $userId); $this->session()->inst_set('loggedInAs', $userId);
$session = $this->form->session; $session = $this->form->session;
$session->write(); $session->write();
$this->assertEquals($userId, $session->SubmitterID); $this->assertEquals($userId, $session->SubmitterID);
} }
function testSecondStep() { function testSecondStep() {
$this->assertEquals('MultiFormTest_StepTwo', $this->form->getCurrentStep()->getNextStep()); $this->assertEquals('MultiFormTest_StepTwo', $this->form->getCurrentStep()->getNextStep());
} }
function testParentForm() { function testParentForm() {
$currentStep = $this->form->getCurrentStep(); $currentStep = $this->form->getCurrentStep();
$this->assertEquals($currentStep->getForm()->class, $this->form->class); $this->assertEquals($currentStep->getForm()->class, $this->form->class);
} }
function testTotalStepCount() { function testTotalStepCount() {
$this->assertEquals(3, $this->form->getAllStepsLinear()->Count()); $this->assertEquals(3, $this->form->getAllStepsLinear()->Count());
} }
@ -71,14 +71,14 @@ class MultiFormTest extends FunctionalTest {
$this->form->session->markCompleted(); $this->form->session->markCompleted();
$this->assertNull($this->form->getCurrentSession()); $this->assertNull($this->form->getCurrentSession());
} }
function testIncorrectSessionIdentifier() { function testIncorrectSessionIdentifier() {
$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->session);
} }
} }
/** /**
@ -90,7 +90,7 @@ class MultiFormTest_Controller extends Controller implements TestOnly {
function Link() { function Link() {
return 'MultiFormTest_Controller'; return 'MultiFormTest_Controller';
} }
public function Form($request = null) { public function Form($request = null) {
$form = new MultiFormTest_Form($this, 'Form'); $form = new MultiFormTest_Form($this, 'Form');
$form->setHTMLID('MultiFormTest_Form'); $form->setHTMLID('MultiFormTest_Form');
@ -105,7 +105,7 @@ class MultiFormTest_Controller extends Controller implements TestOnly {
class MultiFormTest_Form extends MultiForm implements TestOnly { class MultiFormTest_Form extends MultiForm implements TestOnly {
public static $start_step = 'MultiFormTest_StepOne'; public static $start_step = 'MultiFormTest_StepOne';
function getStartStep() { function getStartStep() {
return self::$start_step; return self::$start_step;
} }
@ -117,9 +117,9 @@ class MultiFormTest_Form extends MultiForm implements TestOnly {
* @subpackage tests * @subpackage tests
*/ */
class MultiFormTest_StepOne extends MultiFormStep implements TestOnly { class MultiFormTest_StepOne extends MultiFormStep implements TestOnly {
public static $next_steps = 'MultiFormTest_StepTwo'; public static $next_steps = 'MultiFormTest_StepTwo';
function getFields() { function getFields() {
$class = (class_exists('FieldList')) ? 'FieldList' : 'FieldSet'; $class = (class_exists('FieldList')) ? 'FieldList' : 'FieldSet';
return new $class( return new $class(
@ -135,9 +135,9 @@ class MultiFormTest_StepOne extends MultiFormStep implements TestOnly {
* @subpackage tests * @subpackage tests
*/ */
class MultiFormTest_StepTwo extends MultiFormStep implements TestOnly { class MultiFormTest_StepTwo extends MultiFormStep implements TestOnly {
public static $next_steps = 'MultiFormTest_StepThree'; public static $next_steps = 'MultiFormTest_StepThree';
function getFields() { function getFields() {
$class = (class_exists('FieldList')) ? 'FieldList' : 'FieldSet'; $class = (class_exists('FieldList')) ? 'FieldList' : 'FieldSet';
return new $class( return new $class(
@ -151,14 +151,14 @@ class MultiFormTest_StepTwo extends MultiFormStep implements TestOnly {
* @subpackage tests * @subpackage tests
*/ */
class MultiFormTest_StepThree extends MultiFormStep implements TestOnly { class MultiFormTest_StepThree extends MultiFormStep implements TestOnly {
public static $is_final_step = true; public static $is_final_step = true;
function getFields() { function getFields() {
$class = (class_exists('FieldList')) ? 'FieldList' : 'FieldSet'; $class = (class_exists('FieldList')) ? 'FieldList' : 'FieldSet';
return new $class( return new $class(
new TextField('Test', 'Anything else you\'d like to tell us?') new TextField('Test', 'Anything else you\'d like to tell us?')
); );
} }
} }