Merge remote-tracking branch 'origin/1.1'

# Conflicts:
#	.travis.yml
#	code/extensions/MultiFormObjectDecorator.php
#	code/model/MultiForm.php
#	composer.json
#	tests/MultiFormTest.php
This commit is contained in:
Damian Mooyman 2015-11-30 10:30:20 +13:00
commit 243caeb579
6 changed files with 107 additions and 16 deletions

View File

@ -24,15 +24,26 @@ class MultiFormObjectDecorator extends DataExtension {
'MultiFormSession' => 'MultiFormSession',
);
/**
* Augment any queries to MultiFormObjectDecorator and only
* return anything that isn't considered temporary.
*/
public function augmentSQL(SQLQuery &$query) {
// If you're querying by ID, ignore the sub-site - this is a bit ugly...
$where = $query->getWhere();
if(!$where && !$this->wantsTemporary($query)) {
$from = array_values($query->getFrom());
$query->addWhere("{$from[0]}.MultiFormIsTemporary = 0");
return;
}
if(
strpos($query->where[0], ".`ID` = ") === false
&& strpos($query->where[0], ".ID = ") === false
&& strpos($query->where[0], "ID = ") !== 0
strpos($where[0], ".`ID` = ") === false
&& strpos($where[0], ".ID = ") === false
&& strpos($where[0], "ID = ") !== 0
&& !$this->wantsTemporary($query)
) {
$query->where[] = "\"{$query->from[0]}\".\"MultiFormIsTemporary\" = 0";
$from = array_values($query->getFrom());
$query->addWhere("{$from[0]}.MultiFormIsTemporary = 0");
}
}
@ -45,8 +56,10 @@ class MultiFormObjectDecorator extends DataExtension {
* @return boolean
*/
protected function wantsTemporary($query) {
foreach($query->where as $whereClause) {
if($whereClause == "\"{$query->from[0]}\".\"MultiFormIsTemporary\" = 1") {
foreach($query->getWhere() as $whereClause) {
$from = array_values($query->getFrom());
// SQLQuery will automatically add double quotes and single quotes to values, so check against that.
if($whereClause == "{$from[0]}.\"MultiFormIsTemporary\" = '1'") {
return true;
}
}

View File

@ -50,6 +50,10 @@ abstract class MultiForm extends Form {
'CompletedPercent' => 'Float'
);
/**
* @var string
*/
private static $get_var = 'MultiFormSessionID';
/**
* 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
@ -60,7 +64,6 @@ abstract class MultiForm extends Form {
public static $ignored_fields = array(
'url',
'executeForm',
'MultiFormSessionID',
'SecurityID'
);
@ -146,8 +149,10 @@ abstract class MultiForm extends Form {
// Give the fields, actions, and validation for the current step back to the parent Form class
parent::__construct($controller, $name, $fields, $actions, $validator);
$getVar = $this->config()->get_var;
// 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($getVar, false, $this->session->Hash));
// If there is saved data for the current step, we load it into the form it here
//(CAUTION: loadData() MUST unserialize first!)
@ -157,6 +162,8 @@ abstract class MultiForm extends Form {
// Disable security token - we tie a form to a session ID instead
$this->disableSecurityToken();
self::$ignored_fields[] = $getVar;
}
/**
@ -277,7 +284,7 @@ abstract class MultiForm extends Form {
*/
public function getCurrentSession() {
if(!$this->currentSessionHash) {
$this->currentSessionHash = $this->controller->request->getVar('MultiFormSessionID');
$this->currentSessionHash = $this->controller->request->getVar($this->config()->get_var);
if(!$this->currentSessionHash) {
return false;
@ -360,11 +367,13 @@ abstract class MultiForm extends Form {
if($step->getPreviousStep() && $step->canGoBack()) {
// If there is a next step, insert the action before the next action
if($step->getNextStep()) {
$actions->insertBefore(new FormAction('prev', $step->getPrevText()), 'action_next');
$actions->insertBefore($prev = new FormAction('prev', $step->getPrevText()), 'action_next');
// Assume that this is the last step, insert the action before the finish action
} else {
$actions->insertBefore(new FormAction('prev', $step->getPrevText()), 'action_finish');
$actions->insertBefore($prev = new FormAction('prev', $step->getPrevText()), 'action_finish');
}
//remove browser validation from prev action
$prev->setAttribute("formnovalidate", "formnovalidate");
}
// Merge any extra action fields defined on the step
@ -536,7 +545,7 @@ abstract class MultiForm extends Form {
public function FormAction() {
$action = parent::FormAction();
$action .= (strpos($action, '?')) ? '&' : '?';
$action .= "MultiFormSessionID={$this->session->Hash}";
$action .= "{$this->config()->get_var}={$this->session->Hash}";
return $action;
}

View File

@ -133,7 +133,8 @@ class MultiFormStep extends DataObject {
* @return string Relative URL to this step
*/
public function Link() {
return Controller::join_links($this->form->getDisplayLink(), "?MultiFormSessionID={$this->Session()->Hash}");
$form = $this->form;
return Controller::join_links($form->getDisplayLink(), "?{$form->config()->get_var}={$this->Session()->Hash}");
}
/**

View File

@ -0,0 +1,44 @@
<?php
class MultiFormObjectDecoratorTest extends SapphireTest {
protected static $fixture_file = 'MultiFormObjectDecoratorTest.yml';
protected $requiredExtensions = array(
'MultiFormObjectDecorator_DataObject' => array('MultiFormObjectDecorator')
);
protected $extraDataObjects = array(
'MultiFormObjectDecorator_DataObject'
);
public function testTemporaryDataFilteredQuery() {
$records = MultiFormObjectDecorator_DataObject::get()
->map('Name')
->toArray();
$this->assertContains('Test 1', $records);
$this->assertContains('Test 2', $records);
$this->assertNotContains('Test 3', $records);
}
public function testTemporaryDataQuery() {
$records = MultiFormObjectDecorator_DataObject::get()
->filter(array('MultiFormIsTemporary' => 1))
->map('Name')
->toArray();
$this->assertNotContains('Test 1', $records);
$this->assertNotContains('Test 2', $records);
$this->assertContains('Test 3', $records);
}
}
class MultiFormObjectDecorator_DataObject extends DataObject {
private static $db = array(
'Name' => 'Varchar'
);
}

View File

@ -0,0 +1,10 @@
MultiFormObjectDecorator_DataObject:
test-data-1:
Name: Test 1
MultiFormIsTemporary: 0
test-data-2:
Name: Test 2
MultiFormIsTemporary: 0
test-data-3:
Name: Test 3
MultiFormIsTemporary: 1

View File

@ -79,6 +79,20 @@ class MultiFormTest extends FunctionalTest {
$this->assertInstanceOf('MultiFormSession', $this->form->session);
}
function testCustomGetVar() {
Config::nest();
Config::inst()->update('MultiForm', 'get_var', 'SuperSessionID');
$form = $this->controller->Form();
$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
ID parameter");
$this->assertContains('SuperSessionID', $form->getCurrentStep()->Link(), "Form step doesn't contain correct
session ID parameter");
Config::unnest();
}
}
/**
@ -129,7 +143,7 @@ class MultiFormTest_StepOne extends MultiFormStep implements TestOnly {
);
}
}
/**
* @package multiform
* @subpackage tests
@ -145,7 +159,7 @@ class MultiFormTest_StepTwo extends MultiFormStep implements TestOnly {
);
}
}
/**
* @package multiform
* @subpackage tests