From 6fd952c737b9517f45c50a592f50aad7a4a2f65f Mon Sep 17 00:00:00 2001 From: Franco Springveldt Date: Mon, 15 May 2017 18:03:51 +1200 Subject: [PATCH] Adding extra filters (GreaterThan, LessThan, etc.) to Email Custom Rules (#590) --- code/model/UserDefinedForm.php | 1 + .../UserDefinedForm_EmailRecipient.php | 5 +- ...serDefinedForm_EmailRecipientCondition.php | 61 ++++++++++++++---- tests/UserDefinedFormTest.php | 2 +- ...efinedForm_EmailRecipientConditionTest.php | 64 +++++++++++++++++++ ...efinedForm_EmailRecipientConditionTest.yml | 39 +++++++++++ 6 files changed, 157 insertions(+), 15 deletions(-) create mode 100644 tests/UserDefinedForm_EmailRecipientConditionTest.php create mode 100644 tests/UserDefinedForm_EmailRecipientConditionTest.yml diff --git a/code/model/UserDefinedForm.php b/code/model/UserDefinedForm.php index 5835459..2d54379 100755 --- a/code/model/UserDefinedForm.php +++ b/code/model/UserDefinedForm.php @@ -275,6 +275,7 @@ SQL; // Filter by rules $recipients = $recipients->filterByCallback(function ($recipient) use ($data, $form) { + /** @var UserDefinedForm_EmailRecipient $recipient */ return $recipient->canSend($data, $form); }); diff --git a/code/model/recipients/UserDefinedForm_EmailRecipient.php b/code/model/recipients/UserDefinedForm_EmailRecipient.php index 79110f3..4b098d5 100644 --- a/code/model/recipients/UserDefinedForm_EmailRecipient.php +++ b/code/model/recipients/UserDefinedForm_EmailRecipient.php @@ -157,7 +157,7 @@ class UserDefinedForm_EmailRecipient extends DataObject $validEmailToFields->merge($multiOptionFields); } else { // To address cannot be unbound, so restrict to pre-defined lists - $validEmailToFields = $multiOptionFields; + $validEmailToFields = $multiOptionFields; } // Build fieldlist @@ -383,7 +383,8 @@ class UserDefinedForm_EmailRecipient extends DataObject // Check all rules $isAnd = $this->CustomRulesCondition === 'And'; foreach ($customRules as $customRule) { - $matches = $customRule->matches($data, $form); + /** @var UserDefinedForm_EmailRecipientCondition $customRule */ + $matches = $customRule->matches($data); if ($isAnd && !$matches) { return false; } diff --git a/code/model/recipients/UserDefinedForm_EmailRecipientCondition.php b/code/model/recipients/UserDefinedForm_EmailRecipientCondition.php index 8617bc3..97c21ed 100644 --- a/code/model/recipients/UserDefinedForm_EmailRecipientCondition.php +++ b/code/model/recipients/UserDefinedForm_EmailRecipientCondition.php @@ -5,6 +5,11 @@ * Declares a condition that determines whether an email can be sent to a given recipient * * @method UserDefinedForm_EmailRecipient Parent() + * + * @property Enum ConditionOption + * @property Varchar ConditionValue + * + * @method EditableFormField ConditionField */ class UserDefinedForm_EmailRecipientCondition extends DataObject { @@ -19,11 +24,15 @@ class UserDefinedForm_EmailRecipientCondition extends DataObject "IsBlank" => "Is blank", "IsNotBlank" => "Is not blank", "Equals" => "Equals", - "NotEquals" => "Doesn't equal" + "NotEquals" => "Doesn't equal", + "ValueLessThan" => "Less than", + "ValueLessThanEqual" => "Less than or equal", + "ValueGreaterThan" => "Greater than", + "ValueGreaterThanEqual" => "Greater than or equal" ); private static $db = array( - 'ConditionOption' => 'Enum("IsBlank,IsNotBlank,Equals,NotEquals")', + 'ConditionOption' => 'Enum("IsBlank,IsNotBlank,Equals,NotEquals,ValueLessThan,ValueLessThanEqual,ValueGreaterThan,ValueGreaterThanEqual")', 'ConditionValue' => 'Varchar' ); @@ -33,27 +42,55 @@ class UserDefinedForm_EmailRecipientCondition extends DataObject ); /** + * * Determine if this rule matches the given condition * - * @param array $data - * @param Form $form - * @return bool + * @param $data + * + * @return bool|null + * @throws LogicException */ - public function matches($data, $form) + public function matches($data) { $fieldName = $this->ConditionField()->Name; $fieldValue = isset($data[$fieldName]) ? $data[$fieldName] : null; + $conditionValue = $this->ConditionValue; + $result = null; switch ($this->ConditionOption) { case 'IsBlank': - return empty($fieldValue); + $result = empty($fieldValue); + break; case 'IsNotBlank': - return !empty($fieldValue); + $result = !empty($fieldValue); + break; + case 'ValueLessThan': + $result = ($fieldValue < $conditionValue); + break; + case 'ValueLessThanEqual': + $result = ($fieldValue <= $conditionValue); + break; + case 'ValueGreaterThan': + $result = ($fieldValue > $conditionValue); + break; + case 'ValueGreaterThanEqual': + $result = ($fieldValue >= $conditionValue); + break; + case 'NotEquals': + case 'Equals': + $result = is_array($fieldValue) + ? in_array($conditionValue, $fieldValue) + : $fieldValue == $conditionValue; + + if ($this->ConditionOption == 'NotEquals') { + $result = !($result); + } + break; default: - $matches = is_array($fieldValue) - ? in_array($this->ConditionValue, $fieldValue) - : $this->ConditionValue === (string) $fieldValue; - return ($this->ConditionOption === 'Equals') === (bool)$matches; + throw new LogicException("Unhandled rule {$this->ConditionOption}"); + break; } + + return $result; } /** diff --git a/tests/UserDefinedFormTest.php b/tests/UserDefinedFormTest.php index b3eece3..1948750 100644 --- a/tests/UserDefinedFormTest.php +++ b/tests/UserDefinedFormTest.php @@ -347,6 +347,7 @@ class UserDefinedFormTest extends FunctionalTest public function testEmailRecipientFilters() { + /** @var UserDefinedForm $form */ $form = $this->objFromFixture('UserDefinedForm', 'filtered-form-page'); // Check unfiltered recipients @@ -404,7 +405,6 @@ class UserDefinedFormTest extends FunctionalTest $result2 ); - $result3 = $form->FilteredEmailRecipients( array( 'your-name' => 'Should be blank but is not', diff --git a/tests/UserDefinedForm_EmailRecipientConditionTest.php b/tests/UserDefinedForm_EmailRecipientConditionTest.php new file mode 100644 index 0000000..7c6df3d --- /dev/null +++ b/tests/UserDefinedForm_EmailRecipientConditionTest.php @@ -0,0 +1,64 @@ +objFromFixture($fixtureClass, 'blankTest'); + $this->assertTrue($blankObj->matches(array('Name' => null))); + $this->assertFalse($blankObj->matches(array('Name' => 'Jane'))); + + //Test IsNotBlank + /** @var UserDefinedForm_EmailRecipientCondition $blankObj */ + $blankObj = $this->objFromFixture($fixtureClass, 'isNotBlankTest'); + $this->assertTrue($blankObj->matches(array('Name' => 'Jane'))); + $this->assertFalse($blankObj->matches(array('Name' => null))); + + //Test ValueLessthan + /** @var UserDefinedForm_EmailRecipientCondition $blankObj */ + $blankObj = $this->objFromFixture($fixtureClass, 'valueLessThanTest'); + $this->assertTrue($blankObj->matches(array('Age' => 17))); + $this->assertFalse($blankObj->matches(array('Age' => 19))); + + //Test ValueLessThanEquals + /** @var UserDefinedForm_EmailRecipientCondition $blankObj */ + $blankObj = $this->objFromFixture($fixtureClass, 'valueLessThanEqualTest'); + $this->assertTrue($blankObj->matches(array('Age' => 18))); + $this->assertFalse($blankObj->matches(array('Age' => 19))); + + //Test ValueGreaterThan + /** @var UserDefinedForm_EmailRecipientCondition $blankObj */ + $blankObj = $this->objFromFixture($fixtureClass, 'valueGreaterThanTest'); + $this->assertTrue($blankObj->matches(array('Age' => 19))); + $this->assertFalse($blankObj->matches(array('Age' => 17))); + + //Test ValueGreaterThanEquals + /** @var UserDefinedForm_EmailRecipientCondition $blankObj */ + $blankObj = $this->objFromFixture($fixtureClass, 'valueGreaterThanEqualTest'); + $this->assertTrue($blankObj->matches(array('Age' => 18))); + $this->assertFalse($blankObj->matches(array('Age' => 17))); + + //Test Equals + /** @var UserDefinedForm_EmailRecipientCondition $blankObj */ + $blankObj = $this->objFromFixture($fixtureClass, 'equalsTest'); + $this->assertTrue($blankObj->matches(array('Age' => 18))); + $this->assertFalse($blankObj->matches(array('Age' => 17))); + + //Test NotEquals + /** @var UserDefinedForm_EmailRecipientCondition $blankObj */ + $blankObj = $this->objFromFixture($fixtureClass, 'notEqualsTest'); + $this->assertTrue($blankObj->matches(array('Age' => 17))); + $this->assertFalse($blankObj->matches(array('Age' => 18))); + } +} diff --git a/tests/UserDefinedForm_EmailRecipientConditionTest.yml b/tests/UserDefinedForm_EmailRecipientConditionTest.yml new file mode 100644 index 0000000..bc34979 --- /dev/null +++ b/tests/UserDefinedForm_EmailRecipientConditionTest.yml @@ -0,0 +1,39 @@ +EditableTextField: + nameField: + Name: Name +EditableNumericField: + ageField: + Name: Age +UserDefinedForm_EmailRecipientCondition: + blankTest: + ConditionOption: IsBlank + ConditionValue: null + ConditionField: =>EditableTextField.nameField + isNotBlankTest: + ConditionOption: IsNotBlank + ConditionValue: null + ConditionField: =>EditableTextField.nameField + equalsTest: + ConditionOption: Equals + ConditionValue: 18 + ConditionField: =>EditableNumericField.ageField + notEqualsTest: + ConditionOption: NotEquals + ConditionValue: 18 + ConditionField: =>EditableNumericField.ageField + valueLessThanTest: + ConditionOption: ValueLessThan + ConditionValue: 18 + ConditionField: =>EditableNumericField.ageField + valueLessThanEqualTest: + ConditionOption: ValueLessThanEqual + ConditionValue: 18 + ConditionField: =>EditableNumericField.ageField + valueGreaterThanTest: + ConditionOption: ValueGreaterThan + ConditionValue: 18 + ConditionField: =>EditableNumericField.ageField + valueGreaterThanEqualTest: + ConditionOption: ValueGreaterThanEqual + ConditionValue: 18 + ConditionField: =>EditableNumericField.ageField \ No newline at end of file