diff --git a/composer.json b/composer.json index c4e1e7ecb8b..f982eb36dce 100644 --- a/composer.json +++ b/composer.json @@ -24,17 +24,17 @@ "require": { "php": "^8.3", "composer-runtime-api": "^2.0", - "composer/installers": "^2.2", - "guzzlehttp/guzzle": "^7.5.0", - "guzzlehttp/psr7": "^2.4.0", + "composer/installers": "^2.3", + "guzzlehttp/guzzle": "^7.9", + "guzzlehttp/psr7": "^2.7", "embed/embed": "^4.4.7", - "league/csv": "^9.8.0", + "league/csv": "^9.18", "m1/env": "^2.2.0", - "masterminds/html5": "^2.7.6", - "monolog/monolog": "^3.2.0", - "nikic/php-parser": "^5.1.0", - "psr/container": "^1.1 || ^2.0", - "psr/http-message": "^1", + "masterminds/html5": "^2.9", + "monolog/monolog": "^3.8", + "nikic/php-parser": "^5.3", + "psr/container": "^2.0", + "psr/http-message": "^2.0", "sebastian/diff": "^6.0", "sensiolabs/ansi-to-html": "^1.2", "silverstripe/config": "^3", diff --git a/src/Forms/FieldsValidator.php b/src/Forms/FieldsValidator.php deleted file mode 100644 index 5a70dd76f7e..00000000000 --- a/src/Forms/FieldsValidator.php +++ /dev/null @@ -1,37 +0,0 @@ -<?php - -namespace SilverStripe\Forms; - -use SilverStripe\Dev\Deprecation; - -/** - * Validates the internal state of all fields in the form. - * - * @deprecated 5.4.0 Will be replaced with functionality inside SilverStripe\Forms\Form::validate() - */ -class FieldsValidator extends Validator -{ - public function __construct() - { - Deprecation::noticeWithNoReplacment( - '5.4.0', - 'Will be replaced with functionality inside SilverStripe\Forms\Form::validate()', - Deprecation::SCOPE_CLASS - ); - parent::__construct(); - } - - public function php($data): bool - { - $fields = $this->form->Fields(); - foreach ($fields as $field) { - $this->result->combineAnd($field->validate()); - } - return $this->result->isValid(); - } - - public function canBeCached(): bool - { - return true; - } -} diff --git a/src/Forms/FileField.php b/src/Forms/FileField.php index a4db0fba7c3..fdeed0a59d7 100644 --- a/src/Forms/FileField.php +++ b/src/Forms/FileField.php @@ -33,7 +33,7 @@ * $actions = new FieldList( * new FormAction('doUpload', 'Upload file') * ); - * $validator = new RequiredFields(['MyName', 'MyFile']); + * $validator = new RequiredFieldsValidator(['MyName', 'MyFile']); * * return new Form($this, 'Form', $fields, $actions, $validator); * } diff --git a/src/Forms/Form.php b/src/Forms/Form.php index 5d25b4f543f..40d6f8c252a 100644 --- a/src/Forms/Form.php +++ b/src/Forms/Form.php @@ -20,6 +20,8 @@ use SilverStripe\View\AttributesHTML; use SilverStripe\View\SSViewer; use SilverStripe\Model\ModelData; +use SilverStripe\Forms\Validation\RequiredFieldsValidator; +use SilverStripe\Forms\Validation\Validator; /** * Base class for all forms. @@ -297,8 +299,10 @@ public function __construct( $this->setName($name); // Form validation - $this->validator = ($validator) ? $validator : new RequiredFields(); - $this->validator->setForm($this); + if ($validator) { + $this->validator = $validator; + $this->validator->setForm($this); + } // Form error controls $this->restoreFormState(); @@ -1262,17 +1266,23 @@ public function getLegend() */ public function validationResult() { - // Automatically pass if there is no validator, or the clicked button is exempt + $result = ValidationResult::create(); + // Automatically pass if the clicked button is exempt // Note: Soft support here for validation with absent request handler $handler = $this->getRequestHandler(); $action = $handler ? $handler->buttonClicked() : null; - $validator = $this->getValidator(); - if (!$validator || $this->actionIsValidationExempt($action)) { - return ValidationResult::create(); + if ($this->actionIsValidationExempt($action)) { + return $result; + } + // Invoke FormField validation + foreach ($this->Fields() as $field) { + $result->combineAnd($field->validate()); } - // Invoke validator - $result = $validator->validate(); + $validator = $this->getValidator(); + if ($validator) { + $result->combineAnd($validator->validate()); + } $this->loadMessagesFrom($result); return $result; } diff --git a/src/Forms/GridField/GridFieldDetailForm.php b/src/Forms/GridField/GridFieldDetailForm.php index 544f6221f3c..d80961e16dd 100644 --- a/src/Forms/GridField/GridFieldDetailForm.php +++ b/src/Forms/GridField/GridFieldDetailForm.php @@ -14,8 +14,7 @@ use SilverStripe\Core\Extensible; use SilverStripe\Core\Injector\Injector; use SilverStripe\Forms\FieldList; -use SilverStripe\Forms\FieldsValidator; -use SilverStripe\Forms\Validator; +use SilverStripe\Forms\Validation\Validator; use SilverStripe\ORM\DataList; use SilverStripe\ORM\DataObject; use SilverStripe\Model\ModelData; @@ -147,10 +146,8 @@ public function handleItem($gridField, $request) if (!$this->getValidator()) { if ($record->hasMethod('getCMSCompositeValidator')) { $validator = $record->getCMSCompositeValidator(); - } else { - $validator = FieldsValidator::create(); + $this->setValidator($validator); } - $this->setValidator($validator); } return $handler->handleRequest($request); diff --git a/src/Forms/GridField/GridFieldExportButton.php b/src/Forms/GridField/GridFieldExportButton.php index 6b543b8c49e..3f77b649236 100644 --- a/src/Forms/GridField/GridFieldExportButton.php +++ b/src/Forms/GridField/GridFieldExportButton.php @@ -2,6 +2,7 @@ namespace SilverStripe\Forms\GridField; +use League\Csv\Bom; use League\Csv\Writer; use LogicException; use SilverStripe\Control\HTTPRequest; @@ -180,8 +181,8 @@ public function generateExportFileData($gridField) $csvWriter = Writer::createFromFileObject(new \SplTempFileObject()); $csvWriter->setDelimiter($this->getCsvSeparator()); $csvWriter->setEnclosure($this->getCsvEnclosure()); - $csvWriter->setNewline("\r\n"); //use windows line endings for compatibility with some csv libraries - $csvWriter->setOutputBOM(Writer::BOM_UTF8); + $csvWriter->setEndOfLine("\r\n"); //use windows line endings for compatibility with some csv libraries + $csvWriter->setOutputBOM(Bom::Utf8); if (!Config::inst()->get(get_class($this), 'xls_export_disabled')) { $csvWriter->addFormatter(function (array $row) { @@ -269,11 +270,7 @@ public function generateExportFileData($gridField) } } - if (method_exists($csvWriter, 'getContent')) { - return $csvWriter->getContent(); - } - - return (string)$csvWriter; + return $csvWriter->toString(); } /** diff --git a/src/Forms/HasOneRelationFieldInterface.php b/src/Forms/HasOneRelationFieldInterface.php index b520cc9592a..e02451faf7c 100644 --- a/src/Forms/HasOneRelationFieldInterface.php +++ b/src/Forms/HasOneRelationFieldInterface.php @@ -4,7 +4,7 @@ /** * Added to form fields whose values are the ID of a has_one relation - * This is used in RequiredFields validation to check if the value is set + * This is used in RequiredFieldsValidator validation to check if the value is set */ interface HasOneRelationFieldInterface { diff --git a/src/Forms/CompositeValidator.php b/src/Forms/Validation/CompositeValidator.php similarity index 91% rename from src/Forms/CompositeValidator.php rename to src/Forms/Validation/CompositeValidator.php index 8864168d348..b77bed9559b 100644 --- a/src/Forms/CompositeValidator.php +++ b/src/Forms/Validation/CompositeValidator.php @@ -1,6 +1,6 @@ <?php -namespace SilverStripe\Forms; +namespace SilverStripe\Forms\Validation; use InvalidArgumentException; use SilverStripe\Core\Validation\ValidationResult; @@ -20,7 +20,7 @@ * { * $compositeValidator = parent::getCMSCompositeValidator(); * - * $compositeValidator->addValidator(RequiredFields::create(['MyRequiredField'])); + * $compositeValidator->addValidator(RequiredFieldsValidator::create(['MyRequiredField'])); * * return $compositeValidator * } @@ -29,9 +29,8 @@ * * protected function updateCMSCompositeValidator(CompositeValidator $compositeValidator): void * { - * $compositeValidator->addValidator(RequiredFields::create(['AdditionalContent'])); + * $compositeValidator->addValidator(RequiredFieldsValidator::create(['AdditionalContent'])); * } - * @deprecated 5.4.0 Will be renamed to SilverStripe\Forms\Validation\CompositeValidator */ class CompositeValidator extends Validator { @@ -47,11 +46,6 @@ class CompositeValidator extends Validator */ public function __construct(array $validators = []) { - Deprecation::noticeWithNoReplacment( - '5.4.0', - 'Will be renamed to SilverStripe\\Forms\\Validation\\CompositeValidator', - Deprecation::SCOPE_CLASS - ); $this->validators = array_values($validators ?? []); parent::__construct(); } @@ -106,7 +100,7 @@ public function validate() } /** - * Note: The existing implementations for the php() method (@see RequiredFields) does not check whether the + * Note: The existing implementations for the php() method (@see RequiredFieldsValidator) does not check whether the * Validator is enabled or not, and it also does not reset the validation result - so, neither does this. * * @param array $data @@ -156,7 +150,7 @@ public function getValidators(): array } /** - * Return all Validators that match a certain class name. EG: RequiredFields::class + * Return all Validators that match a certain class name. EG: RequiredFieldsValidator::class * * The keys for the return array match the keys in the unfiltered array. You cannot assume the keys will be * sequential or that the first key will be ZERO. @@ -181,7 +175,7 @@ public function getValidatorsByType(string $className): array } /** - * Remove all Validators that match a certain class name. EG: RequiredFields::class + * Remove all Validators that match a certain class name. EG: RequiredFieldsValidator::class * * @param string $className * @return CompositeValidator diff --git a/src/Forms/RequiredFields.php b/src/Forms/Validation/RequiredFieldsValidator.php similarity index 91% rename from src/Forms/RequiredFields.php rename to src/Forms/Validation/RequiredFieldsValidator.php index 0ec173f5c1e..aeadf8974b9 100644 --- a/src/Forms/RequiredFields.php +++ b/src/Forms/Validation/RequiredFieldsValidator.php @@ -1,9 +1,11 @@ <?php -namespace SilverStripe\Forms; +namespace SilverStripe\Forms\Validation; use SilverStripe\Core\ArrayLib; -use SilverStripe\Dev\Deprecation; +use SilverStripe\Forms\HasOneRelationFieldInterface; +use SilverStripe\Forms\FileField; +use SilverStripe\Forms\FormField; /** * Required Fields allows you to set which fields need to be present before @@ -12,10 +14,8 @@ * * Validation is performed on a field by field basis through * {@link FormField::validate}. - * - * @deprecated 5.4.0 Will be renamed to SilverStripe\Forms\Validation\RequiredFieldsValidator */ -class RequiredFields extends Validator +class RequiredFieldsValidator extends Validator { /** * Whether to globally allow whitespace only as a valid value for a required field @@ -42,11 +42,6 @@ class RequiredFields extends Validator */ public function __construct() { - Deprecation::noticeWithNoReplacment( - '5.4.0', - 'Will be renamed to SilverStripe\\Forms\\Validation\\RequiredFieldsValidator', - Deprecation::SCOPE_CLASS - ); $required = func_get_args(); if (isset($required[0]) && is_array($required[0])) { $required = $required[0]; @@ -121,12 +116,6 @@ public function php($data) $valid = true; $fields = $this->form->Fields(); - foreach ($fields as $field) { - $result = $field->validate(); - $valid = $result->isValid() && $valid; - $this->result->combineAnd($result); - } - if (!$this->required) { return $valid; } @@ -232,7 +221,7 @@ public function removeRequiredField($field) /** * Add {@link RequiredField} objects together * - * @param RequiredFields $requiredFields + * @param RequiredFieldsValidator $requiredFields * @return $this */ public function appendRequiredFields($requiredFields) diff --git a/src/Forms/Validator.php b/src/Forms/Validation/Validator.php similarity index 91% rename from src/Forms/Validator.php rename to src/Forms/Validation/Validator.php index 4a88c447412..04df3d263cb 100644 --- a/src/Forms/Validator.php +++ b/src/Forms/Validation/Validator.php @@ -1,19 +1,16 @@ <?php -namespace SilverStripe\Forms; +namespace SilverStripe\Forms\Validation; use SilverStripe\Core\Config\Configurable; use SilverStripe\Core\Extensible; use SilverStripe\Core\Injector\Injectable; use SilverStripe\Core\Validation\ValidationResult; -use SilverStripe\Dev\Deprecation; /** * This validation class handles all form and custom form validation through the use of Required * fields. It relies on javascript for client-side validation, and marking fields after server-side * validation. It acts as a visitor to individual form fields. - * - * @deprecated 5.4.0 Will be renamed to SilverStripe\Forms\Validation\Validator */ abstract class Validator { @@ -23,11 +20,6 @@ abstract class Validator public function __construct() { - Deprecation::noticeWithNoReplacment( - '5.4.0', - 'Will be renamed to SilverStripe\\Forms\\Validation\\Validator', - Deprecation::SCOPE_CLASS - ); $this->resetResult(); } @@ -179,7 +171,7 @@ public function removeValidation() /** * When Validators are set on the form, it can affect whether or not the form cannot be cached. * - * @see RequiredFields for an example of when you might be able to cache your form. + * @see RequiredFieldsValidator for an example of when you might be able to cache your form. * * @return bool */ diff --git a/src/ORM/DataObject.php b/src/ORM/DataObject.php index 586db64a941..8cbf4f9575d 100644 --- a/src/ORM/DataObject.php +++ b/src/ORM/DataObject.php @@ -18,8 +18,7 @@ use SilverStripe\Forms\FieldList; use SilverStripe\Forms\FormField; use SilverStripe\Forms\FormScaffolder; -use SilverStripe\Forms\CompositeValidator; -use SilverStripe\Forms\FieldsValidator; +use SilverStripe\Forms\Validation\CompositeValidator; use SilverStripe\Forms\GridField\GridField; use SilverStripe\Forms\GridField\GridFieldConfig_RelationEditor; use SilverStripe\Forms\HiddenField; @@ -2686,7 +2685,7 @@ public function getCMSActions() */ public function getCMSCompositeValidator(): CompositeValidator { - $compositeValidator = CompositeValidator::create([FieldsValidator::create()]); + $compositeValidator = CompositeValidator::create(); // Support for the old method during the deprecation period if ($this->hasMethod('getCMSValidator')) { diff --git a/src/ORM/Hierarchy/Hierarchy.php b/src/ORM/Hierarchy/Hierarchy.php index 4ae4014668d..c9eff0c8183 100644 --- a/src/ORM/Hierarchy/Hierarchy.php +++ b/src/ORM/Hierarchy/Hierarchy.php @@ -617,6 +617,30 @@ public function showingCMSTree() && in_array($controller->getAction(), ["treeview", "listview", "getsubtree"]); } + /** + * Return the CSS classes to apply to this node in the CMS tree. + */ + public function CMSTreeClasses(): string + { + $owner = $this->getOwner(); + $classes = sprintf('class-%s', Convert::raw2htmlid(get_class($owner))); + + if (!$owner->canAddChildren()) { + $classes .= " nochildren"; + } + + if (!$owner->canEdit() && !$owner->canAddChildren()) { + if (!$owner->canView()) { + $classes .= " disabled"; + } else { + $classes .= " edit-disabled"; + } + } + + $owner->invokeWithExtensions('updateCMSTreeClasses', $classes); + return $classes; + } + /** * Find the first class in the inheritance chain that has Hierarchy extension applied * @@ -777,6 +801,17 @@ public function getBreadcrumbs($separator = ' » ') return implode($separator ?? '', $crumbs); } + /** + * Get the title that will be used in TreeDropdownField and other tree structures. + */ + public function getTreeTitle(): string + { + $owner = $this->getOwner(); + $title = $owner->MenuTitle ?: $owner->Title; + $owner->extend('updateTreeTitle', $title); + return Convert::raw2xml($title ?? ''); + } + /** * Get the name of the dedicated sort field, if there is one. */ diff --git a/src/Security/Group.php b/src/Security/Group.php index 6c10d32c073..4298c11dd89 100755 --- a/src/Security/Group.php +++ b/src/Security/Group.php @@ -4,7 +4,7 @@ use SilverStripe\Admin\SecurityAdmin; use SilverStripe\Core\Convert; -use SilverStripe\Forms\CompositeValidator; +use SilverStripe\Forms\Validation\CompositeValidator; use SilverStripe\Forms\DropdownField; use SilverStripe\Forms\FieldList; use SilverStripe\Forms\Form; @@ -23,7 +23,7 @@ use SilverStripe\Forms\HTMLEditor\HTMLEditorConfig; use SilverStripe\Forms\ListboxField; use SilverStripe\Forms\LiteralField; -use SilverStripe\Forms\RequiredFields; +use SilverStripe\Forms\Validation\RequiredFieldsValidator; use SilverStripe\Forms\Tab; use SilverStripe\Forms\TabSet; use SilverStripe\Forms\TextareaField; @@ -494,16 +494,6 @@ public function stageChildren() ->sort('"Sort"'); } - /** - * @return string - */ - public function getTreeTitle() - { - $title = htmlspecialchars($this->Title ?? '', ENT_QUOTES); - $this->extend('updateTreeTitle', $title); - return $title; - } - /** * Overloaded to ensure the code is always descent. * @@ -559,7 +549,7 @@ public function getCMSCompositeValidator(): CompositeValidator { $validator = parent::getCMSCompositeValidator(); - $validator->addValidator(RequiredFields::create([ + $validator->addValidator(RequiredFieldsValidator::create([ 'Title' ])); diff --git a/src/Security/LogoutForm.php b/src/Security/LogoutForm.php index 5b12c2c3563..6f4588d9d11 100644 --- a/src/Security/LogoutForm.php +++ b/src/Security/LogoutForm.php @@ -9,7 +9,7 @@ use SilverStripe\Forms\Form; use SilverStripe\Forms\FormAction; use SilverStripe\Forms\HiddenField; -use SilverStripe\Forms\Validator; +use SilverStripe\Forms\Validation\Validator; /** * Log out form to display to users who arrive at 'Security/logout' without a diff --git a/src/Security/Member.php b/src/Security/Member.php index 1e025d5a159..7707df74ee2 100644 --- a/src/Security/Member.php +++ b/src/Security/Member.php @@ -15,7 +15,7 @@ use SilverStripe\Core\Injector\Injector; use SilverStripe\Dev\TestMailer; use SilverStripe\Forms\CheckboxField; -use SilverStripe\Forms\CompositeValidator; +use SilverStripe\Forms\Validation\CompositeValidator; use SilverStripe\Forms\ConfirmedPasswordField; use SilverStripe\Forms\DropdownField; use SilverStripe\Forms\FieldList; @@ -682,7 +682,7 @@ public function getMemberPasswordField() /** - * Returns the {@link RequiredFields} instance for the Member object. This + * Returns the {@link RequiredFieldsValidator} instance for the Member object. This * Validator is used when saving a {@link CMSProfileController} or added to * any form responsible for saving a users data. * diff --git a/src/Security/MemberAuthenticator/MemberLoginForm.php b/src/Security/MemberAuthenticator/MemberLoginForm.php index c88df53dc87..8273020748f 100644 --- a/src/Security/MemberAuthenticator/MemberLoginForm.php +++ b/src/Security/MemberAuthenticator/MemberLoginForm.php @@ -10,7 +10,7 @@ use SilverStripe\Forms\HiddenField; use SilverStripe\Forms\LiteralField; use SilverStripe\Forms\PasswordField; -use SilverStripe\Forms\RequiredFields; +use SilverStripe\Forms\Validation\RequiredFieldsValidator; use SilverStripe\Forms\TextField; use SilverStripe\Core\Validation\ValidationResult; use SilverStripe\Security\LoginForm as BaseLoginForm; @@ -111,7 +111,7 @@ public function __construct( if (isset($logoutAction)) { $this->setFormAction($logoutAction); } - $this->setValidator(RequiredFields::create(static::config()->get('required_fields'))); + $this->setValidator(RequiredFieldsValidator::create(static::config()->get('required_fields'))); } /** diff --git a/src/Security/Member_Validator.php b/src/Security/Member_Validator.php index 6b979847dd7..7ad2bc354a5 100644 --- a/src/Security/Member_Validator.php +++ b/src/Security/Member_Validator.php @@ -3,7 +3,7 @@ namespace SilverStripe\Security; use SilverStripe\Forms\GridField\GridFieldDetailForm_ItemRequest; -use SilverStripe\Forms\RequiredFields; +use SilverStripe\Forms\Validation\RequiredFieldsValidator; /** * Member Validator @@ -22,7 +22,7 @@ * - Surname * </code> */ -class Member_Validator extends RequiredFields +class Member_Validator extends RequiredFieldsValidator { /** * Fields that are required by this validator diff --git a/src/Security/PermissionCheckable.php b/src/Security/PermissionCheckable.php new file mode 100644 index 00000000000..1e5348f53a2 --- /dev/null +++ b/src/Security/PermissionCheckable.php @@ -0,0 +1,14 @@ +<?php + +namespace SilverStripe\Security; + +/** + * Model with permissions that can be checked using PermissionChecker + */ +interface PermissionCheckable +{ + /** + * Get the permission checker for this model + */ + public function getPermissionChecker(): PermissionChecker; +} diff --git a/tests/php/Forms/CheckboxFieldTest.php b/tests/php/Forms/CheckboxFieldTest.php index bbd3603492b..574106976f0 100644 --- a/tests/php/Forms/CheckboxFieldTest.php +++ b/tests/php/Forms/CheckboxFieldTest.php @@ -9,7 +9,7 @@ use SilverStripe\ORM\DB; use SilverStripe\Dev\SapphireTest; use SilverStripe\Forms\CheckboxField; -use SilverStripe\Forms\RequiredFields; +use SilverStripe\Forms\Validation\RequiredFieldsValidator; class CheckboxFieldTest extends SapphireTest { @@ -200,7 +200,7 @@ public function testNoAriaRequired() "form", new FieldList($field), new FieldList(), - new RequiredFields(["RequiredField"]) + new RequiredFieldsValidator(["RequiredField"]) ); $this->assertTrue($field->Required()); diff --git a/tests/php/Forms/CheckboxSetFieldTest.php b/tests/php/Forms/CheckboxSetFieldTest.php index a9c717ae753..2c7e75a3775 100644 --- a/tests/php/Forms/CheckboxSetFieldTest.php +++ b/tests/php/Forms/CheckboxSetFieldTest.php @@ -15,7 +15,7 @@ use SilverStripe\Forms\CheckboxSetField; use SilverStripe\Forms\FieldList; use SilverStripe\Forms\Form; -use SilverStripe\Forms\RequiredFields; +use SilverStripe\Forms\Validation\RequiredFieldsValidator; use SilverStripe\Model\ArrayData; class CheckboxSetFieldTest extends SapphireTest @@ -355,7 +355,7 @@ public function testNoAriaRequired() "form", new FieldList($field), new FieldList(), - new RequiredFields(["RequiredField"]) + new RequiredFieldsValidator(["RequiredField"]) ); $this->assertTrue($field->Required()); diff --git a/tests/php/Forms/CompositeFieldTest.php b/tests/php/Forms/CompositeFieldTest.php index f3b22dc711a..d15f60599ab 100644 --- a/tests/php/Forms/CompositeFieldTest.php +++ b/tests/php/Forms/CompositeFieldTest.php @@ -7,7 +7,7 @@ use SilverStripe\Forms\CompositeField; use SilverStripe\Forms\DropdownField; use SilverStripe\Forms\FieldList; -use SilverStripe\Forms\RequiredFields; +use SilverStripe\Forms\Validation\RequiredFieldsValidator; use SilverStripe\Forms\TextField; class CompositeFieldTest extends SapphireTest diff --git a/tests/php/Forms/CompositeValidatorTest.php b/tests/php/Forms/CompositeValidatorTest.php index bcd79a41caf..da181e9bbd8 100644 --- a/tests/php/Forms/CompositeValidatorTest.php +++ b/tests/php/Forms/CompositeValidatorTest.php @@ -8,10 +8,10 @@ use SilverStripe\Dev\SapphireTest; use SilverStripe\Forms\FieldList; use SilverStripe\Forms\Form; -use SilverStripe\Forms\RequiredFields; +use SilverStripe\Forms\Validation\RequiredFieldsValidator; use SilverStripe\Forms\Tests\ValidatorTest\TestValidator; use SilverStripe\Forms\TextField; -use SilverStripe\Forms\CompositeValidator; +use SilverStripe\Forms\Validation\CompositeValidator; /** * @package framework @@ -40,8 +40,8 @@ protected function getForm(array $fieldNames = []): Form public function testAddValidator(): void { $compositeValidator = new CompositeValidator(); - $compositeValidator->addValidator(new RequiredFields()); - $compositeValidator->addValidator(new RequiredFields()); + $compositeValidator->addValidator(new RequiredFieldsValidator()); + $compositeValidator->addValidator(new RequiredFieldsValidator()); $this->assertCount(2, $compositeValidator->getValidators()); } @@ -76,38 +76,38 @@ public function testSetForm(): void public function testGetValidatorsByType(): void { $compositeValidator = new CompositeValidator(); - $compositeValidator->addValidator(new RequiredFields()); + $compositeValidator->addValidator(new RequiredFieldsValidator()); $compositeValidator->addValidator(new TestValidator()); - $compositeValidator->addValidator(new RequiredFields()); + $compositeValidator->addValidator(new RequiredFieldsValidator()); $compositeValidator->addValidator(new TestValidator()); $this->assertCount(4, $compositeValidator->getValidators()); - $this->assertCount(2, $compositeValidator->getValidatorsByType(RequiredFields::class)); + $this->assertCount(2, $compositeValidator->getValidatorsByType(RequiredFieldsValidator::class)); } public function testRemoveValidatorsByType(): void { $compositeValidator = new CompositeValidator(); - $compositeValidator->addValidator(new RequiredFields()); + $compositeValidator->addValidator(new RequiredFieldsValidator()); $compositeValidator->addValidator(new TestValidator()); - $compositeValidator->addValidator(new RequiredFields()); + $compositeValidator->addValidator(new RequiredFieldsValidator()); $compositeValidator->addValidator(new TestValidator()); $this->assertCount(4, $compositeValidator->getValidators()); - $compositeValidator->removeValidatorsByType(RequiredFields::class); + $compositeValidator->removeValidatorsByType(RequiredFieldsValidator::class); $this->assertCount(2, $compositeValidator->getValidators()); } public function testCanBeCached(): void { $compositeValidator = new CompositeValidator(); - $compositeValidator->addValidator(new RequiredFields()); + $compositeValidator->addValidator(new RequiredFieldsValidator()); $this->assertTrue($compositeValidator->canBeCached()); $compositeValidator = new CompositeValidator(); - $compositeValidator->addValidator(new RequiredFields(['Foor'])); + $compositeValidator->addValidator(new RequiredFieldsValidator(['Foor'])); $this->assertFalse($compositeValidator->canBeCached()); } @@ -121,12 +121,12 @@ public function testFieldIsRequired(): void 'Content', ]; - $requiredFieldsFirst = new RequiredFields( + $requiredFieldsFirst = new RequiredFieldsValidator( [ $fieldNames[0], ] ); - $requiredFieldsSecond = new RequiredFields( + $requiredFieldsSecond = new RequiredFieldsValidator( [ $fieldNames[1], ] @@ -147,8 +147,8 @@ public function testValidate(): void { $compositeValidator = new CompositeValidator(); // Add two separate validators, each with one required field - $compositeValidator->addValidator(new RequiredFields(['Foo'])); - $compositeValidator->addValidator(new RequiredFields(['Bar'])); + $compositeValidator->addValidator(new RequiredFieldsValidator(['Foo'])); + $compositeValidator->addValidator(new RequiredFieldsValidator(['Bar'])); // Setup a form with the fields/data we're testing (a form is a dependency for validation right now) // We'll add three empty fields, but only two of them should be required diff --git a/tests/php/Forms/ConfirmedPasswordFieldTest.php b/tests/php/Forms/ConfirmedPasswordFieldTest.php index 7fb6f643d3f..6c8cee8cf66 100644 --- a/tests/php/Forms/ConfirmedPasswordFieldTest.php +++ b/tests/php/Forms/ConfirmedPasswordFieldTest.php @@ -9,7 +9,7 @@ use SilverStripe\Forms\FieldList; use SilverStripe\Forms\Form; use SilverStripe\Forms\ReadonlyField; -use SilverStripe\Forms\RequiredFields; +use SilverStripe\Forms\Validation\RequiredFieldsValidator; use SilverStripe\Security\Member; use SilverStripe\View\SSViewer; use Closure; @@ -466,7 +466,7 @@ public function testChildFieldsAreRequired(bool $canBeEmpty, bool $required, boo $requiredFields[] = 'Test[_Password]'; $requiredFields[] = 'Test[_ConfirmPassword]'; } - $form->setValidator(new RequiredFields($requiredFields)); + $form->setValidator(new RequiredFieldsValidator($requiredFields)); $rendered = $field->Field(); $fieldOneRegex = '<input\s+type="password"\s+name="Test\[_Password\]"\s[^>]*?required="required"\s+aria-required="true"\s[^>]*\/>'; diff --git a/tests/php/Forms/CurrencyFieldTest.php b/tests/php/Forms/CurrencyFieldTest.php index af08d227595..13543e65751 100644 --- a/tests/php/Forms/CurrencyFieldTest.php +++ b/tests/php/Forms/CurrencyFieldTest.php @@ -6,7 +6,7 @@ use SilverStripe\Dev\SapphireTest; use SilverStripe\Forms\CurrencyField; use SilverStripe\Forms\CurrencyField_Readonly; -use SilverStripe\Forms\RequiredFields; +use SilverStripe\Forms\Validation\RequiredFieldsValidator; use SilverStripe\ORM\FieldType\DBCurrency; class CurrencyFieldTest extends SapphireTest diff --git a/tests/php/Forms/DateFieldTest.php b/tests/php/Forms/DateFieldTest.php index 9ac536bc2e3..7f60339a177 100644 --- a/tests/php/Forms/DateFieldTest.php +++ b/tests/php/Forms/DateFieldTest.php @@ -7,7 +7,7 @@ use SilverStripe\Dev\SapphireTest; use SilverStripe\Forms\DateField; use SilverStripe\Forms\DateField_Disabled; -use SilverStripe\Forms\RequiredFields; +use SilverStripe\Forms\Validation\RequiredFieldsValidator; use SilverStripe\i18n\i18n; use SilverStripe\ORM\FieldType\DBDate; use SilverStripe\ORM\FieldType\DBDatetime; diff --git a/tests/php/Forms/DatetimeFieldTest.php b/tests/php/Forms/DatetimeFieldTest.php index 68e31a4eac8..4dc5da9e8b4 100644 --- a/tests/php/Forms/DatetimeFieldTest.php +++ b/tests/php/Forms/DatetimeFieldTest.php @@ -9,7 +9,7 @@ use SilverStripe\Forms\FieldList; use SilverStripe\Forms\Form; use SilverStripe\Forms\FormAction; -use SilverStripe\Forms\RequiredFields; +use SilverStripe\Forms\Validation\RequiredFieldsValidator; use SilverStripe\Forms\Tests\DatetimeFieldTest\Model; use SilverStripe\i18n\i18n; use SilverStripe\ORM\FieldType\DBDatetime; diff --git a/tests/php/Forms/DropdownFieldTest.php b/tests/php/Forms/DropdownFieldTest.php index 8e4de0e2fbe..2e87284a7c3 100644 --- a/tests/php/Forms/DropdownFieldTest.php +++ b/tests/php/Forms/DropdownFieldTest.php @@ -7,7 +7,7 @@ use SilverStripe\Dev\CSSContentParser; use SilverStripe\Dev\SapphireTest; use SilverStripe\Forms\DropdownField; -use SilverStripe\Forms\RequiredFields; +use SilverStripe\Forms\Validation\RequiredFieldsValidator; use SilverStripe\Forms\FormTemplateHelper; use SilverStripe\Forms\FieldList; use SilverStripe\Forms\Form; @@ -574,7 +574,7 @@ public function testRequiredDropdownHasEmptyDefault() "form", new FieldList($field), new FieldList(), - new RequiredFields(["RequiredField"]) + new RequiredFieldsValidator(["RequiredField"]) ); $this->assertTrue($field->getHasEmptyDefault()); diff --git a/tests/php/Forms/EmailFieldTest.php b/tests/php/Forms/EmailFieldTest.php index d46ceae1214..9c5064812dd 100644 --- a/tests/php/Forms/EmailFieldTest.php +++ b/tests/php/Forms/EmailFieldTest.php @@ -4,7 +4,6 @@ use SilverStripe\Dev\FunctionalTest; use SilverStripe\Forms\EmailField; -use SilverStripe\Forms\FieldsValidator; class EmailFieldTest extends FunctionalTest { diff --git a/tests/php/Forms/EmailFieldTest/TestController.php b/tests/php/Forms/EmailFieldTest/TestController.php index fd01418e34f..a0ae0ca3dc1 100644 --- a/tests/php/Forms/EmailFieldTest/TestController.php +++ b/tests/php/Forms/EmailFieldTest/TestController.php @@ -9,7 +9,7 @@ use SilverStripe\Forms\FieldList; use SilverStripe\Forms\Form; use SilverStripe\Forms\FormAction; -use SilverStripe\Forms\RequiredFields; +use SilverStripe\Forms\Validation\RequiredFieldsValidator; use SilverStripe\View\SSViewer; class TestController extends Controller implements TestOnly @@ -54,7 +54,7 @@ public function Form() new FieldList( new FormAction('doSubmit') ), - new RequiredFields( + new RequiredFieldsValidator( 'Email' ) ); diff --git a/tests/php/Forms/FieldsValidatorTest.php b/tests/php/Forms/FieldsValidatorTest.php deleted file mode 100644 index d5eac24d9c4..00000000000 --- a/tests/php/Forms/FieldsValidatorTest.php +++ /dev/null @@ -1,78 +0,0 @@ -<?php - -namespace SilverStripe\Forms\Tests; - -use SilverStripe\Dev\SapphireTest; -use SilverStripe\Forms\EmailField; -use SilverStripe\Forms\FieldList; -use SilverStripe\Forms\FieldsValidator; -use SilverStripe\Forms\Form; -use PHPUnit\Framework\Attributes\DataProvider; - -class FieldsValidatorTest extends SapphireTest -{ - protected $usesDatabase = false; - - public static function provideValidation() - { - return [ - 'missing values arent invalid' => [ - 'values' => [], - 'isValid' => true, - ], - 'empty values arent invalid' => [ - 'values' => [ - 'EmailField1' => '', - 'EmailField2' => null, - ], - 'isValid' => true, - ], - 'any invalid is invalid' => [ - 'values' => [ - 'EmailField1' => 'email@example.com', - 'EmailField2' => 'not email', - ], - 'isValid' => false, - ], - 'all invalid is invalid' => [ - 'values' => [ - 'EmailField1' => 'not email', - 'EmailField2' => 'not email', - ], - 'isValid' => false, - ], - 'all valid is valid' => [ - 'values' => [ - 'EmailField1' => 'email@example.com', - 'EmailField2' => 'email@example.com', - ], - 'isValid' => true, - ], - ]; - } - - #[DataProvider('provideValidation')] - public function testValidation(array $values, bool $isValid) - { - $fieldList = new FieldList([ - $field1 = new EmailField('EmailField1'), - $field2 = new EmailField('EmailField2'), - ]); - if (array_key_exists('EmailField1', $values)) { - $field1->setValue($values['EmailField1']); - } - if (array_key_exists('EmailField2', $values)) { - $field2->setValue($values['EmailField2']); - } - $form = new Form(null, 'testForm', $fieldList, new FieldList([/* no actions */]), new FieldsValidator()); - - $result = $form->validationResult(); - $this->assertSame($isValid, $result->isValid()); - $messages = $result->getMessages(); - if ($isValid) { - $this->assertEmpty($messages); - } else { - $this->assertNotEmpty($messages); - } - } -} diff --git a/tests/php/Forms/FileFieldTest.php b/tests/php/Forms/FileFieldTest.php index 3529b5eea1f..aa863cf049d 100644 --- a/tests/php/Forms/FileFieldTest.php +++ b/tests/php/Forms/FileFieldTest.php @@ -10,7 +10,7 @@ use SilverStripe\Forms\FileField; use SilverStripe\Forms\FieldList; use SilverStripe\Forms\Form; -use SilverStripe\Forms\RequiredFields; +use SilverStripe\Forms\Validation\RequiredFieldsValidator; class FileFieldTest extends FunctionalTest { @@ -126,7 +126,7 @@ public function testUploadMissingRequiredFile() $fileField = new FileField('cv', 'Upload your CV') ), new FieldList(), - new RequiredFields('cv') + new RequiredFieldsValidator('cv') ); // All fields are filled but for some reason an error occurred when uploading the file => fails $fileFieldValue = [ diff --git a/tests/php/Forms/FormFieldTest.php b/tests/php/Forms/FormFieldTest.php index 647c1adcfec..4ccc0039400 100644 --- a/tests/php/Forms/FormFieldTest.php +++ b/tests/php/Forms/FormFieldTest.php @@ -20,7 +20,7 @@ use SilverStripe\Forms\NullableField; use SilverStripe\Forms\PopoverField; use SilverStripe\Forms\PrintableTransformation_TabSet; -use SilverStripe\Forms\RequiredFields; +use SilverStripe\Forms\Validation\RequiredFieldsValidator; use SilverStripe\Forms\SelectionGroup; use SilverStripe\Forms\SelectionGroup_Item; use SilverStripe\Forms\Tab; @@ -41,7 +41,6 @@ use PHPUnit\Framework\Attributes\DataProvider; use SilverStripe\Core\Injector\Injector; use SilverStripe\Forms\ConfirmedPasswordField; -use SilverStripe\Forms\FieldsValidator; use SilverStripe\Forms\NumericField; use SilverStripe\Forms\CheckboxField_Readonly; use SilverStripe\VersionedAdmin\Forms\DiffField; @@ -533,7 +532,7 @@ public function testSetSchemaState() public function testGetSchemaStateWithFormValidation() { $field = new FormField('MyField', 'My Field'); - $validator = new RequiredFields('MyField'); + $validator = new RequiredFieldsValidator('MyField'); $form = new Form(null, 'TestForm', new FieldList($field), new FieldList(), $validator); $form->validationResult(); $schema = $field->getSchemaState(); @@ -548,7 +547,7 @@ public function testValidationExtensionHooks() /** @var TextField|FieldValidationExtension $field */ $field = new TextField('Test'); $field->setMaxLength(5); - $form = new Form(null, 'test', new FieldList($field), new FieldList(), new FieldsValidator()); + $form = new Form(null, 'test', new FieldList($field), new FieldList()); $form->disableSecurityToken(); $field->setValue('IAmLongerThan5Characters'); diff --git a/tests/php/Forms/FormSchemaTest.php b/tests/php/Forms/FormSchemaTest.php index ed78a8ef70c..1cc3a46fbd6 100644 --- a/tests/php/Forms/FormSchemaTest.php +++ b/tests/php/Forms/FormSchemaTest.php @@ -11,7 +11,7 @@ use SilverStripe\Forms\FieldList; use SilverStripe\Forms\Form; use SilverStripe\Forms\TextField; -use SilverStripe\Forms\RequiredFields; +use SilverStripe\Forms\Validation\RequiredFieldsValidator; use SilverStripe\Forms\FormAction; use SilverStripe\Forms\PopoverField; use SilverStripe\Forms\FormField; @@ -141,7 +141,7 @@ public function testGetStateWithFieldValidationErrors() { $fields = new FieldList(new TextField('Title')); $actions = new FieldList(); - $validator = new RequiredFields('Title'); + $validator = new RequiredFieldsValidator('Title'); $form = new Form(null, 'TestForm', $fields, $actions, $validator); $form->clearMessage(); $form->loadDataFrom( @@ -240,7 +240,7 @@ public function testSchemaValidation() new CurrencyField("Money") ), new FieldList(), - new RequiredFields('Name') + new RequiredFieldsValidator('Name') ); $formSchema = new FormSchema(); $schema = $formSchema->getSchema($form); diff --git a/tests/php/Forms/FormTest.php b/tests/php/Forms/FormTest.php index 30816b0feb9..7e30a1b5fe3 100644 --- a/tests/php/Forms/FormTest.php +++ b/tests/php/Forms/FormTest.php @@ -34,6 +34,7 @@ use SilverStripe\Model\ArrayData; use SilverStripe\View\SSViewer; use PHPUnit\Framework\Attributes\DataProvider; +use SilverStripe\Forms\EmailField; class FormTest extends FunctionalTest { @@ -1309,4 +1310,67 @@ protected function clean($input) trim($input ?? '') ); } + + public static function provideValidateFormFields() + { + return [ + 'missing values arent invalid' => [ + 'values' => [], + 'isValid' => true, + ], + 'empty values arent invalid' => [ + 'values' => [ + 'EmailField1' => '', + 'EmailField2' => null, + ], + 'isValid' => true, + ], + 'any invalid is invalid' => [ + 'values' => [ + 'EmailField1' => 'email@example.com', + 'EmailField2' => 'not email', + ], + 'isValid' => false, + ], + 'all invalid is invalid' => [ + 'values' => [ + 'EmailField1' => 'not email', + 'EmailField2' => 'not email', + ], + 'isValid' => false, + ], + 'all valid is valid' => [ + 'values' => [ + 'EmailField1' => 'email@example.com', + 'EmailField2' => 'email@example.com', + ], + 'isValid' => true, + ], + ]; + } + + #[DataProvider('provideValidateFormFields')] + public function testValidateFormFields(array $values, bool $isValid) + { + $fieldList = new FieldList([ + $field1 = new EmailField('EmailField1'), + $field2 = new EmailField('EmailField2'), + ]); + if (array_key_exists('EmailField1', $values)) { + $field1->setValue($values['EmailField1']); + } + if (array_key_exists('EmailField2', $values)) { + $field2->setValue($values['EmailField2']); + } + $form = new Form(null, 'testForm', $fieldList, new FieldList([/* no actions */])); + + $result = $form->validationResult(); + $this->assertSame($isValid, $result->isValid()); + $messages = $result->getMessages(); + if ($isValid) { + $this->assertEmpty($messages); + } else { + $this->assertNotEmpty($messages); + } + } } diff --git a/tests/php/Forms/FormTest/ControllerWithSpecialSubmittedValueFields.php b/tests/php/Forms/FormTest/ControllerWithSpecialSubmittedValueFields.php index 538261bd6c9..d16d59a8034 100644 --- a/tests/php/Forms/FormTest/ControllerWithSpecialSubmittedValueFields.php +++ b/tests/php/Forms/FormTest/ControllerWithSpecialSubmittedValueFields.php @@ -12,7 +12,7 @@ use SilverStripe\Forms\FormAction; use SilverStripe\Forms\MoneyField; use SilverStripe\Forms\NumericField; -use SilverStripe\Forms\RequiredFields; +use SilverStripe\Forms\Validation\RequiredFieldsValidator; use SilverStripe\Forms\TextField; use SilverStripe\Core\Validation\ValidationException; use SilverStripe\Core\Validation\ValidationResult; @@ -69,7 +69,7 @@ public function Form() new FieldList( FormAction::create('doSubmit') ), - new RequiredFields( + new RequiredFieldsValidator( 'SomeRequiredField' ) ); diff --git a/tests/php/Forms/FormTest/TestController.php b/tests/php/Forms/FormTest/TestController.php index a9ca0a1259d..1aac455062d 100644 --- a/tests/php/Forms/FormTest/TestController.php +++ b/tests/php/Forms/FormTest/TestController.php @@ -11,7 +11,7 @@ use SilverStripe\Forms\Form; use SilverStripe\Forms\FormAction; use SilverStripe\Forms\NumericField; -use SilverStripe\Forms\RequiredFields; +use SilverStripe\Forms\Validation\RequiredFieldsValidator; use SilverStripe\Forms\TextField; use SilverStripe\Core\Validation\ValidationException; use SilverStripe\Core\Validation\ValidationResult; @@ -66,7 +66,7 @@ public function Form() FormAction::create('doSubmitActionExempt') ->setValidationExempt(true) ), - new RequiredFields( + new RequiredFieldsValidator( 'Email', 'SomeRequiredField' ) diff --git a/tests/php/Forms/GridField/GridFieldDetailFormTest/Person.php b/tests/php/Forms/GridField/GridFieldDetailFormTest/Person.php index c5f33364065..ce97268c0e6 100644 --- a/tests/php/Forms/GridField/GridFieldDetailFormTest/Person.php +++ b/tests/php/Forms/GridField/GridFieldDetailFormTest/Person.php @@ -5,7 +5,7 @@ use SilverStripe\Dev\TestOnly; use SilverStripe\Forms\GridField\GridField; use SilverStripe\Forms\GridField\GridFieldConfig_RelationEditor; -use SilverStripe\Forms\RequiredFields; +use SilverStripe\Forms\Validation\RequiredFieldsValidator; use SilverStripe\ORM\DataObject; use SilverStripe\ORM\DataObjectSchema; @@ -67,7 +67,7 @@ public function getCMSFields() public function getCMSValidator() { - return new RequiredFields( + return new RequiredFieldsValidator( [ 'FirstName', 'Surname' diff --git a/tests/php/Forms/GridField/GridFieldExportButtonTest.php b/tests/php/Forms/GridField/GridFieldExportButtonTest.php index 9ec0d38ce48..255ba66edfe 100644 --- a/tests/php/Forms/GridField/GridFieldExportButtonTest.php +++ b/tests/php/Forms/GridField/GridFieldExportButtonTest.php @@ -2,6 +2,7 @@ namespace SilverStripe\Forms\Tests\GridField; +use League\Csv\Bom; use League\Csv\Reader; use LogicException; use ReflectionMethod; @@ -64,7 +65,7 @@ public function testCanView() $this->assertEquals( "$bom\"My Name\"\r\n", - (string) $csvReader + (string) $csvReader->toString() ); } @@ -78,7 +79,7 @@ public function testGenerateFileDataBasicFields() $this->assertEquals( $bom . '"My Name"' . "\r\n" . 'Test' . "\r\n" . 'Test2' . "\r\n", - (string) $csvReader + $csvReader->toString() ); } @@ -98,7 +99,7 @@ public function testXLSSanitisation() $this->assertEquals( "$bom\"My Name\"\r\n\"\t=SUM(1, 2)\"\r\nTest\r\nTest2\r\n", - (string) $csvReader + $csvReader->toString() ); } @@ -117,7 +118,7 @@ public function testGenerateFileDataAnonymousFunctionField() $this->assertEquals( $bom . 'Name,City' . "\r\n" . 'Test,"City city"' . "\r\n" . 'Test2,"Quoted ""City"" 2 city"' . "\r\n", - (string) $csvReader + $csvReader->toString() ); } @@ -134,7 +135,7 @@ public function testBuiltInFunctionNameCanBeUsedAsHeader() $this->assertEquals( $bom . 'Name,strtolower' . "\r\n" . 'Test,City' . "\r\n" . 'Test2,"Quoted ""City"" 2"' . "\r\n", - (string) $csvReader + $csvReader->toString() ); } @@ -152,7 +153,7 @@ public function testNoCsvHeaders() $this->assertEquals( $bom . 'Test,City' . "\r\n" . 'Test2,"Quoted ""City"" 2"' . "\r\n", - (string) $csvReader + $csvReader->toString() ); } @@ -179,7 +180,7 @@ public function testArrayListInput() $this->assertEquals( $bom . "ID\r\n" . "1\r\n" . "2\r\n" . "3\r\n" . "4\r\n" . "5\r\n" . "6\r\n" . "7\r\n" . "8\r\n" . "9\r\n" . "10\r\n" . "11\r\n" . "12\r\n" . "13\r\n" . "14\r\n" . "15\r\n" . "16\r\n", - (string) $csvReader + $csvReader->toString() ); } @@ -195,7 +196,7 @@ public function testZeroValue() $this->assertEquals( "$bom\"Rugby Team Number\"\r\n2\r\n0\r\n", - (string) $csvReader + $csvReader->toString() ); } @@ -224,7 +225,7 @@ protected function createReader($string) // Explicitly set the output BOM in league/csv 9 if (method_exists($reader, 'getContent')) { - $reader->setOutputBOM(Reader::BOM_UTF8); + $reader->setOutputBOM(Bom::Utf8); } return $reader; diff --git a/tests/php/Forms/GridField/GridFieldTest.php b/tests/php/Forms/GridField/GridFieldTest.php index d80a9a70c62..8847ee255f8 100644 --- a/tests/php/Forms/GridField/GridFieldTest.php +++ b/tests/php/Forms/GridField/GridFieldTest.php @@ -22,7 +22,7 @@ use SilverStripe\Forms\GridField\GridState; use SilverStripe\Forms\GridField\GridState_Component; use SilverStripe\Forms\GridField\GridState_Data; -use SilverStripe\Forms\RequiredFields; +use SilverStripe\Forms\Validation\RequiredFieldsValidator; use SilverStripe\Forms\Tests\GridField\GridFieldTest\Cheerleader; use SilverStripe\Forms\Tests\GridField\GridFieldTest\Component; use SilverStripe\Forms\Tests\GridField\GridFieldTest\Component2; @@ -551,7 +551,7 @@ public function testValidationMessageInOutput() $gridField->setMessage(null); // A form that passes validation should not display a validation error in the FieldHolder output. - $form->setValidator(new RequiredFields()); + $form->setValidator(null); $form->validationResult(); $gridfieldOutput = $gridField->FieldHolder(); $this->assertStringNotContainsString('<p class="message ' . ValidationResult::TYPE_ERROR . '">', $gridfieldOutput); diff --git a/tests/php/Forms/GroupedDropdownFieldTest.php b/tests/php/Forms/GroupedDropdownFieldTest.php index d382afcbe6d..22207dfd9ff 100644 --- a/tests/php/Forms/GroupedDropdownFieldTest.php +++ b/tests/php/Forms/GroupedDropdownFieldTest.php @@ -4,7 +4,7 @@ use SilverStripe\Dev\SapphireTest; use SilverStripe\Forms\GroupedDropdownField; -use SilverStripe\Forms\RequiredFields; +use SilverStripe\Forms\Validation\RequiredFieldsValidator; class GroupedDropdownFieldTest extends SapphireTest { diff --git a/tests/php/Forms/ListboxFieldTest.php b/tests/php/Forms/ListboxFieldTest.php index b451f97b590..5ef0a1b3832 100644 --- a/tests/php/Forms/ListboxFieldTest.php +++ b/tests/php/Forms/ListboxFieldTest.php @@ -9,7 +9,7 @@ use SilverStripe\Dev\CSSContentParser; use SilverStripe\Dev\SapphireTest; use SilverStripe\Forms\ListboxField; -use SilverStripe\Forms\RequiredFields; +use SilverStripe\Forms\Validation\RequiredFieldsValidator; use SilverStripe\Model\ArrayData; use PHPUnit\Framework\Attributes\DataProvider; diff --git a/tests/php/Forms/MoneyFieldTest.php b/tests/php/Forms/MoneyFieldTest.php index d48b393301b..ea136e8be69 100644 --- a/tests/php/Forms/MoneyFieldTest.php +++ b/tests/php/Forms/MoneyFieldTest.php @@ -5,7 +5,7 @@ use SilverStripe\Forms\DropdownField; use SilverStripe\Forms\HiddenField; use SilverStripe\Forms\NumericField; -use SilverStripe\Forms\RequiredFields; +use SilverStripe\Forms\Validation\RequiredFieldsValidator; use SilverStripe\Forms\Tests\MoneyFieldTest\CustomSetter_Object; use SilverStripe\Forms\Tests\MoneyFieldTest\TestObject; use SilverStripe\Forms\TextField; diff --git a/tests/php/Forms/NumericFieldTest.php b/tests/php/Forms/NumericFieldTest.php index 6637f3d55b6..641a8153703 100644 --- a/tests/php/Forms/NumericFieldTest.php +++ b/tests/php/Forms/NumericFieldTest.php @@ -4,7 +4,7 @@ use SilverStripe\Dev\SapphireTest; use SilverStripe\Forms\NumericField; -use SilverStripe\Forms\RequiredFields; +use SilverStripe\Forms\Validation\RequiredFieldsValidator; use SilverStripe\i18n\i18n; use PHPUnit\Framework\Attributes\DataProvider; diff --git a/tests/php/Forms/OptionsetFieldTest.php b/tests/php/Forms/OptionsetFieldTest.php index 0528e7ed268..04c188d6e5c 100644 --- a/tests/php/Forms/OptionsetFieldTest.php +++ b/tests/php/Forms/OptionsetFieldTest.php @@ -7,7 +7,7 @@ use SilverStripe\Dev\CSSContentParser; use SilverStripe\Dev\SapphireTest; use SilverStripe\Forms\OptionsetField; -use SilverStripe\Forms\RequiredFields; +use SilverStripe\Forms\Validation\RequiredFieldsValidator; use SilverStripe\Forms\FieldList; use SilverStripe\Forms\Form; @@ -46,7 +46,7 @@ public function testValidation() "Five" => "Five" ] ); - $validator = new RequiredFields('Test'); + $validator = new RequiredFieldsValidator('Test'); $form = new Form(null, 'Form', new FieldList($field), new FieldList(), $validator); $field->setValue("One"); @@ -60,14 +60,14 @@ public function testValidation() $field->setValue(''); $this->assertFalse($field->validate()->isValid()); - // ... and should not pass "RequiredFields" validation + // ... and should not pass "RequiredFieldsValidator" validation $this->assertFalse($form->validationResult()->isValid()); // null value should pass field-level validation... $field->setValue(null); $this->assertTrue($field->validate()->isValid()); - // ... but should not pass "RequiredFields" validation + // ... but should not pass "RequiredFieldsValidator" validation $this->assertFalse($form->validationResult()->isValid()); // disabled items shouldn't validate @@ -118,7 +118,7 @@ public function testNoAriaRequired() "form", new FieldList($field), new FieldList(), - new RequiredFields(["RequiredField"]) + new RequiredFieldsValidator(["RequiredField"]) ); $this->assertTrue($field->Required()); diff --git a/tests/php/Forms/RequiredFieldsTest.php b/tests/php/Forms/RequiredFieldsValidatorTest.php similarity index 92% rename from tests/php/Forms/RequiredFieldsTest.php rename to tests/php/Forms/RequiredFieldsValidatorTest.php index 1f52c0cb46c..188a6f1831f 100644 --- a/tests/php/Forms/RequiredFieldsTest.php +++ b/tests/php/Forms/RequiredFieldsValidatorTest.php @@ -3,7 +3,7 @@ namespace SilverStripe\Forms\Tests; use SilverStripe\Dev\SapphireTest; -use SilverStripe\Forms\RequiredFields; +use SilverStripe\Forms\Validation\RequiredFieldsValidator; use SilverStripe\Forms\Form; use SilverStripe\Forms\SearchableDropdownField; use SilverStripe\Forms\TreeDropdownField; @@ -12,7 +12,7 @@ use SilverStripe\Forms\TextField; use SilverStripe\Forms\FieldList; -class RequiredFieldsTest extends SapphireTest +class RequiredFieldsValidatorTest extends SapphireTest { public function testConstructingWithArray() { @@ -23,7 +23,7 @@ public function testConstructingWithArray() 'Image', 'AnotherField' ]; - $requiredFields = new RequiredFields($fields); + $requiredFields = new RequiredFieldsValidator($fields); //check the fields and the array match $this->assertEquals( $fields, @@ -35,7 +35,7 @@ public function testConstructingWithArray() public function testConstructingWithArguments() { //can we construct with arguments? - $requiredFields = new RequiredFields( + $requiredFields = new RequiredFieldsValidator( 'Title', 'Content', 'Image', @@ -57,7 +57,7 @@ public function testConstructingWithArguments() public function testRemoveValidation() { //can we remove all fields at once? - $requiredFields = new RequiredFields( + $requiredFields = new RequiredFieldsValidator( 'Title', 'Content', 'Image', @@ -74,7 +74,7 @@ public function testRemoveValidation() public function testRemoveRequiredField() { //set up the required fields - $requiredFields = new RequiredFields( + $requiredFields = new RequiredFieldsValidator( 'Title', 'Content', 'Image', @@ -117,7 +117,7 @@ public function testRemoveRequiredField() public function testAddRequiredField() { //set up the validator - $requiredFields = new RequiredFields( + $requiredFields = new RequiredFieldsValidator( 'Title' ); //add a field @@ -183,14 +183,14 @@ public function testAddRequiredField() public function testAppendRequiredFields() { //get the validator - $requiredFields = new RequiredFields( + $requiredFields = new RequiredFieldsValidator( 'Title', 'Content', 'Image', 'AnotherField' ); //create another validator with other fields - $otherRequiredFields = new RequiredFields( + $otherRequiredFields = new RequiredFieldsValidator( [ 'ExtraField1', 'ExtraField2' @@ -212,7 +212,7 @@ public function testAppendRequiredFields() "Merging of required fields failed to behave as expected" ); // create the standard validator so we can check duplicates are ignored - $otherRequiredFields = new RequiredFields( + $otherRequiredFields = new RequiredFieldsValidator( 'Title', 'Content', 'Image', @@ -234,7 +234,7 @@ public function testAppendRequiredFields() "Merging of required fields with duplicates failed to behave as expected" ); //add some new fields and some old ones in a strange order - $otherRequiredFields = new RequiredFields( + $otherRequiredFields = new RequiredFieldsValidator( 'ExtraField3', 'Title', 'ExtraField4', @@ -263,7 +263,7 @@ public function testAppendRequiredFields() public function testFieldIsRequired() { //get the validator - $requiredFields = new RequiredFields( + $requiredFields = new RequiredFieldsValidator( $fieldNames = [ 'Title', 'Content', @@ -312,7 +312,7 @@ public function testHasOneRelationFieldInterfaceValidation(string $className) $param = $className === TreeDropdownField::class ? Group::class : Group::get(); $field = new $className('TestField', 'TestField', $param); $form->Fields()->push($field); - $validator = new RequiredFields('TestField'); + $validator = new RequiredFieldsValidator('TestField'); $validator->setForm($form); // blank string and 0 and '0' and array with value of 0 fail required field validation $this->assertFalse($validator->php(['TestField' => ''])); @@ -418,12 +418,12 @@ public function testAllowWhitespaceOnlyConfig( bool $allowWhitespaceOnly, bool $expected, ): void { - $validator = new RequiredFields(['TestField']); + $validator = new RequiredFieldsValidator(['TestField']); $this->assertSame(true, $validator->getAllowWhitespaceOnly()); $field = new TextField('TestField'); $field->setValue($value); $form = new Form(null, null, new FieldList([$field]), null, $validator); - RequiredFields::config()->set('allow_whitespace_only', $allowWhitespaceOnly); + RequiredFieldsValidator::config()->set('allow_whitespace_only', $allowWhitespaceOnly); $result = $validator->validate($form); $this->assertEquals($expected, $result->isValid()); } @@ -434,7 +434,7 @@ public function testAllowWhitespaceOnlySetter( bool $allowWhitespaceOnly, bool $expected, ): void { - $validator = new RequiredFields(['TestField']); + $validator = new RequiredFieldsValidator(['TestField']); $validator->setAllowWhitespaceOnly($allowWhitespaceOnly); $this->assertSame($allowWhitespaceOnly, $validator->getAllowWhitespaceOnly()); $field = new TextField('TestField'); @@ -443,10 +443,10 @@ public function testAllowWhitespaceOnlySetter( $result = $validator->validate($form); $this->assertEquals($expected, $result->isValid()); // assert that global config makes no difference - RequiredFields::config()->set('allow_whitespace_only', true); + RequiredFieldsValidator::config()->set('allow_whitespace_only', true); $result = $validator->validate($form); $this->assertEquals($expected, $result->isValid()); - RequiredFields::config()->set('allow_whitespace_only', false); + RequiredFieldsValidator::config()->set('allow_whitespace_only', false); $result = $validator->validate($form); $this->assertEquals($expected, $result->isValid()); } diff --git a/tests/php/Forms/TextFieldTest.php b/tests/php/Forms/TextFieldTest.php index 062867cad19..09d44ef9f22 100644 --- a/tests/php/Forms/TextFieldTest.php +++ b/tests/php/Forms/TextFieldTest.php @@ -4,7 +4,7 @@ use SilverStripe\Dev\SapphireTest; use SilverStripe\Forms\TextField; -use SilverStripe\Forms\RequiredFields; +use SilverStripe\Forms\Validation\RequiredFieldsValidator; use SilverStripe\Forms\Tip; use PHPUnit\Framework\Attributes\DataProvider; diff --git a/tests/php/Forms/TextareaFieldTest.php b/tests/php/Forms/TextareaFieldTest.php index fa481b6a6c3..32ee7724aab 100644 --- a/tests/php/Forms/TextareaFieldTest.php +++ b/tests/php/Forms/TextareaFieldTest.php @@ -4,7 +4,7 @@ use SilverStripe\Dev\SapphireTest; use SilverStripe\Forms\TextareaField; -use SilverStripe\Forms\RequiredFields; +use SilverStripe\Forms\Validation\RequiredFieldsValidator; use PHPUnit\Framework\Attributes\DataProvider; class TextareaFieldTest extends SapphireTest diff --git a/tests/php/Forms/TimeFieldTest.php b/tests/php/Forms/TimeFieldTest.php index 35d0e9fdd27..ea915cceb6f 100644 --- a/tests/php/Forms/TimeFieldTest.php +++ b/tests/php/Forms/TimeFieldTest.php @@ -7,7 +7,7 @@ use SilverStripe\Core\Config\Config; use SilverStripe\Dev\SapphireTest; use SilverStripe\Forms\TimeField; -use SilverStripe\Forms\RequiredFields; +use SilverStripe\Forms\Validation\RequiredFieldsValidator; use SilverStripe\i18n\i18n; use PHPUnit\Framework\Attributes\DataProvider; use ReflectionMethod; diff --git a/tests/php/Forms/TreeDropdownFieldTest.php b/tests/php/Forms/TreeDropdownFieldTest.php index 012b22b9a32..fbf15de4f1e 100644 --- a/tests/php/Forms/TreeDropdownFieldTest.php +++ b/tests/php/Forms/TreeDropdownFieldTest.php @@ -10,7 +10,7 @@ use SilverStripe\Control\HTTPRequest; use SilverStripe\Forms\FieldList; use SilverStripe\Forms\Form; -use SilverStripe\Forms\RequiredFields; +use SilverStripe\Forms\Validation\RequiredFieldsValidator; use SilverStripe\Forms\TreeDropdownField; use SilverStripe\ORM\DataObject; use SilverStripe\ORM\Tests\HierarchyTest\HierarchyOnSubclassTestObject; @@ -61,7 +61,7 @@ public function testGetSchemaValidation(): void $this->assertSame($expected, $field->getSchemaValidation()); // field is required $fieldList = new FieldList([$field]); - $validator = new RequiredFields('TestTree'); + $validator = new RequiredFieldsValidator('TestTree'); new Form(null, null, $fieldList, null, $validator); $expected = [ 'required' => ['extraEmptyValues' => ['0']], diff --git a/tests/php/Forms/UrlFieldTest.php b/tests/php/Forms/UrlFieldTest.php index da55e05e993..03d73b3a728 100644 --- a/tests/php/Forms/UrlFieldTest.php +++ b/tests/php/Forms/UrlFieldTest.php @@ -4,7 +4,7 @@ use SilverStripe\Dev\SapphireTest; use SilverStripe\Forms\UrlField; -use SilverStripe\Forms\RequiredFields; +use SilverStripe\Forms\Validation\RequiredFieldsValidator; use PHPUnit\Framework\Attributes\DataProvider; class UrlFieldTest extends SapphireTest diff --git a/tests/php/Forms/ValidatorTest/TestValidator.php b/tests/php/Forms/ValidatorTest/TestValidator.php index 141c3522112..f5ebf73826f 100644 --- a/tests/php/Forms/ValidatorTest/TestValidator.php +++ b/tests/php/Forms/ValidatorTest/TestValidator.php @@ -4,7 +4,7 @@ use SilverStripe\Dev\TestOnly; use SilverStripe\Forms\Form; -use SilverStripe\Forms\Validator; +use SilverStripe\Forms\Validation\Validator; class TestValidator extends Validator implements TestOnly { diff --git a/tests/php/Security/GroupTest.php b/tests/php/Security/GroupTest.php index 1834f019ed8..0d5846c496a 100644 --- a/tests/php/Security/GroupTest.php +++ b/tests/php/Security/GroupTest.php @@ -5,7 +5,7 @@ use InvalidArgumentException; use SilverStripe\Control\Controller; use SilverStripe\Dev\FunctionalTest; -use SilverStripe\Forms\RequiredFields; +use SilverStripe\Forms\Validation\RequiredFieldsValidator; use SilverStripe\Model\List\ArrayList; use SilverStripe\ORM\DataObject; use SilverStripe\Security\Group; @@ -287,10 +287,10 @@ public function testGroupTitleValidation() $newGroup = new Group(); - $validators = $newGroup->getCMSCompositeValidator()->getValidatorsByType(RequiredFields::class); + $validators = $newGroup->getCMSCompositeValidator()->getValidatorsByType(RequiredFieldsValidator::class); $this->assertCount(1, $validators); $validator = array_shift($validators); - $this->assertInstanceOf(RequiredFields::class, $validator); + $this->assertInstanceOf(RequiredFieldsValidator::class, $validator); $this->assertTrue(in_array('Title', $validator->getRequired() ?? [])); $newGroup->Title = $group1->Title; diff --git a/tests/php/View/Embed/MockRequest.php b/tests/php/View/Embed/MockRequest.php index c92af57733b..0e3d2cec741 100644 --- a/tests/php/View/Embed/MockRequest.php +++ b/tests/php/View/Embed/MockRequest.php @@ -5,6 +5,7 @@ use Psr\Http\Message\RequestInterface; use Psr\Http\Message\UriInterface; use Psr\Http\Message\StreamInterface; +use Psr\Http\Message\MessageInterface; class MockRequest implements RequestInterface { @@ -17,80 +18,88 @@ public function __construct(EmbedUnitTest $unitTest, MockUri $mockUri) $this->mockUri = $mockUri; } - public function getRequestTarget() + public function getRequestTarget(): string { + return ''; } - public function getMethod() + public function getMethod(): string { + return ''; } - public function getUri() + public function getUri(): UriInterface { $this->unitTest->setFirstRequest(false); return $this->mockUri; } - public function getProtocolVersion() + public function getProtocolVersion(): string { + return ''; } - public function getHeaders() + public function getHeaders(): array { + return []; } - public function getHeader($name) + public function getHeader($name): array { + return []; } - public function getHeaderLine($name) + public function getHeaderLine($name): string { + return ''; } - public function getBody() + public function getBody(): StreamInterface { + return MockUtil::createStreamInterface(''); } - public function hasHeader($name) + public function hasHeader($name): bool { + return false; } - public function withHeader($name, $value) + public function withHeader($name, $value): MessageInterface { return $this; } - public function withAddedHeader($name, $value) + public function withAddedHeader($name, $value): MessageInterface { return $this; } - public function withoutHeader($name) + public function withoutHeader($name): MessageInterface { return $this; } - public function withBody(StreamInterface $body) + public function withBody(StreamInterface $body): MessageInterface { return $this; } - public function withProtocolVersion($version) + public function withProtocolVersion($version): MessageInterface { return $this; } - public function withRequestTarget($requestTarget) + public function withRequestTarget($requestTarget): RequestInterface { return $this; } - public function withMethod($method) + public function withMethod($method): RequestInterface { return $this; } - public function withUri(UriInterface $uri, $preserveHost = false) + public function withUri(UriInterface $uri, $preserveHost = false): RequestInterface { return $this; } diff --git a/tests/php/View/Embed/MockResponse.php b/tests/php/View/Embed/MockResponse.php index 65785047afd..477ba360eeb 100644 --- a/tests/php/View/Embed/MockResponse.php +++ b/tests/php/View/Embed/MockResponse.php @@ -4,6 +4,7 @@ use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\StreamInterface; +use Psr\Http\Message\MessageInterface; class MockResponse implements ResponseInterface { @@ -18,78 +19,78 @@ public function __construct(EmbedUnitTest $unitTest, string $firstResponse, stri $this->secondResponse = $secondResponse; } - public function getStatusCode() + public function getStatusCode(): int { return 200; } - public function getBody() + public function getBody(): StreamInterface { // first request is to the video HTML to get to find the oembed link // second request is to the oembed endpoint to fetch JSON if ($this->unitTest->getFirstRequest()) { - return $this->firstResponse; + return MockUtil::createStreamInterface($this->firstResponse); } else { - return $this->secondResponse; + return MockUtil::createStreamInterface($this->secondResponse); } } - public function getReasonPhrase() + public function getReasonPhrase(): string { return ''; } - public function getProtocolVersion() + public function getProtocolVersion(): string { return ''; } - public function getHeaders() + public function getHeaders(): array { return []; } - public function getHeader($name) + public function getHeader($name): array { - return ''; + return []; } - public function getHeaderLine($name) + public function getHeaderLine($name): string { return ''; } - public function hasHeader($name) + public function hasHeader($name): bool { return false; } - public function withHeader($name, $value) + public function withHeader($name, $value): MessageInterface { return $this; } - public function withAddedHeader($name, $value) + public function withAddedHeader($name, $value): MessageInterface { return $this; } - public function withBody(StreamInterface $body) + public function withBody(StreamInterface $body): MessageInterface { return $this; } - public function withoutHeader($name) + public function withoutHeader($name): MessageInterface { return $this; } - public function withProtocolVersion($version) + public function withProtocolVersion($version): MessageInterface { return $this; } - public function withStatus($code, $reasonPhrase = '') + public function withStatus($code, $reasonPhrase = ''): ResponseInterface { return $this; } diff --git a/tests/php/View/Embed/MockUri.php b/tests/php/View/Embed/MockUri.php index a374d1336d2..e7a692d72cf 100644 --- a/tests/php/View/Embed/MockUri.php +++ b/tests/php/View/Embed/MockUri.php @@ -7,10 +7,10 @@ class MockUri implements UriInterface, Stringable { - private string $scheme; - private string $host; - private string $path; - private string $query; + private string $scheme = ''; + private string $host = ''; + private string $path = ''; + private string $query = ''; public function __construct(string $url) { @@ -21,73 +21,77 @@ public function __construct(string $url) $this->query = $p['query'] ?? ''; } - public function getScheme() + public function getScheme(): string { return $this->scheme; } - public function getHost() + public function getHost(): string { return $this->host; } - public function getPath() + public function getPath(): string { return $this->path; } - public function getQuery() + public function getQuery(): string { return $this->query; } - public function getPort() + public function getPort(): ?int { + return null; } - public function getAuthority() + public function getAuthority(): string { + return ''; } - public function getUserInfo() + public function getUserInfo(): string { + return ''; } - public function getFragment() + public function getFragment(): string { + return ''; } - public function withPath($path) + public function withPath($path): UriInterface { return $this; } - public function withScheme($scheme) + public function withScheme($scheme): UriInterface { return $this; } - public function withUserInfo($user, $password = null) + public function withUserInfo($user, $password = null): UriInterface { return $this; } - public function withHost($host) + public function withHost($host): UriInterface { return $this; } - public function withPort($port) + public function withPort($port): UriInterface { return $this; } - public function withQuery($query) + public function withQuery($query): UriInterface { return $this; } - public function withFragment($fragment) + public function withFragment($fragment): UriInterface { return $this; } diff --git a/tests/php/View/Embed/MockUtil.php b/tests/php/View/Embed/MockUtil.php new file mode 100644 index 00000000000..82000a9f035 --- /dev/null +++ b/tests/php/View/Embed/MockUtil.php @@ -0,0 +1,79 @@ +<?php + +namespace SilverStripe\View\Tests\Embed; + +use Psr\Http\Message\StreamInterface; + +class MockUtil +{ + public static function createStreamInterface(string $body) + { + return new class($body) implements StreamInterface { + private string $body; + public function __construct(string $body) + { + $this->body = $body; + } + public function __toString(): string + { + return $this->body; + } + public function close(): void + { + return; + } + public function detach() + { + return; + } + public function getSize(): ?int + { + return null; + } + public function tell(): int + { + return 0; + } + public function eof(): bool + { + return false; + } + public function isSeekable(): bool + { + return false; + } + public function seek(int $offset, int $whence = SEEK_SET): void + { + return; + } + public function rewind(): void + { + return; + } + public function isWritable(): bool + { + return false; + } + public function write(string $string): int + { + return 0; + } + public function isReadable(): bool + { + return false; + } + public function read(int $length): string + { + return ''; + } + public function getContents(): string + { + return ''; + } + public function getMetadata(?string $key = null) + { + return; + } + }; + } +}