Skip to content

Commit

Permalink
FIX for #4417: Ensuring ->removeValidation() is defined on instances …
Browse files Browse the repository at this point in the history
…of Validator. Setup new API for enabling/disabling validation. Documentation and better type handling.
  • Loading branch information
patricknelson committed Aug 27, 2015
1 parent 958f98b commit 9400ec9
Show file tree
Hide file tree
Showing 2 changed files with 101 additions and 10 deletions.
50 changes: 40 additions & 10 deletions forms/Validator.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* This validation class handles all form and custom form validation through
* the use of Required fields.
*
* Relies on javascript for client-side validation, and marking fields after serverside validation.
* Relies on javascript for client-side validation, and marking fields after server-side validation.
*
* Acts as a visitor to individual form fields.
*
Expand All @@ -21,7 +21,12 @@ abstract class Validator extends Object {
/**
* @var array $errors
*/
protected $errors;
protected $errors = array();

/**
* @var bool
*/
protected $enabled = true;

/**
* @param Form $form
Expand All @@ -37,13 +42,12 @@ public function setForm($form) {
/**
* Returns any errors there may be.
*
* @return null|array
* @return array
*/
public function validate() {
$this->errors = null;

$this->php($this->form->getData());

// Reset errors array (if already set).
$this->errors = array();
if ($this->enabled) $this->php($this->form->getData());
return $this->errors;
}

Expand Down Expand Up @@ -81,10 +85,12 @@ public function getErrors() {
}

/**
* @param string $fieldName
* @param array $data
* Ensures the specified field is not empty.
*
* @param string $fieldName The name of the valid you wish to ensure is not empty.
* @param array $data An array of field values you want to check against.
*/
public function requireField($fieldName, $data) {
public function requireField($fieldName, array $data) {
if(is_array($data[$fieldName]) && count($data[$fieldName])) {
foreach($data[$fieldName] as $componentKey => $componentValue) {
if(!strlen($componentValue)) {
Expand Down Expand Up @@ -116,9 +122,33 @@ public function fieldIsRequired($fieldName) {
}

/**
* Performs actual validation. Data from the form is passed into this method.
*
* @param array $data
*
* @return mixed
*/
abstract public function php($data);

/**
* Ensures your validator will not perform any validation at all, in case the current user doesn't have access to
* edit any fields (for example).
*
* @param bool $enabled
* @return static
*/
public function setEnabled($enabled) {
$this->enabled = (bool) $enabled;
return $this;
}

/**
* An alias to ->setEnabled(false) for backward compatibility.
*
* @return static
*/
public function removeValidation() {
$this->setEnabled(false);
return $this;
}
}
61 changes: 61 additions & 0 deletions tests/forms/ValidatorTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
<?php

/**
* @package framework
* @subpackage tests
*/

class ValidatorTest extends SapphireTest {

/**
* Common method for setting up form, since that will always be a dependency for the validator.
*
* @param array $fieldNames
* @return Form
*/
protected function getForm(array $fieldNames = array()) {
// Setup field list now. We're only worried about names right now.
$fieldList = new FieldList();
foreach($fieldNames as $name) {
$fieldList->add(new TextField($name));
}

return new Form(new Controller(), "testForm", $fieldList, new FieldList(array(/* no actions */)));
}


public function testRemoveValidation() {
$validator = new ValidatorTestExample();

// Setup a form with the fields/data we're testing (a form is a dependency for validation right now).
$data = array("foobar" => "");
$form = $this->getForm(array_keys($data)); // We only care right now about the fields we've got setup in this array.
$form->setValidator($validator); // Setup validator now that we've got our form.
$form->loadDataFrom($data); // Put data into the form so the validator can pull it back out again.

// Make sure it fails and that error results match ->getErrors().
$errors = $validator->validate();
$this->assertCount(1, $errors);
$this->assertEquals($validator->getErrors(), $errors);

// Make sure it doesn't fail after removing validation AND has no errors (since calling validate should reset errors).
$validator->removeValidation();
$errors = $validator->validate();
$this->assertEquals(array(), $errors);
}

}


class ValidatorTestExample extends Validator implements TestOnly {

/**
* Requires a specific field for test purposes.
*
* @param array $data
* @return null
*/
public function php($data) {
$this->requireField("foobar", $data);
}
}

0 comments on commit 9400ec9

Please sign in to comment.