Skip to content

Commit a5cf78c

Browse files
Merge pull request #3 from GuySartorelli/pulls/2/use-core-searchfilter-arraylist
ENH Use the core ArrayList Searchfilter functionality
2 parents a68ba45 + 83c8727 commit a5cf78c

File tree

6 files changed

+53
-23
lines changed

6 files changed

+53
-23
lines changed

CONTRIBUTING.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ try your hand at fixing it via [a pull request](https://github.com/guysartorelli
88

99
Any feature requests or recommendations should be raised as [an issue](https://github.com/guysartorelli/silverstripe-composable-validators/issues).
1010

11-
This module adheres to [the Silverstripe module standards](https://docs.silverstripe.org/en/4/developer_guides/extending/modules/#module-standard)
11+
This module adheres to [the Silverstripe module standards](https://docs.silverstripe.org/en/developer_guides/extending/modules/#module-standard)
1212
Commit messages should be [semantic](https://seesparkbox.com/foundry/semantic_commit_messages), though the style used for this module differs from that reference in the following ways:
1313

1414
- The first letter after the commit type is capitalized.

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ Like `ValidatesMultipleFields` but requires a configuration array for each field
6868
[10]: https://api.silverstripe.org/4/SilverStripe/Forms/RequiredFields.html
6969
[11]: docs/en/01-validators.md#warningfieldsvalidator
7070
[12]: docs/en/01-validators.md#dependentrequiredfieldsvalidator
71-
[13]: https://docs.silverstripe.org/en/4/developer_guides/model/searchfilters/
71+
[13]: https://docs.silverstripe.org/en/developer_guides/model/searchfilters/
7272
[14]: docs/en/01-validators.md#requiredblocksvalidator
7373
[15]: https://github.com/silverstripe/silverstripe-elemental
7474
[16]: docs/en/01-validators.md#regexfieldsvalidator

composer.json

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,7 @@
3838
},
3939
"require": {
4040
"php": "^8.1",
41-
"silverstripe/framework": "^5.0.17",
42-
"signify-nz/silverstripe-searchfilter-arraylist": "^1.1.0"
41+
"silverstripe/framework": "^5.1.0"
4342
},
4443
"require-dev": {
4544
"silverstripe/cms": "^5",
@@ -48,9 +47,6 @@
4847
"silverstripe/frameworktest": "^1",
4948
"silverstripe/recipe-testing": "^3"
5049
},
51-
"conflict": {
52-
"silverstripe/framework": ">=5.1.0"
53-
},
5450
"extra": {
5551
"expose": [
5652
"client/dist",

docs/en/01-validators.md

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ This validator is also extremely useful for front-end forms, as it provides clie
2020

2121
If the [`DataObjectDefaultAjaxExtension`](./02-extensions.md#dataobjectdefaultajaxextension) extension has been applied, calling `parent::getCMSCompositeValidator()` inside the `getCMSCompositeValidator()` method will return an `AjaxCompositeValidator`, which can then be manipulated.
2222

23-
You can also opt to just return a new `AjaxCompositeValidator` from that method - and in front-end situations, you can instantiate a new `AjaxCompositeValidator` (preferably [via injection](https://docs.silverstripe.org/en/4/developer_guides/extending/injector/) i.e. `AjaxCompositeValidator::create()`).
23+
You can also opt to just return a new `AjaxCompositeValidator` from that method - and in front-end situations, you can instantiate a new `AjaxCompositeValidator` (preferably [via injection](https://docs.silverstripe.org/en/developer_guides/extending/injector/) i.e. `AjaxCompositeValidator::create()`).
2424

2525
Ajax validation can also be disabled at any stage, if there is a cause for doing so.
2626

@@ -123,7 +123,7 @@ Displays a validation warning if the field(s) has no value.
123123

124124
## DependentRequiredFieldsValidator
125125

126-
Allows you to define fields as being required conditionally based on the values of other fields. It uses [`SearchFilters`](https://docs.silverstripe.org/en/4/developer_guides/model/searchfilters/) to provide a variety of ways to compare values, depending on what causes the fields to be required. It uses (so has all of the functionality and methods of) the [`ValidatesMultipleFieldsWithConfig`](#validatesmultiplefieldswithconfig) trait.
126+
Allows you to define fields as being required conditionally based on the values of other fields. It uses [`SearchFilters`](https://docs.silverstripe.org/en/developer_guides/model/searchfilters/) to provide a variety of ways to compare values, depending on what causes the fields to be required. It uses (so has all of the functionality and methods of) the [`ValidatesMultipleFieldsWithConfig`](#validatesmultiplefieldswithconfig) trait.
127127

128128
In the below example, we have fields with various levels of dependency on whether they are required or not.
129129

@@ -142,9 +142,7 @@ DependentRequiredFieldsValidator::create([
142142

143143
**Note:** All of the dependencies must be met for a field to be considered required. So in the example above, if `DependencyField` had the value "someValues" the `StartsEndsWithField` would not be marked required, because only one of its dependencies is met.
144144

145-
The conditional checking functionality is powered by [signify-nz/silverstripe-searchfilter-arraylist](https://github.com/signify-nz/silverstripe-searchfilter-arraylist), which does provide some extensibility. You may want to check the documentation of that module.
146-
147-
All of the `SearchFilter`s and modifiers documented in [Silverstripe's SearchFilter documentation](https://docs.silverstripe.org/en/4/developer_guides/model/searchfilters/) should be supported - if you find that isn't the case, please [raise an issue](https://github.com/signify-nz/silverstripe-searchfilter-arraylist/issues) (or, better yet, a pull request) against the `signify-nz/silverstripe-searchfilter-arraylist` module.
145+
All of the `SearchFilter`s and modifiers documented in [Silverstripe's SearchFilter documentation](https://docs.silverstripe.org/en/developer_guides/model/searchfilters/) should be supported - if you find that isn't the case, please [raise an issue](https://github.com/silverstripe/silverstripe-framework/issues) (or, better yet, a pull request) against the `siglverstripe/silverstripe-framework` module.
148146

149147
## RequiredBlocksValidator
150148

src/Validators/DependentRequiredFieldsValidator.php

Lines changed: 41 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,11 @@
33
namespace Signify\ComposableValidators\Validators;
44

55
use Signify\ComposableValidators\Traits\ValidatesMultipleFieldsWithConfig;
6-
use Signify\SearchFilterArrayList\SearchFilterableArrayList;
76
use SilverStripe\Core\ClassInfo;
7+
use SilverStripe\Core\Injector\Injector;
88
use SilverStripe\Forms\FieldList;
99
use SilverStripe\Forms\FormField;
10+
use SilverStripe\ORM\ArrayList;
1011
use SilverStripe\ORM\Filters\SearchFilter;
1112

1213
/**
@@ -49,7 +50,7 @@ public function php($data)
4950
$dependencyValue = $data[$dependencyFieldName];
5051
$tempObj = new \stdClass();
5152
$tempObj->$dependencyFieldName = $dependencyValue;
52-
$filterList = SearchFilterableArrayList::create([$tempObj]);
53+
$filterList = ArrayList::create([$tempObj]);
5354
$isRequired = $filterList->filter($filterKey, $filterValue)->count() !== 0;
5455
// If field is not required, we can stop processing it.
5556
if (!$isRequired) {
@@ -103,6 +104,42 @@ protected function validateField($data, FieldList $fields, string $fieldName, ar
103104
return true;
104105
}
105106

107+
/**
108+
* Ugly copypasta from SearchFilterable trait 'cause that's just easier.
109+
* Don't use the trait directly 'cause if new methods are added to that trait, we don't want them here.
110+
*/
111+
private function createSearchFilter($filter, $value)
112+
{
113+
// Field name is always the first component
114+
$fieldArgs = explode(':', $filter);
115+
$fieldName = array_shift($fieldArgs);
116+
$default = 'DataListFilter.default';
117+
118+
// Inspect type of second argument to determine context
119+
$secondArg = array_shift($fieldArgs);
120+
$modifiers = $fieldArgs;
121+
if (!$secondArg) {
122+
// Use default SearchFilter if none specified. E.g. `->filter(['Name' => $myname])`
123+
$filterServiceName = $default;
124+
} else {
125+
// The presence of a second argument is by default ambiguous; We need to query
126+
// Whether this is a valid modifier on the default filter, or a filter itself.
127+
/** @var SearchFilter $defaultFilterInstance */
128+
$defaultFilterInstance = Injector::inst()->get($default);
129+
if (in_array(strtolower($secondArg), $defaultFilterInstance->getSupportedModifiers() ?? [])) {
130+
// Treat second (and any subsequent) argument as modifiers, using default filter
131+
$filterServiceName = $default;
132+
array_unshift($modifiers, $secondArg);
133+
} else {
134+
// Second argument isn't a valid modifier, so assume is filter identifier
135+
$filterServiceName = "DataListFilter.{$secondArg}";
136+
}
137+
}
138+
139+
// Build instance
140+
return Injector::inst()->create($filterServiceName, $fieldName, $value, $modifiers);
141+
}
142+
106143
/**
107144
* Build the validation error message for a field based on its dependency filter.
108145
*
@@ -113,10 +150,9 @@ protected function validateField($data, FieldList $fields, string $fieldName, ar
113150
*/
114151
protected function buildValidationMessage(FieldList $fields, string $title, array $filter): string
115152
{
116-
$arrayList = SearchFilterableArrayList::create();
117153
$dependencies = [];
118154
foreach ($filter as $filterKey => $filterValue) {
119-
$filter = $arrayList->createSearchFilter($filterKey, $filterValue);
155+
$filter = $this->createSearchFilter($filterKey, $filterValue);
120156
$filterClass = get_class($filter);
121157
$dependencyField = $this->getFormField($fields, $filter->getName());
122158
$negated = in_array('not', $filter->getModifiers()) ? '_NEGATED' : '';
@@ -143,7 +179,7 @@ protected function buildValidationMessage(FieldList $fields, string $title, arra
143179
}
144180

145181
/**
146-
* Make a containing all values for a given dependency filter.
182+
* Make a string containing all values for a given dependency filter.
147183
*
148184
* @param SearchFilter $filter
149185
* @return string

tests/php/ValidatorTests/DependentRequiredFieldsValidatorTest.php

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@ class DependentRequiredFieldsValidatorTest extends SapphireTest
1616
* If the dependency is not met, the field should not be required.
1717
*
1818
* Note we do not need to test all SearchFilter dependency combinations, as
19-
* that functionality comes from the signify-nz/silverstripe-searchfilter-arraylist
20-
* module which has unit tests for that.
19+
* that functionality comes from silverstripe/framework which has its own testing
20+
* for that.
2121
*/
2222
public function testFieldNotRequiredIfDependencyNotMet(): void
2323
{
@@ -38,8 +38,8 @@ public function testFieldNotRequiredIfDependencyNotMet(): void
3838
* If the dependency is met, the field should be required.
3939
*
4040
* Note we do not need to test all SearchFilter dependency combinations, as
41-
* that functionality comes from the signify-nz/silverstripe-searchfilter-arraylist
42-
* module which has unit tests for that.
41+
* that functionality comes from silverstripe/framework which has its own testing
42+
* for that.
4343
*/
4444
public function testFieldRequiredIfDependencyMet(): void
4545
{
@@ -70,8 +70,8 @@ public function testFieldRequiredIfDependencyMet(): void
7070
* If the nullish dependency is met, the field should be required.
7171
*
7272
* Note we do not need to test all SearchFilter dependency combinations, as
73-
* that functionality comes from the signify-nz/silverstripe-searchfilter-arraylist
74-
* module which has unit tests for that.
73+
* that functionality comes from silverstripe/framework which has its own testing
74+
* for that.
7575
*/
7676
public function testFieldRequiredIfNullishDependencyMet(): void
7777
{

0 commit comments

Comments
 (0)