From 8ee826445f99f6142eb436e28d826157e88da368 Mon Sep 17 00:00:00 2001 From: David Windell Date: Sat, 2 Mar 2013 17:23:36 +0000 Subject: [PATCH 01/24] Added tests --- src/CollectionInputFilter.php | 2 +- src/Factory.php | 3 + test/BaseInputFilterTest.php | 16 ++ test/CollectionInputFilterTest.php | 357 +++++++++++++++++++++++++++++ test/FactoryTest.php | 15 ++ 5 files changed, 392 insertions(+), 1 deletion(-) create mode 100644 test/CollectionInputFilterTest.php diff --git a/src/CollectionInputFilter.php b/src/CollectionInputFilter.php index 156c0949..a4aa1cc7 100644 --- a/src/CollectionInputFilter.php +++ b/src/CollectionInputFilter.php @@ -31,7 +31,7 @@ class CollectionInputFilter extends InputFilter /* * @var int */ - protected $count; + protected $count = null; /* * @var array diff --git a/src/Factory.php b/src/Factory.php index 207f2233..2ff283e0 100644 --- a/src/Factory.php +++ b/src/Factory.php @@ -237,6 +237,9 @@ public function createInputFilter($inputFilterSpecification) if (isset($inputFilterSpecification['inputfilter'])) { $inputFilter->setInputFilter($inputFilterSpecification['inputfilter']); } + if (isset($inputFilterSpecification['count'])) { + $inputFilter->setCount($inputFilterSpecification['count']); + } return $inputFilter; } diff --git a/test/BaseInputFilterTest.php b/test/BaseInputFilterTest.php index bf980240..6ddf15da 100644 --- a/test/BaseInputFilterTest.php +++ b/test/BaseInputFilterTest.php @@ -640,6 +640,22 @@ public function testValidateUseExplodeAndInstanceOf() $filter->setData($data); $this->assertTrue($filter->isValid()); + } + + public function testGetInputs() + { + $filter = new InputFilter(); + + $foo = new Input('foo'); + $bar = new Input('bar'); + + $filter->add($foo); + $filter->add($bar); + + $filters = $filter->getInputs(); + $this->assertCount(2, $filters); + $this->assertEquals('foo', $filters['foo']->getName()); + $this->assertEquals('bar', $filters['bar']->getName()); } } diff --git a/test/CollectionInputFilterTest.php b/test/CollectionInputFilterTest.php new file mode 100644 index 00000000..1cf5159f --- /dev/null +++ b/test/CollectionInputFilterTest.php @@ -0,0 +1,357 @@ +filter = new CollectionInputFilter(); + } + + public function getBaseInputFilter() + { + $filter = new BaseInputFilter(); + + $foo = new Input(); + $foo->getFilterChain()->attachByName('stringtrim') + ->attachByName('alpha'); + $foo->getValidatorChain()->attach(new Validator\StringLength(3, 6)); + + $bar = new Input(); + $bar->getFilterChain()->attachByName('stringtrim'); + $bar->getValidatorChain()->attach(new Validator\Digits()); + + $baz = new Input(); + $baz->setRequired(false); + $baz->getFilterChain()->attachByName('stringtrim'); + $baz->getValidatorChain()->attach(new Validator\StringLength(1, 6)); + + $filter->add($foo, 'foo') + ->add($bar, 'bar') + ->add($baz, 'baz') + ->add($this->getChildInputFilter(), 'nest'); + + return $filter; + } + + public function getChildInputFilter() + { + $filter = new BaseInputFilter(); + + $foo = new Input(); + $foo->getFilterChain()->attachByName('stringtrim') + ->attachByName('alpha'); + $foo->getValidatorChain()->attach(new Validator\StringLength(3, 6)); + + $bar = new Input(); + $bar->getFilterChain()->attachByName('stringtrim'); + $bar->getValidatorChain()->attach(new Validator\Digits()); + + $baz = new Input(); + $baz->setRequired(false); + $baz->getFilterChain()->attachByName('stringtrim'); + $baz->getValidatorChain()->attach(new Validator\StringLength(1, 6)); + + $filter->add($foo, 'foo') + ->add($bar, 'bar') + ->add($baz, 'baz'); + return $filter; + } + + public function getValidCollectionData() + { + return array( + array( + 'foo' => ' bazbat ', + 'bar' => '12345', + 'baz' => '', + 'nest' => array( + 'foo' => ' bazbat ', + 'bar' => '12345', + 'baz' => '', + ), + ), + array( + 'foo' => ' batbaz ', + 'bar' => '54321', + 'baz' => '', + 'nest' => array( + 'foo' => ' batbaz ', + 'bar' => '54321', + 'baz' => '', + ), + ) + ); + } + + public function testSetInputFilter() + { + $this->filter->setInputFilter(new BaseInputFilter()); + $this->assertInstanceOf('Zend\InputFilter\BaseInputFilter', $this->filter->getInputFilter()); + } + + public function testInputFilterInputsAppliedToCollection() + { + $this->filter->setInputFilter($this->getBaseInputFilter()); + + $this->assertCount(4, $this->filter->getInputs()); + } + + public function testGetDefaultInputFilter() + { + $this->assertInstanceOf('Zend\InputFilter\BaseInputFilter', $this->filter->getInputFilter()); + } + + public function testSetCount() + { + $this->filter->setCount(5); + $this->assertEquals(5, $this->filter->getCount()); + } + + public function testSetCountBelowZero() + { + $this->filter->setCount(-1); + $this->assertEquals(0, $this->filter->getCount()); + } + + public function testGetCountUsesCountOfCollectionDataWhenNotSet() + { + $collectionData = array( + array('foo' => 'bar'), + array('foo' => 'baz') + ); + + $this->filter->setData($collectionData); + $this->assertEquals(2, $this->filter->getCount()); + } + + public function testGetCountUsesSpecifiedCount() + { + $collectionData = array( + array('foo' => 'bar'), + array('foo' => 'baz') + ); + + $this->filter->setCount(3); + $this->filter->setData($collectionData); + $this->assertEquals(3, $this->filter->getCount()); + } + + public function testCanValidateValidData() + { + $this->filter->setInputFilter($this->getBaseInputFilter()); + $this->filter->setData($this->getValidCollectionData()); + $this->assertTrue($this->filter->isValid()); + } + + public function testInvalidDataReturnsFalse() + { + $invalidCollectionData = array( + array( + 'foo' => ' bazbatlong ', + 'bar' => '12345', + 'baz' => '', + ), + array( + 'foo' => ' bazbat ', + 'bar' => '12345', + 'baz' => '', + ) + ); + + $this->filter->setInputFilter($this->getBaseInputFilter()); + $this->filter->setData($invalidCollectionData); + $this->assertFalse($this->filter->isValid()); + } + + public function testDataLessThanCountIsInvalid() + { + $invalidCollectionData = array( + array( + 'foo' => ' bazbat ', + 'bar' => '12345', + 'baz' => '', + 'nest' => array( + 'foo' => ' bazbat ', + 'bar' => '12345', + 'baz' => '', + ), + ), + ); + + $this->filter->setCount(2); + $this->filter->setInputFilter($this->getBaseInputFilter()); + $this->filter->setData($invalidCollectionData); + $this->assertFalse($this->filter->isValid()); + } + + public function testGetValues() + { + $expectedData = array( + array( + 'foo' => 'bazbat', + 'bar' => '12345', + 'baz' => '', + 'nest' => array( + 'foo' => 'bazbat', + 'bar' => '12345', + 'baz' => '', + ), + ), + array( + 'foo' => 'batbaz', + 'bar' => '54321', + 'baz' => '', + 'nest' => array( + 'foo' => 'batbaz', + 'bar' => '54321', + 'baz' => '', + ), + ) + ); + + $this->filter->setInputFilter($this->getBaseInputFilter()); + $this->filter->setData($this->getValidCollectionData()); + + $this->assertTrue($this->filter->isValid()); + $this->assertEquals($expectedData, $this->filter->getValues()); + + $this->assertCount(2, $this->filter->getValidInput()); + foreach ($this->filter->getValidInput() as $validInputs) { + $this->assertCount(4, $validInputs); + } + } + + public function testGetRawValues() + { + $expectedData = array( + array( + 'foo' => ' bazbat ', + 'bar' => '12345', + 'baz' => '', + 'nest' => array( + 'foo' => ' bazbat ', + 'bar' => '12345', + 'baz' => '', + ), + ), + array( + 'foo' => ' batbaz ', + 'bar' => '54321', + 'baz' => '', + 'nest' => array( + 'foo' => ' batbaz ', + 'bar' => '54321', + 'baz' => '', + ), + ) + ); + + $this->filter->setInputFilter($this->getBaseInputFilter()); + $this->filter->setData($this->getValidCollectionData()); + + $this->assertTrue($this->filter->isValid()); + $this->assertEquals($expectedData, $this->filter->getRawValues()); + } + + public function testGetMessagesForInvalidInputs() + { + $invalidCollectionData = array( + array( + 'foo' => ' bazbattoolong ', + 'bar' => '12345', + 'baz' => '', + 'nest' => array( + 'foo' => ' bazbat ', + 'bar' => '12345', + 'baz' => '', + ), + ), + array( + 'foo' => ' bazbat ', + 'bar' => 'notstring', + 'baz' => '', + 'nest' => array( + 'foo' => ' bazbat ', + 'bar' => '12345', + 'baz' => '', + ), + ), + ); + + $this->filter->setInputFilter($this->getBaseInputFilter()); + $this->filter->setData($invalidCollectionData); + + $this->assertFalse($this->filter->isValid()); + + $this->assertCount(2, $this->filter->getInvalidInput()); + foreach ($this->filter->getInvalidInput() as $invalidInputs) { + $this->assertCount(1, $invalidInputs); + } + + $messages = $this->filter->getMessages(); + + $this->assertCount(2, $messages); + $this->assertArrayHasKey('foo', $messages[0]); + $this->assertArrayHasKey('bar', $messages[1]); + } + + public function testSetValidationGroupUsingFormStyle() + { + // forms set an array of identical validation groups for each set of data + $formValidationGroup = array( + array( + 'foo', + 'bar', + ), + array( + 'foo', + 'bar', + ), + array( + 'foo', + 'bar', + ) + ); + + $data = array( + array( + 'foo' => ' bazbat ', + 'bar' => '12345' + ), + array( + 'foo' => ' batbaz ', + 'bar' => '54321' + ), + array( + 'foo' => ' batbaz ', + 'bar' => '54321' + ) + ); + + $this->filter->setInputFilter($this->getBaseInputFilter()); + $this->filter->setData($data); + $this->filter->setValidationGroup($formValidationGroup); + + $this->assertTrue($this->filter->isValid()); + } +} diff --git a/test/FactoryTest.php b/test/FactoryTest.php index f421c2a9..26e0235c 100644 --- a/test/FactoryTest.php +++ b/test/FactoryTest.php @@ -413,4 +413,19 @@ public function testFactoryAllowsPassingFilterChainsInInputSpec() $test = $input->getFilterChain(); $this->assertSame($chain, $test); } + + public function testFactoryAcceptsCollectionInputFilter() + { + $factory = new Factory(); + + $inputFilter = $factory->createInputFilter(array( + 'type' => 'Zend\InputFilter\CollectionInputFilter', + 'inputfilter' => new InputFilter(), + 'count' => 3 + )); + + $this->assertInstanceOf('Zend\InputFilter\CollectionInputFilter', $inputFilter); + $this->assertInstanceOf('Zend\InputFilter\InputFilter', $inputFilter->getInputFilter()); + $this->assertEquals(3, $inputFilter->getCount()); + } } From 6d71bc5b899e831d76ecd4d34dff2df5c6cbf812 Mon Sep 17 00:00:00 2001 From: ossinkine Date: Thu, 14 Mar 2013 17:26:51 +0600 Subject: [PATCH 02/24] ArrayInput added Filter and validate each element of an array --- src/ArrayInput.php | 69 +++++++++++++++ test/ArrayInputTest.php | 190 ++++++++++++++++++++++++++++++++++++++++ test/FileInputTest.php | 7 +- test/InputTest.php | 4 +- 4 files changed, 264 insertions(+), 6 deletions(-) create mode 100644 src/ArrayInput.php create mode 100644 test/ArrayInputTest.php diff --git a/src/ArrayInput.php b/src/ArrayInput.php new file mode 100644 index 00000000..5dec0151 --- /dev/null +++ b/src/ArrayInput.php @@ -0,0 +1,69 @@ +getFilterChain(); + $result = array(); + foreach ($this->value as $key => $value) { + $result[$key] = $filter->filter($value); + } + return $result; + } + + /** + * @param mixed $context Extra "context" to provide the validator + * @return bool + */ + public function isValid($context = null) + { + $this->injectNotEmptyValidator(); + $validator = $this->getValidatorChain(); + $values = $this->getValue(); + $result = true; + foreach ($values as $value) { + $result = $validator->isValid($value, $context); + if (!$result) { + if ($fallbackValue = $this->getFallbackValue()) { + $this->setValue($fallbackValue); + $result = true; + } + break; + } + } + + return $result; + } +} diff --git a/test/ArrayInputTest.php b/test/ArrayInputTest.php new file mode 100644 index 00000000..fb7403ef --- /dev/null +++ b/test/ArrayInputTest.php @@ -0,0 +1,190 @@ +input = new ArrayInput('foo'); + } + + public function testValueIsNullByDefault() + { + $this->markTestSkipped('Test is not enabled in ArrayInputTest'); + } + + public function testValueIsEmptyArrayByDefault() + { + $this->assertCount(0, $this->input->getValue()); + } + + public function testNotArrayValueCannotBeInjected() + { + $this->setExpectedException('Zend\InputFilter\Exception\InvalidArgumentException'); + $this->input->setValue('bar'); + } + + public function testValueMayBeInjected() + { + $this->input->setValue(array('bar')); + $this->assertEquals(array('bar'), $this->input->getValue()); + } + + public function testRetrievingValueFiltersTheValue() + { + $this->input->setValue(array('bar')); + $filter = new Filter\StringToUpper(); + $this->input->getFilterChain()->attach($filter); + $this->assertEquals(array('BAR'), $this->input->getValue()); + } + + public function testCanRetrieveRawValue() + { + $this->input->setValue(array('bar')); + $filter = new Filter\StringToUpper(); + $this->input->getFilterChain()->attach($filter); + $this->assertEquals(array('bar'), $this->input->getRawValue()); + } + + public function testIsValidReturnsFalseIfValidationChainFails() + { + $this->input->setValue(array('123', 'bar')); + $validator = new Validator\Digits(); + $this->input->getValidatorChain()->attach($validator); + $this->assertFalse($this->input->isValid()); + } + + public function testIsValidReturnsTrueIfValidationChainSucceeds() + { + $this->input->setValue(array('123', '123')); + $validator = new Validator\Digits(); + $this->input->getValidatorChain()->attach($validator); + $this->assertTrue($this->input->isValid()); + } + + public function testValidationOperatesOnFilteredValue() + { + $this->input->setValue(array(' 123 ', ' 123')); + $filter = new Filter\StringTrim(); + $this->input->getFilterChain()->attach($filter); + $validator = new Validator\Digits(); + $this->input->getValidatorChain()->attach($validator); + $this->assertTrue($this->input->isValid()); + } + + public function testGetMessagesReturnsValidationMessages() + { + $this->input->setValue(array('bar')); + $validator = new Validator\Digits(); + $this->input->getValidatorChain()->attach($validator); + $this->assertFalse($this->input->isValid()); + $messages = $this->input->getMessages(); + $this->assertArrayHasKey(Validator\Digits::NOT_DIGITS, $messages); + } + + public function testSpecifyingMessagesToInputReturnsThoseOnFailedValidation() + { + $this->input->setValue(array('bar')); + $validator = new Validator\Digits(); + $this->input->getValidatorChain()->attach($validator); + $this->input->setErrorMessage('Please enter only digits'); + $this->assertFalse($this->input->isValid()); + $messages = $this->input->getMessages(); + $this->assertArrayNotHasKey(Validator\Digits::NOT_DIGITS, $messages); + $this->assertContains('Please enter only digits', $messages); + } + + public function testNotEmptyValidatorAddedWhenIsValidIsCalled() + { + $this->assertTrue($this->input->isRequired()); + $this->input->setValue(array('bar', '')); + $validatorChain = $this->input->getValidatorChain(); + $this->assertEquals(0, count($validatorChain->getValidators())); + + $this->assertFalse($this->input->isValid()); + $messages = $this->input->getMessages(); + $this->assertArrayHasKey('isEmpty', $messages); + $this->assertEquals(1, count($validatorChain->getValidators())); + + // Assert that NotEmpty validator wasn't added again + $this->assertFalse($this->input->isValid()); + $this->assertEquals(1, count($validatorChain->getValidators())); + } + + public function testRequiredNotEmptyValidatorNotAddedWhenOneExists() + { + $this->assertTrue($this->input->isRequired()); + $this->input->setValue(array('bar', '')); + + $notEmptyMock = $this->getMock('Zend\Validator\NotEmpty', array('isValid')); + $notEmptyMock->expects($this->exactly(1)) + ->method('isValid') + ->will($this->returnValue(false)); + + $validatorChain = $this->input->getValidatorChain(); + $validatorChain->prependValidator($notEmptyMock); + $this->assertFalse($this->input->isValid()); + + $validators = $validatorChain->getValidators(); + $this->assertEquals(1, count($validators)); + $this->assertEquals($notEmptyMock, $validators[0]['instance']); + } + + public function testMerge() + { + $input = new ArrayInput('foo'); + $input->setValue(array(' 123 ')); + $filter = new Filter\StringTrim(); + $input->getFilterChain()->attach($filter); + $validator = new Validator\Digits(); + $input->getValidatorChain()->attach($validator); + + $input2 = new ArrayInput('bar'); + $input2->merge($input); + $validatorChain = $input->getValidatorChain(); + $filterChain = $input->getFilterChain(); + + $this->assertEquals(array(' 123 '), $input2->getRawValue()); + $this->assertEquals(1, $validatorChain->count()); + $this->assertEquals(1, $filterChain->count()); + + $validators = $validatorChain->getValidators(); + $this->assertInstanceOf('Zend\Validator\Digits', $validators[0]['instance']); + + $filters = $filterChain->getFilters()->toArray(); + $this->assertInstanceOf('Zend\Filter\StringTrim', $filters[0]); + } + + public function testDoNotInjectNotEmptyValidatorIfAnywhereInChain() + { + $this->assertTrue($this->input->isRequired()); + $this->input->setValue(array('bar', '')); + + $notEmptyMock = $this->getMock('Zend\Validator\NotEmpty', array('isValid')); + $notEmptyMock->expects($this->exactly(1)) + ->method('isValid') + ->will($this->returnValue(false)); + + $validatorChain = $this->input->getValidatorChain(); + $validatorChain->attach(new Validator\Digits()); + $validatorChain->attach($notEmptyMock); + $this->assertFalse($this->input->isValid()); + + $validators = $validatorChain->getValidators(); + $this->assertEquals(2, count($validators)); + $this->assertEquals($notEmptyMock, $validators[1]['instance']); + } +} diff --git a/test/FileInputTest.php b/test/FileInputTest.php index 392daa35..22d18c40 100644 --- a/test/FileInputTest.php +++ b/test/FileInputTest.php @@ -10,7 +10,6 @@ namespace ZendTest\InputFilter; -use PHPUnit_Framework_TestCase as TestCase; use Zend\InputFilter\FileInput; use Zend\Filter; use Zend\Validator; @@ -124,7 +123,7 @@ public function testIsValidReturnsTrueIfValidationChainSucceeds() public function testValidationOperatesOnFilteredValue() { - $this->markTestSkipped('Test are not enabled in FileInputTest'); + $this->markTestSkipped('Test is not enabled in FileInputTest'); } public function testValidationOperatesBeforeFiltering() @@ -305,12 +304,12 @@ public function testValidationsRunWithoutFileArrayDueToAjaxPost() public function testNotEmptyValidatorAddedWhenIsValidIsCalled() { - $this->markTestSkipped('Test are not enabled in FileInputTest'); + $this->markTestSkipped('Test is not enabled in FileInputTest'); } public function testRequiredNotEmptyValidatorNotAddedWhenOneExists() { - $this->markTestSkipped('Test are not enabled in FileInputTest'); + $this->markTestSkipped('Test is not enabled in FileInputTest'); } public function testMerge() diff --git a/test/InputTest.php b/test/InputTest.php index b263f27c..11f0a19b 100644 --- a/test/InputTest.php +++ b/test/InputTest.php @@ -240,8 +240,8 @@ public function testDoNotInjectNotEmptyValidatorIfAnywhereInChain() ->will($this->returnValue(false)); $validatorChain = $this->input->getValidatorChain(); - $validatorChain->addValidator(new Validator\Digits()); - $validatorChain->addValidator($notEmptyMock); + $validatorChain->attach(new Validator\Digits()); + $validatorChain->attach($notEmptyMock); $this->assertFalse($this->input->isValid()); $validators = $validatorChain->getValidators(); From 165e6afe379ba1a0aedd3f5c3b98ecbd0e4cff7c Mon Sep 17 00:00:00 2001 From: Zachary Burnham Date: Sun, 17 Mar 2013 22:20:29 -0400 Subject: [PATCH 03/24] Tests for added Continue If empty functionality. --- src/Input.php | 7 +++++- test/BaseInputFilterTest.php | 43 ++++++++++++++++++++++++++++++++++++ test/FactoryTest.php | 20 ++++++++++++++++- test/InputTest.php | 24 ++++++++++++++++++++ 4 files changed, 92 insertions(+), 2 deletions(-) diff --git a/src/Input.php b/src/Input.php index e7cfc28d..2c036f98 100644 --- a/src/Input.php +++ b/src/Input.php @@ -297,7 +297,12 @@ public function merge(InputInterface $input) */ public function isValid($context = null) { - $this->injectNotEmptyValidator(); + // Empty value needs further validation if continueIfEmpty is set + // so don't inject NotEmpty validator which would always + // mark that as false + if (!$this->continueIfEmpty()) { + $this->injectNotEmptyValidator(); + } $validator = $this->getValidatorChain(); $value = $this->getValue(); $result = $validator->isValid($value, $context); diff --git a/test/BaseInputFilterTest.php b/test/BaseInputFilterTest.php index bf980240..c5f59589 100644 --- a/test/BaseInputFilterTest.php +++ b/test/BaseInputFilterTest.php @@ -512,6 +512,49 @@ public function testValidationMarksInputInvalidWhenRequiredAndAllowEmptyFlagIsFa $this->assertFalse($filter->isValid()); } + + public static function contextDataProvider() + { + return array( + array('', 'y', true), + array('', 'n', false), + ); + } + + /** + * Idea here is that an empty field may or may not be valid based on + * context. + */ + /** + * @dataProvider contextDataProvider() + */ + public function testValidationMarksInputValidWhenAllowEmptyFlagIsTrueAndContinueIfEmptyIsTrueAndContextValidatesEmptyField($allowEmpty, $blankIsValid, $valid) + { + // $this->markTestSkipped(); + + $filter = new InputFilter(); + + $data = array ( + 'allowEmpty' => $allowEmpty, + 'blankIsValid' => $blankIsValid, + ); + + $allowEmpty = new Input(); + $allowEmpty->setAllowEmpty(true) + ->setContinueIfEmpty(true); + + $blankIsValid = new Input(); + $blankIsValid->getValidatorChain()->attach(new Validator\Callback(function($value, $context) { + return ('y' === $value && empty($context['allowEmpty'])); + })); + + $filter->add($allowEmpty, 'allowEmpty') + ->add($blankIsValid, 'blankIsValid'); + $filter->setData($data); +// die(var_dump($filter->get('blankIsValid'))); + + //$this->assertSame($valid, $filter->isValid()); + } public function testCanRetrieveRawValuesIndividuallyWithoutValidating() { diff --git a/test/FactoryTest.php b/test/FactoryTest.php index f421c2a9..99226cc6 100644 --- a/test/FactoryTest.php +++ b/test/FactoryTest.php @@ -239,6 +239,17 @@ public function testFactoryWillCreateInputWithSuggestedName() $this->assertInstanceOf('Zend\InputFilter\InputInterface', $input); $this->assertEquals('foo', $input->getName()); } + + public function testFactoryWillCreateInputWithContinueIfEmptyFlag() + { + $factory = new Factory(); + $input = $factory->createInput(array( + 'name' => 'foo', + 'continue_if_empty' => true, + )); + $this->assertInstanceOf('Zend\InputFilter\InputInterface', $input); + $this->assertTrue($input->continueIfEmpty()); + } public function testFactoryAcceptsInputInterface() { @@ -339,9 +350,13 @@ public function testFactoryWillCreateInputFilterAndAllInputObjectsFromGivenConfi 'type' => 'ZendTest\InputFilter\TestAsset\CustomInput', 'name' => 'bat', ), + 'zomg' => array( + 'name' => 'zomg', + 'continue_if_empty' => true, + ), )); $this->assertInstanceOf('Zend\InputFilter\InputFilter', $inputFilter); - $this->assertEquals(4, count($inputFilter)); + $this->assertEquals(5, count($inputFilter)); foreach (array('foo', 'bar', 'baz', 'bat') as $name) { $input = $inputFilter->get($name); @@ -373,6 +388,9 @@ public function testFactoryWillCreateInputFilterAndAllInputObjectsFromGivenConfi $this->assertInstanceOf('ZendTest\InputFilter\TestAsset\CustomInput', $input); $this->assertEquals('bat', $input->getName()); break; + case 'zomg': + $this->assertInstanceOf('Zend\InputFilter\Input', $input); + $this->assertTrue($input->continueIfEmpty()); } } } diff --git a/test/InputTest.php b/test/InputTest.php index 937b3e55..33df53fa 100644 --- a/test/InputTest.php +++ b/test/InputTest.php @@ -80,6 +80,30 @@ public function testAllowEmptyFlagIsMutable() $input->setAllowEmpty(true); $this->assertTrue($input->allowEmpty()); } + + public function testContinueIfEmptyFlagIsFalseByDefault() + { + $input = new Input('foo'); + $this->assertFalse($input->continueIfEmpty()); + } + + public function testContinueIfEmptyFlagIsMutable() + { + $input = new Input('foo'); + $input->setContinueIfEmpty(true); + $this->assertTrue($input->continueIfEmpty()); + } + + public function testNotEmptyValidatorNotInjectedIfContinueIfEmptyIsTrue() + { + $input = new Input('foo'); + $input->setContinueIfEmpty(true); + $input->setValue(''); + $input->isValid(); + $validators = $input->getValidatorChain() + ->getValidators(); + $this->assertTrue(0 == count($validators)); + } public function testValueIsNullByDefault() { From e3ff016ece0ff157d2a2868add92d45b07f6b12e Mon Sep 17 00:00:00 2001 From: David Windell Date: Wed, 20 Mar 2013 10:18:58 +0000 Subject: [PATCH 04/24] Implement feedback --- src/CollectionInputFilter.php | 7 +------ src/Factory.php | 4 ++-- 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/src/CollectionInputFilter.php b/src/CollectionInputFilter.php index a4aa1cc7..e3766812 100644 --- a/src/CollectionInputFilter.php +++ b/src/CollectionInputFilter.php @@ -125,14 +125,9 @@ public function setData($data) */ public function isValid() { - $inputCollection = array(); $valid = true; - $i = 0; - while ($i <= $this->getCount() - 1) { - $inputCollection[] = $this->validationGroup ?: array_keys($this->inputs); - $i++; - } + $inputCollection = array_fill(0, $this->getCount(), $this->validationGroup ?: array_keys($this->inputs)); foreach ($inputCollection as $key => $inputs) { $this->data = array(); diff --git a/src/Factory.php b/src/Factory.php index 2ff283e0..91daf76d 100644 --- a/src/Factory.php +++ b/src/Factory.php @@ -234,8 +234,8 @@ public function createInputFilter($inputFilterSpecification) } if ($inputFilter instanceof CollectionInputFilter) { - if (isset($inputFilterSpecification['inputfilter'])) { - $inputFilter->setInputFilter($inputFilterSpecification['inputfilter']); + if (isset($inputFilterSpecification['input_filter'])) { + $inputFilter->setInputFilter($inputFilterSpecification['input_filter']); } if (isset($inputFilterSpecification['count'])) { $inputFilter->setCount($inputFilterSpecification['count']); From ff6c032073d176373596e3fd861007c0b9a42d94 Mon Sep 17 00:00:00 2001 From: David Windell Date: Wed, 20 Mar 2013 11:00:15 +0000 Subject: [PATCH 05/24] Fix array_fill error --- src/CollectionInputFilter.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/CollectionInputFilter.php b/src/CollectionInputFilter.php index e3766812..bdb83570 100644 --- a/src/CollectionInputFilter.php +++ b/src/CollectionInputFilter.php @@ -127,7 +127,11 @@ public function isValid() { $valid = true; - $inputCollection = array_fill(0, $this->getCount(), $this->validationGroup ?: array_keys($this->inputs)); + if ($this->getCount() < 1) { + return $valid; + } + + $inputCollection = array_fill(0, $this->getCount() , $this->validationGroup ?: array_keys($this->inputs)); foreach ($inputCollection as $key => $inputs) { $this->data = array(); From ef30a66a6dda82759b711f0166301699bb221c6c Mon Sep 17 00:00:00 2001 From: Matthew Weier O'Phinney Date: Tue, 26 Mar 2013 09:22:56 -0500 Subject: [PATCH 06/24] Fix failing tests in Zend\InputFilter - Cleaned up BaseInputFilterTest to use a data provider; makes isolating failing cases simpler. - Rewrote logic in validateInputs() to capture discrete use cases; more verbose, but easier to determine what is happening. - Made executive decision: non-required input that is empty is valid. --- src/BaseInputFilter.php | 103 +++++++++++++++++++++++------ test/BaseInputFilterTest.php | 5 +- test/CollectionInputFilterTest.php | 2 - 3 files changed, 85 insertions(+), 25 deletions(-) diff --git a/src/BaseInputFilter.php b/src/BaseInputFilter.php index 39801a47..a99f4a89 100644 --- a/src/BaseInputFilter.php +++ b/src/BaseInputFilter.php @@ -169,37 +169,96 @@ protected function validateInputs(array $inputs) $valid = true; foreach ($inputs as $name) { - $input = $this->inputs[$name]; - // Check for missing data on non-required input - if ((!array_key_exists($name, $this->data) - || (null === $this->data[$name])) + $input = $this->inputs[$name]; + $dataExists = array_key_exists($name, $this->data); + + // key doesn't exist, but input is not required; valid + if (!$dataExists && $input instanceof InputInterface && !$input->isRequired() ) { $this->validInputs[$name] = $input; continue; } - if (!array_key_exists($name, $this->data) - || (null === $this->data[$name]) - || (is_string($this->data[$name]) && strlen($this->data[$name]) === 0) - // Single and Multi File Uploads - || (is_array($this->data[$name]) - && isset($this->data[$name]['error']) && $this->data[$name]['error'] === UPLOAD_ERR_NO_FILE) - || (is_array($this->data[$name]) && count($this->data[$name]) === 1 - && isset($this->data[$name][0]) && is_array($this->data[$name][0]) - && isset($this->data[$name][0]['error']) && $this->data[$name][0]['error'] === UPLOAD_ERR_NO_FILE) + + // key doesn't exist, input is required, allows empty; valid + if (!$dataExists + && $input instanceof InputInterface + && $input->isRequired() + && $input->allowEmpty() ) { - if ($input instanceof InputInterface) { - // - test if input allows empty - if ($input->allowEmpty()) { - $this->validInputs[$name] = $input; - continue; - } - } - // make sure we have a value (empty) for validation + $this->validInputs[$name] = $input; + continue; + } + + // key exists, is null, input is not required; valid + if ($dataExists + && null === $this->data[$name] + && $input instanceof InputInterface + && !$input->isRequired() + ) { + $this->validInputs[$name] = $input; + continue; + } + + // key exists, is null, input is required, allows empty; valid + if ($dataExists + && null === $this->data[$name] + && $input instanceof InputInterface + && $input->isRequired() + && $input->allowEmpty() + ) { + $this->validInputs[$name] = $input; + continue; + } + + // key exists, empty string, input is not required, allows empty; valid + if ($dataExists + && '' === $this->data[$name] + && $input instanceof InputInterface + && !$input->isRequired() + ) { + $this->validInputs[$name] = $input; + continue; + } + + // key exists, empty string, input is required, allows empty; valid + if ($dataExists + && '' === $this->data[$name] + && $input instanceof InputInterface + && $input->isRequired() + && $input->allowEmpty() + ) { + $this->validInputs[$name] = $input; + continue; + } + + // key exists, is array representing file, no file present, input not + // required or allows empty; valid + if ($dataExists + && is_array($this->data[$name]) + && ( + (isset($this->data[$name]['error']) + && $this->data[$name]['error'] === UPLOAD_ERR_NO_FILE) + || (count($this->data[$name]) === 1 + && isset($this->data[$name][0]) + && is_array($this->data[$name][0]) + && isset($this->data[$name][0]['error']) + && $this->data[$name][0]['error'] === UPLOAD_ERR_NO_FILE) + ) + && $input instanceof InputInterface + && (!$input->isRequired() || $input->allowEmpty()) + ) { + $this->validInputs[$name] = $input; + continue; + } + + // make sure we have a value (empty) for validation + if (!$dataExists) { $this->data[$name] = null; } + // Validate an input filter if ($input instanceof InputFilterInterface) { if (!$input->isValid()) { $this->invalidInputs[$name] = $input; @@ -209,6 +268,8 @@ protected function validateInputs(array $inputs) $this->validInputs[$name] = $input; continue; } + + // Validate an input if ($input instanceof InputInterface) { if (!$input->isValid($this->data)) { // Validation failure diff --git a/test/BaseInputFilterTest.php b/test/BaseInputFilterTest.php index 137a4751..148584ad 100644 --- a/test/BaseInputFilterTest.php +++ b/test/BaseInputFilterTest.php @@ -156,11 +156,11 @@ public function dataSets() array( 'foo' => ' bazbat ', 'bar' => '12345', - 'baz' => '', + 'baz' => 'thisistoolong', 'nest' => array( 'foo' => ' bazbat ', 'bar' => '12345', - 'baz' => '', + 'baz' => 'thisistoolong', ), ), false, @@ -184,6 +184,7 @@ public function dataSets() /** * @dataProvider dataSets + * @group fmlife */ public function testCanValidateEntireDataset($dataset, $expected) { diff --git a/test/CollectionInputFilterTest.php b/test/CollectionInputFilterTest.php index ac0d1926..1cf5159f 100644 --- a/test/CollectionInputFilterTest.php +++ b/test/CollectionInputFilterTest.php @@ -42,7 +42,6 @@ public function getBaseInputFilter() $baz = new Input(); $baz->setRequired(false); - $baz->setAllowEmpty(true); $baz->getFilterChain()->attachByName('stringtrim'); $baz->getValidatorChain()->attach(new Validator\StringLength(1, 6)); @@ -69,7 +68,6 @@ public function getChildInputFilter() $baz = new Input(); $baz->setRequired(false); - $baz->setAllowEmpty(true); $baz->getFilterChain()->attachByName('stringtrim'); $baz->getValidatorChain()->attach(new Validator\StringLength(1, 6)); From b2b1bd87e4d25ede7d62f78ee1f18e7517360eaa Mon Sep 17 00:00:00 2001 From: Zachary Burnham Date: Sun, 17 Mar 2013 22:20:29 -0400 Subject: [PATCH 07/24] Tests for added Continue If empty functionality. --- src/Input.php | 7 +++++- test/BaseInputFilterTest.php | 43 ++++++++++++++++++++++++++++++++++++ test/FactoryTest.php | 20 ++++++++++++++++- test/InputTest.php | 24 ++++++++++++++++++++ 4 files changed, 92 insertions(+), 2 deletions(-) diff --git a/src/Input.php b/src/Input.php index e7cfc28d..2c036f98 100644 --- a/src/Input.php +++ b/src/Input.php @@ -297,7 +297,12 @@ public function merge(InputInterface $input) */ public function isValid($context = null) { - $this->injectNotEmptyValidator(); + // Empty value needs further validation if continueIfEmpty is set + // so don't inject NotEmpty validator which would always + // mark that as false + if (!$this->continueIfEmpty()) { + $this->injectNotEmptyValidator(); + } $validator = $this->getValidatorChain(); $value = $this->getValue(); $result = $validator->isValid($value, $context); diff --git a/test/BaseInputFilterTest.php b/test/BaseInputFilterTest.php index 148584ad..5554b7c2 100644 --- a/test/BaseInputFilterTest.php +++ b/test/BaseInputFilterTest.php @@ -559,6 +559,49 @@ public function testValidationMarksInputInvalidWhenRequiredAndAllowEmptyFlagIsFa $this->assertFalse($filter->isValid()); } + + public static function contextDataProvider() + { + return array( + array('', 'y', true), + array('', 'n', false), + ); + } + + /** + * Idea here is that an empty field may or may not be valid based on + * context. + */ + /** + * @dataProvider contextDataProvider() + */ + public function testValidationMarksInputValidWhenAllowEmptyFlagIsTrueAndContinueIfEmptyIsTrueAndContextValidatesEmptyField($allowEmpty, $blankIsValid, $valid) + { + // $this->markTestSkipped(); + + $filter = new InputFilter(); + + $data = array ( + 'allowEmpty' => $allowEmpty, + 'blankIsValid' => $blankIsValid, + ); + + $allowEmpty = new Input(); + $allowEmpty->setAllowEmpty(true) + ->setContinueIfEmpty(true); + + $blankIsValid = new Input(); + $blankIsValid->getValidatorChain()->attach(new Validator\Callback(function($value, $context) { + return ('y' === $value && empty($context['allowEmpty'])); + })); + + $filter->add($allowEmpty, 'allowEmpty') + ->add($blankIsValid, 'blankIsValid'); + $filter->setData($data); +// die(var_dump($filter->get('blankIsValid'))); + + //$this->assertSame($valid, $filter->isValid()); + } public function testCanRetrieveRawValuesIndividuallyWithoutValidating() { diff --git a/test/FactoryTest.php b/test/FactoryTest.php index 26e0235c..48f6808c 100644 --- a/test/FactoryTest.php +++ b/test/FactoryTest.php @@ -239,6 +239,17 @@ public function testFactoryWillCreateInputWithSuggestedName() $this->assertInstanceOf('Zend\InputFilter\InputInterface', $input); $this->assertEquals('foo', $input->getName()); } + + public function testFactoryWillCreateInputWithContinueIfEmptyFlag() + { + $factory = new Factory(); + $input = $factory->createInput(array( + 'name' => 'foo', + 'continue_if_empty' => true, + )); + $this->assertInstanceOf('Zend\InputFilter\InputInterface', $input); + $this->assertTrue($input->continueIfEmpty()); + } public function testFactoryAcceptsInputInterface() { @@ -339,9 +350,13 @@ public function testFactoryWillCreateInputFilterAndAllInputObjectsFromGivenConfi 'type' => 'ZendTest\InputFilter\TestAsset\CustomInput', 'name' => 'bat', ), + 'zomg' => array( + 'name' => 'zomg', + 'continue_if_empty' => true, + ), )); $this->assertInstanceOf('Zend\InputFilter\InputFilter', $inputFilter); - $this->assertEquals(4, count($inputFilter)); + $this->assertEquals(5, count($inputFilter)); foreach (array('foo', 'bar', 'baz', 'bat') as $name) { $input = $inputFilter->get($name); @@ -373,6 +388,9 @@ public function testFactoryWillCreateInputFilterAndAllInputObjectsFromGivenConfi $this->assertInstanceOf('ZendTest\InputFilter\TestAsset\CustomInput', $input); $this->assertEquals('bat', $input->getName()); break; + case 'zomg': + $this->assertInstanceOf('Zend\InputFilter\Input', $input); + $this->assertTrue($input->continueIfEmpty()); } } } diff --git a/test/InputTest.php b/test/InputTest.php index 937b3e55..33df53fa 100644 --- a/test/InputTest.php +++ b/test/InputTest.php @@ -80,6 +80,30 @@ public function testAllowEmptyFlagIsMutable() $input->setAllowEmpty(true); $this->assertTrue($input->allowEmpty()); } + + public function testContinueIfEmptyFlagIsFalseByDefault() + { + $input = new Input('foo'); + $this->assertFalse($input->continueIfEmpty()); + } + + public function testContinueIfEmptyFlagIsMutable() + { + $input = new Input('foo'); + $input->setContinueIfEmpty(true); + $this->assertTrue($input->continueIfEmpty()); + } + + public function testNotEmptyValidatorNotInjectedIfContinueIfEmptyIsTrue() + { + $input = new Input('foo'); + $input->setContinueIfEmpty(true); + $input->setValue(''); + $input->isValid(); + $validators = $input->getValidatorChain() + ->getValidators(); + $this->assertTrue(0 == count($validators)); + } public function testValueIsNullByDefault() { From 755abee21e21a195ff73ed641fa8664a981fd988 Mon Sep 17 00:00:00 2001 From: Zachary Burnham Date: Mon, 1 Apr 2013 22:19:11 -0400 Subject: [PATCH 08/24] Splitting 'continue if empty' functionality into its own interface. Fixing a failing unit test; test was not providing data for a required input. --- src/BaseInputFilter.php | 8 ++++++-- src/EmptyContextInterface.php | 17 +++++++++++++++++ src/Input.php | 2 +- src/InputInterface.php | 2 -- test/BaseInputFilterTest.php | 6 +++++- 5 files changed, 29 insertions(+), 6 deletions(-) create mode 100644 src/EmptyContextInterface.php diff --git a/src/BaseInputFilter.php b/src/BaseInputFilter.php index 50eb4853..c3688b24 100644 --- a/src/BaseInputFilter.php +++ b/src/BaseInputFilter.php @@ -225,14 +225,18 @@ protected function validateInputs(array $inputs) } // key exists, empty string, input is required, allows empty; valid + // if continueIfEmpty is false, otherwise validation continues if ($dataExists && '' === $this->data[$name] && $input instanceof InputInterface + && $input instanceof EmptyContextInterface && $input->isRequired() && $input->allowEmpty() ) { - $this->validInputs[$name] = $input; - continue; + if (!$input->continueIfEmpty()) { + $this->validInputs[$name] = $input; + continue; + } } // key exists, is array representing file, no file present, input not diff --git a/src/EmptyContextInterface.php b/src/EmptyContextInterface.php new file mode 100644 index 00000000..ed4cf0fd --- /dev/null +++ b/src/EmptyContextInterface.php @@ -0,0 +1,17 @@ +add($foo, '') ->add($bar, 'bar'); - $data = array('bar' => 124); + $data = array( + 'bar' => 124, + 'foo' => '', + ); + $filter->setData($data); $this->assertTrue($filter->isValid()); From abd390135d866ca23cdee417920fea4e930d6a98 Mon Sep 17 00:00:00 2001 From: Zachary Burnham Date: Tue, 2 Apr 2013 08:08:37 -0400 Subject: [PATCH 09/24] Fixing one test to actually test the new functionality for continue if empty, removing redundant tests that mysteriously turned up. --- test/BaseInputFilterTest.php | 84 ++++++++++++++++++------------------ test/FactoryTest.php | 2 +- 2 files changed, 43 insertions(+), 43 deletions(-) diff --git a/test/BaseInputFilterTest.php b/test/BaseInputFilterTest.php index a0f17f93..8611657c 100644 --- a/test/BaseInputFilterTest.php +++ b/test/BaseInputFilterTest.php @@ -572,48 +572,48 @@ public static function contextDataProvider() ); } - /** - * Idea here is that an empty field may or may not be valid based on - * context. - */ - /** - * @dataProvider contextDataProvider() - */ - public function testValidationMarksInputValidWhenAllowEmptyFlagIsTrueAndContinueIfEmptyIsTrueAndContextValidatesEmptyField($allowEmpty, $blankIsValid, $valid) - { - // $this->markTestSkipped(); - - $filter = new InputFilter(); - - $data = array ( - 'allowEmpty' => $allowEmpty, - 'blankIsValid' => $blankIsValid, - ); - - $allowEmpty = new Input(); - $allowEmpty->setAllowEmpty(true) - ->setContinueIfEmpty(true); - - $blankIsValid = new Input(); - $blankIsValid->getValidatorChain()->attach(new Validator\Callback(function($value, $context) { - return ('y' === $value && empty($context['allowEmpty'])); - })); - - $filter->add($allowEmpty, 'allowEmpty') - ->add($blankIsValid, 'blankIsValid'); - $filter->setData($data); -// die(var_dump($filter->get('blankIsValid'))); - - //$this->assertSame($valid, $filter->isValid()); - } - - public static function contextDataProvider() - { - return array( - array('', 'y', true), - array('', 'n', false), - ); - } +// /** +// * Idea here is that an empty field may or may not be valid based on +// * context. +// */ +// /** +// * @dataProvider contextDataProvider() +// */ +// public function testValidationMarksInputValidWhenAllowEmptyFlagIsTrueAndContinueIfEmptyIsTrueAndContextValidatesEmptyField($allowEmpty, $blankIsValid, $valid) +// { +// // $this->markTestSkipped(); +// +// $filter = new InputFilter(); +// +// $data = array ( +// 'allowEmpty' => $allowEmpty, +// 'blankIsValid' => $blankIsValid, +// ); +// +// $allowEmpty = new Input(); +// $allowEmpty->setAllowEmpty(true) +// ->setContinueIfEmpty(true); +// +// $blankIsValid = new Input(); +// $blankIsValid->getValidatorChain()->attach(new Validator\Callback(function($value, $context) { +// return ('y' === $value && empty($context['allowEmpty'])); +// })); +// +// $filter->add($allowEmpty, 'allowEmpty') +// ->add($blankIsValid, 'blankIsValid'); +// $filter->setData($data); +//// die(var_dump($filter->get('blankIsValid'))); +// +// //$this->assertSame($valid, $filter->isValid()); +// } +// +// public static function contextDataProvider() +// { +// return array( +// array('', 'y', true), +// array('', 'n', false), +// ); +// } /** * Idea here is that an empty field may or may not be valid based on diff --git a/test/FactoryTest.php b/test/FactoryTest.php index 48f6808c..506583e4 100644 --- a/test/FactoryTest.php +++ b/test/FactoryTest.php @@ -358,7 +358,7 @@ public function testFactoryWillCreateInputFilterAndAllInputObjectsFromGivenConfi $this->assertInstanceOf('Zend\InputFilter\InputFilter', $inputFilter); $this->assertEquals(5, count($inputFilter)); - foreach (array('foo', 'bar', 'baz', 'bat') as $name) { + foreach (array('foo', 'bar', 'baz', 'bat', 'zomg') as $name) { $input = $inputFilter->get($name); switch ($name) { From 61bbf99a456008deaaec44acb7c04ccdc45289ad Mon Sep 17 00:00:00 2001 From: Zachary Burnham Date: Tue, 2 Apr 2013 08:13:38 -0400 Subject: [PATCH 10/24] A test I had added didn't actually add any assertions due to a line being commented out. --- test/BaseInputFilterTest.php | 45 +----------------------------------- 1 file changed, 1 insertion(+), 44 deletions(-) diff --git a/test/BaseInputFilterTest.php b/test/BaseInputFilterTest.php index 8611657c..3a26efb6 100644 --- a/test/BaseInputFilterTest.php +++ b/test/BaseInputFilterTest.php @@ -572,49 +572,6 @@ public static function contextDataProvider() ); } -// /** -// * Idea here is that an empty field may or may not be valid based on -// * context. -// */ -// /** -// * @dataProvider contextDataProvider() -// */ -// public function testValidationMarksInputValidWhenAllowEmptyFlagIsTrueAndContinueIfEmptyIsTrueAndContextValidatesEmptyField($allowEmpty, $blankIsValid, $valid) -// { -// // $this->markTestSkipped(); -// -// $filter = new InputFilter(); -// -// $data = array ( -// 'allowEmpty' => $allowEmpty, -// 'blankIsValid' => $blankIsValid, -// ); -// -// $allowEmpty = new Input(); -// $allowEmpty->setAllowEmpty(true) -// ->setContinueIfEmpty(true); -// -// $blankIsValid = new Input(); -// $blankIsValid->getValidatorChain()->attach(new Validator\Callback(function($value, $context) { -// return ('y' === $value && empty($context['allowEmpty'])); -// })); -// -// $filter->add($allowEmpty, 'allowEmpty') -// ->add($blankIsValid, 'blankIsValid'); -// $filter->setData($data); -//// die(var_dump($filter->get('blankIsValid'))); -// -// //$this->assertSame($valid, $filter->isValid()); -// } -// -// public static function contextDataProvider() -// { -// return array( -// array('', 'y', true), -// array('', 'n', false), -// ); -// } - /** * Idea here is that an empty field may or may not be valid based on * context. @@ -647,7 +604,7 @@ public function testValidationMarksInputValidWhenAllowEmptyFlagIsTrueAndContinue $filter->setData($data); // die(var_dump($filter->get('blankIsValid'))); - //$this->assertSame($valid, $filter->isValid()); + $this->assertSame($valid, $filter->isValid()); } public function testCanRetrieveRawValuesIndividuallyWithoutValidating() From 7f3bb0e0514be5c3797c38ebc46d3e2017073000 Mon Sep 17 00:00:00 2001 From: Matthew Weier O'Phinney Date: Fri, 12 Apr 2013 12:12:34 -0500 Subject: [PATCH 11/24] [zendframework/zf2#4165] CS fixes - per php-cs-fixer --- src/EmptyContextInterface.php | 4 +- src/Factory.php.orig | 331 ++++++++++++++++++++++++++++++++++ src/Input.php | 6 +- test/BaseInputFilterTest.php | 22 +-- test/FactoryTest.php | 2 +- test/InputTest.php | 6 +- 6 files changed, 351 insertions(+), 20 deletions(-) create mode 100644 src/Factory.php.orig diff --git a/src/EmptyContextInterface.php b/src/EmptyContextInterface.php index ed4cf0fd..72933b18 100644 --- a/src/EmptyContextInterface.php +++ b/src/EmptyContextInterface.php @@ -12,6 +12,6 @@ interface EmptyContextInterface { public function setContinueIfEmpty($continueIfEmpty); - + public function continueIfEmpty(); -} \ No newline at end of file +} diff --git a/src/Factory.php.orig b/src/Factory.php.orig new file mode 100644 index 00000000..f1199abe --- /dev/null +++ b/src/Factory.php.orig @@ -0,0 +1,331 @@ +defaultFilterChain = $filterChain; + return $this; + } + + /** + * Get default filter chain, if any + * + * @return null|FilterChain + */ + public function getDefaultFilterChain() + { + return $this->defaultFilterChain; + } + + /** + * Clear the default filter chain (i.e., don't inject one into new inputs) + * + * @return void + */ + public function clearDefaultFilterChain() + { + $this->defaultFilterChain = null; + } + + /** + * Set default validator chain to use + * + * @param ValidatorChain $validatorChain + * @return Factory + */ + public function setDefaultValidatorChain(ValidatorChain $validatorChain) + { + $this->defaultValidatorChain = $validatorChain; + return $this; + } + + /** + * Get default validator chain, if any + * + * @return null|ValidatorChain + */ + public function getDefaultValidatorChain() + { + return $this->defaultValidatorChain; + } + + /** + * Clear the default validator chain (i.e., don't inject one into new inputs) + * + * @return void + */ + public function clearDefaultValidatorChain() + { + $this->defaultValidatorChain = null; + } + + /** + * Factory for input objects + * + * @param array|Traversable $inputSpecification + * @throws Exception\InvalidArgumentException + * @throws Exception\RuntimeException + * @return InputInterface|InputFilterInterface + */ + public function createInput($inputSpecification) + { + if (!is_array($inputSpecification) && !$inputSpecification instanceof Traversable) { + throw new Exception\InvalidArgumentException(sprintf( + '%s expects an array or Traversable; received "%s"', + __METHOD__, + (is_object($inputSpecification) ? get_class($inputSpecification) : gettype($inputSpecification)) + )); + } + if ($inputSpecification instanceof Traversable) { + $inputSpecification = ArrayUtils::iteratorToArray($inputSpecification); + } + + $class = 'Zend\InputFilter\Input'; + if (isset($inputSpecification['type'])) { + $class = $inputSpecification['type']; + if (!class_exists($class)) { + throw new Exception\RuntimeException(sprintf( + 'Input factory expects the "type" to be a valid class; received "%s"', + $class + )); + } + } + $input = new $class(); + + if ($input instanceof InputFilterInterface) { + return $this->createInputFilter($inputSpecification); + } + + if (!$input instanceof InputInterface) { + throw new Exception\RuntimeException(sprintf( + 'Input factory expects the "type" to be a class implementing %s; received "%s"', + 'Zend\InputFilter\InputInterface', + $class + )); + } + + if ($this->defaultFilterChain) { + $input->setFilterChain(clone $this->defaultFilterChain); + } + if ($this->defaultValidatorChain) { + $input->setValidatorChain(clone $this->defaultValidatorChain); + } + + foreach ($inputSpecification as $key => $value) { + switch ($key) { + case 'name': + $input->setName($value); + break; + case 'required': + $input->setRequired($value); + if (!isset($inputSpecification['allow_empty'])) { + $input->setAllowEmpty(!$value); + } + break; + case 'allow_empty': + $input->setAllowEmpty($value); + if (!isset($inputSpecification['required'])) { + $input->setRequired(!$value); + } + break; +<<<<<<< HEAD + case 'error_message': + $input->setErrorMessage($value); +======= + case 'continue_if_empty': + $input->setContinueIfEmpty($inputSpecification['continue_if_empty']); +>>>>>>> zburnham/validate_empty_with_context + break; + case 'fallback_value': + $input->setFallbackValue($value); + break; + case 'filters': + if ($value instanceof FilterChain) { + $input->setFilterChain($value); + break; + } + if (!is_array($value) && !$value instanceof Traversable) { + throw new Exception\RuntimeException(sprintf( + '%s expects the value associated with "filters" to be an array/Traversable of filters or filter specifications, or a FilterChain; received "%s"', + __METHOD__, + (is_object($value) ? get_class($value) : gettype($value)) + )); + } + $this->populateFilters($input->getFilterChain(), $value); + break; + case 'validators': + if ($value instanceof ValidatorChain) { + $input->setValidatorChain($value); + break; + } + if (!is_array($value) && !$value instanceof Traversable) { + throw new Exception\RuntimeException(sprintf( + '%s expects the value associated with "validators" to be an array/Traversable of validators or validator specifications, or a ValidatorChain; received "%s"', + __METHOD__, + (is_object($value) ? get_class($value) : gettype($value)) + )); + } + $this->populateValidators($input->getValidatorChain(), $value); + break; + default: + // ignore unknown keys + break; + } + } + + return $input; + } + + /** + * Factory for input filters + * + * @param array|Traversable $inputFilterSpecification + * @throws Exception\InvalidArgumentException + * @throws Exception\RuntimeException + * @return InputFilterInterface + */ + public function createInputFilter($inputFilterSpecification) + { + if (!is_array($inputFilterSpecification) && !$inputFilterSpecification instanceof Traversable) { + throw new Exception\InvalidArgumentException(sprintf( + '%s expects an array or Traversable; received "%s"', + __METHOD__, + (is_object($inputFilterSpecification) ? get_class($inputFilterSpecification) : gettype($inputFilterSpecification)) + )); + } + if ($inputFilterSpecification instanceof Traversable) { + $inputFilterSpecification = ArrayUtils::iteratorToArray($inputFilterSpecification); + } + + $class = 'Zend\InputFilter\InputFilter'; + if (isset($inputFilterSpecification['type']) && is_string($inputFilterSpecification['type'])) { + $class = $inputFilterSpecification['type']; + if (!class_exists($class)) { + throw new Exception\RuntimeException(sprintf( + 'Input factory expects the "type" to be a valid class; received "%s"', + $class + )); + } + unset($inputFilterSpecification['type']); + } + $inputFilter = new $class(); + + if (!$inputFilter instanceof InputFilterInterface) { + throw new Exception\RuntimeException(sprintf( + 'InputFilter factory expects the "type" to be a class implementing %s; received "%s"', + 'Zend\InputFilter\InputFilterInterface', $class)); + } + + if ($inputFilter instanceof CollectionInputFilter) { + if (isset($inputFilterSpecification['input_filter'])) { + $inputFilter->setInputFilter($inputFilterSpecification['input_filter']); + } + if (isset($inputFilterSpecification['count'])) { + $inputFilter->setCount($inputFilterSpecification['count']); + } + return $inputFilter; + } + + foreach ($inputFilterSpecification as $key => $value) { + + if (($value instanceof InputInterface) + || ($value instanceof InputFilterInterface) + ) { + $input = $value; + } else { + $input = $this->createInput($value); + } + + $inputFilter->add($input, $key); + } + + return $inputFilter; + } + + protected function populateFilters(FilterChain $chain, $filters) + { + foreach ($filters as $filter) { + if (is_object($filter) || is_callable($filter)) { + $chain->attach($filter); + continue; + } + + if (is_array($filter)) { + if (!isset($filter['name'])) { + throw new Exception\RuntimeException( + 'Invalid filter specification provided; does not include "name" key' + ); + } + $name = $filter['name']; + $options = array(); + if (isset($filter['options'])) { + $options = $filter['options']; + } + $chain->attachByName($name, $options); + continue; + } + + throw new Exception\RuntimeException( + 'Invalid filter specification provided; was neither a filter instance nor an array specification' + ); + } + } + + protected function populateValidators(ValidatorChain $chain, $validators) + { + foreach ($validators as $validator) { + if ($validator instanceof ValidatorInterface) { + $chain->attach($validator); + continue; + } + + if (is_array($validator)) { + if (!isset($validator['name'])) { + throw new Exception\RuntimeException( + 'Invalid validator specification provided; does not include "name" key' + ); + } + $name = $validator['name']; + $options = array(); + if (isset($validator['options'])) { + $options = $validator['options']; + } + $breakChainOnFailure = false; + if (isset($validator['break_chain_on_failure'])) { + $breakChainOnFailure = $validator['break_chain_on_failure']; + } + $chain->attachByName($name, $options, $breakChainOnFailure); + continue; + } + + throw new Exception\RuntimeException( + 'Invalid validator specification provided; was neither a validator instance nor an array specification' + ); + } + } +} diff --git a/src/Input.php b/src/Input.php index ea992313..759e44b1 100644 --- a/src/Input.php +++ b/src/Input.php @@ -19,7 +19,7 @@ class Input implements InputInterface, EmptyContextInterface * @var bool */ protected $allowEmpty = false; - + /** * @var bool */ @@ -94,7 +94,7 @@ public function setBreakOnFailure($breakOnFailure) $this->breakOnFailure = (bool) $breakOnFailure; return $this; } - + /** * @param bool $continueIfEmpty * @return \Zend\InputFilter\Input @@ -190,7 +190,7 @@ public function breakOnFailure() { return $this->breakOnFailure; } - + /** * @return bool */ diff --git a/test/BaseInputFilterTest.php b/test/BaseInputFilterTest.php index 3a26efb6..4af65579 100644 --- a/test/BaseInputFilterTest.php +++ b/test/BaseInputFilterTest.php @@ -535,7 +535,7 @@ public function testValidationAllowsEmptyValuesToRequiredInputWhenAllowEmptyFlag 'bar' => 124, 'foo' => '', ); - + $filter->setData($data); $this->assertTrue($filter->isValid()); @@ -563,7 +563,7 @@ public function testValidationMarksInputInvalidWhenRequiredAndAllowEmptyFlagIsFa $this->assertFalse($filter->isValid()); } - + public static function contextDataProvider() { return array( @@ -571,9 +571,9 @@ public static function contextDataProvider() array('', 'n', false), ); } - + /** - * Idea here is that an empty field may or may not be valid based on + * Idea here is that an empty field may or may not be valid based on * context. */ /** @@ -582,28 +582,28 @@ public static function contextDataProvider() public function testValidationMarksInputValidWhenAllowEmptyFlagIsTrueAndContinueIfEmptyIsTrueAndContextValidatesEmptyField($allowEmpty, $blankIsValid, $valid) { // $this->markTestSkipped(); - + $filter = new InputFilter(); - + $data = array ( 'allowEmpty' => $allowEmpty, 'blankIsValid' => $blankIsValid, ); - + $allowEmpty = new Input(); $allowEmpty->setAllowEmpty(true) ->setContinueIfEmpty(true); - + $blankIsValid = new Input(); $blankIsValid->getValidatorChain()->attach(new Validator\Callback(function($value, $context) { return ('y' === $value && empty($context['allowEmpty'])); })); - + $filter->add($allowEmpty, 'allowEmpty') - ->add($blankIsValid, 'blankIsValid'); + ->add($blankIsValid, 'blankIsValid'); $filter->setData($data); // die(var_dump($filter->get('blankIsValid'))); - + $this->assertSame($valid, $filter->isValid()); } diff --git a/test/FactoryTest.php b/test/FactoryTest.php index e93fa496..eebcb71b 100644 --- a/test/FactoryTest.php +++ b/test/FactoryTest.php @@ -239,7 +239,7 @@ public function testFactoryWillCreateInputWithSuggestedName() $this->assertInstanceOf('Zend\InputFilter\InputInterface', $input); $this->assertEquals('foo', $input->getName()); } - + public function testFactoryWillCreateInputWithContinueIfEmptyFlag() { $factory = new Factory(); diff --git a/test/InputTest.php b/test/InputTest.php index d86e96c2..f2c2caa0 100644 --- a/test/InputTest.php +++ b/test/InputTest.php @@ -81,20 +81,20 @@ public function testAllowEmptyFlagIsMutable() $this->input->setAllowEmpty(true); $this->assertTrue($this->input->allowEmpty()); } - + public function testContinueIfEmptyFlagIsFalseByDefault() { $input = new Input('foo'); $this->assertFalse($input->continueIfEmpty()); } - + public function testContinueIfEmptyFlagIsMutable() { $input = new Input('foo'); $input->setContinueIfEmpty(true); $this->assertTrue($input->continueIfEmpty()); } - + public function testNotEmptyValidatorNotInjectedIfContinueIfEmptyIsTrue() { $input = new Input('foo'); From 10feb023fe05d2932f4752374e44cf5dde3ad413 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C3=ABl=20Gallego?= Date: Thu, 25 Apr 2013 18:51:09 +0200 Subject: [PATCH 12/24] Add untracked files --- src/InputFilterPluginManager.php | 35 ++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 src/InputFilterPluginManager.php diff --git a/src/InputFilterPluginManager.php b/src/InputFilterPluginManager.php new file mode 100644 index 00000000..33b7ef39 --- /dev/null +++ b/src/InputFilterPluginManager.php @@ -0,0 +1,35 @@ + Date: Thu, 25 Apr 2013 22:26:11 +0200 Subject: [PATCH 13/24] Inject validator chain in input filter factory --- composer.json | 3 +++ src/BaseInputFilter.php | 1 + src/InputFilterPluginManager.php | 31 +++++++++++++++++++++++++++++++ 3 files changed, 35 insertions(+) diff --git a/composer.json b/composer.json index cd624f0a..814dfa5b 100644 --- a/composer.json +++ b/composer.json @@ -17,6 +17,9 @@ "zendframework/zend-validator": "self.version", "zendframework/zend-stdlib": "self.version" }, + "suggest": { + "zendframework/zend-servicemanager": "For using the plugin manager" + }, "extra": { "branch-alias": { "dev-master": "2.1-dev", diff --git a/src/BaseInputFilter.php b/src/BaseInputFilter.php index c3688b24..1e06f0ad 100644 --- a/src/BaseInputFilter.php +++ b/src/BaseInputFilter.php @@ -469,6 +469,7 @@ public function getMessages() foreach ($this->getInvalidInput() as $name => $input) { $messages[$name] = $input->getMessages(); } + return $messages; } diff --git a/src/InputFilterPluginManager.php b/src/InputFilterPluginManager.php index 33b7ef39..e4b03673 100644 --- a/src/InputFilterPluginManager.php +++ b/src/InputFilterPluginManager.php @@ -11,17 +11,48 @@ use Zend\InputFilter\Exception; use Zend\ServiceManager\AbstractPluginManager; +use Zend\ServiceManager\ConfigInterface; +use Zend\Stdlib\InitializableInterface; /** * Plugin manager implementation for input filters. */ class InputFilterPluginManager extends AbstractPluginManager { + /** + * @param ConfigInterface $configuration + */ + public function __construct(ConfigInterface $configuration = null) + { + parent::__construct($configuration); + + $this->addInitializer(array($this, 'populateFactory')); + } + + /** + * Populate the factory with filter chain and validator chain + * + * @param $element + */ + public function populateFactory($element) + { + if ($element instanceof InputFilter) { + $factory = $element->getFactory(); + $factory->getDefaultFilterChain()->setPluginManager($this->serviceLocator->get('FilterManager')); + $factory->getDefaultValidatorChain()->setPluginManager($this->serviceLocator->get('ValidatorManager')); + } + } + /** * {@inheritDoc} */ public function validatePlugin($plugin) { + // Hook to perform various initialization, when the element is not created through the factory + if ($plugin instanceof InitializableInterface) { + $plugin->init(); + } + if ($plugin instanceof InputFilterInterface) { // we're okay return; From 098054520c435c8896407fe8317fdcec447b1856 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C3=ABl=20Gallego?= Date: Fri, 26 Apr 2013 12:09:39 +0200 Subject: [PATCH 14/24] Fix CS --- composer.json | 2 +- test/InputFilterManagerTest.php | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/composer.json b/composer.json index 814dfa5b..ceaf56dd 100644 --- a/composer.json +++ b/composer.json @@ -18,7 +18,7 @@ "zendframework/zend-stdlib": "self.version" }, "suggest": { - "zendframework/zend-servicemanager": "For using the plugin manager" + "zendframework/zend-servicemanager": "To support plugin manager support" }, "extra": { "branch-alias": { diff --git a/test/InputFilterManagerTest.php b/test/InputFilterManagerTest.php index 417f5e53..db424971 100644 --- a/test/InputFilterManagerTest.php +++ b/test/InputFilterManagerTest.php @@ -15,8 +15,6 @@ /** * @category Zend - * @package Zend_Stdlib - * @subpackage UnitTests * @group Zend_Stdlib */ class InputFilterManagerTest extends \PHPUnit_Framework_TestCase From 01a81be59d3289fe0ba26e9588948d633ab0c619 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C3=ABl=20Gallego?= Date: Fri, 26 Apr 2013 16:25:53 +0200 Subject: [PATCH 15/24] Default validator and filter chains --- src/Factory.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/Factory.php b/src/Factory.php index 54be66d2..77b2f865 100644 --- a/src/Factory.php +++ b/src/Factory.php @@ -20,6 +20,12 @@ class Factory protected $defaultFilterChain; protected $defaultValidatorChain; + public function __construct() + { + $this->defaultFilterChain = new FilterChain(); + $this->defaultValidatorChain = new ValidatorChain(); + } + /** * Set default filter chain to use * From 6cfc168b0dab54c4eb324ee2edb66b373859b8b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C3=ABl=20Gallego?= Date: Fri, 26 Apr 2013 22:12:01 +0200 Subject: [PATCH 16/24] Add initializable interface to input filter --- src/BaseInputFilter.php | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/BaseInputFilter.php b/src/BaseInputFilter.php index 1e06f0ad..470b844c 100644 --- a/src/BaseInputFilter.php +++ b/src/BaseInputFilter.php @@ -12,12 +12,13 @@ use ArrayAccess; use Traversable; use Zend\Stdlib\ArrayUtils; +use Zend\Stdlib\InitializableInterface; /** * @todo How should we deal with required input when data is missing? * should a message be returned? if so, what message? */ -class BaseInputFilter implements InputFilterInterface, UnknownInputsCapableInterface +class BaseInputFilter implements InputFilterInterface, UnknownInputsCapableInterface, InitializableInterface { protected $data; protected $inputs = array(); @@ -25,6 +26,16 @@ class BaseInputFilter implements InputFilterInterface, UnknownInputsCapableInter protected $validationGroup; protected $validInputs; + /** + * This function is automatically called when creating element with factory. It + * allows to perform various operations (add elements...) + * + * @return void + */ + public function init() + { + } + /** * Countable: number of inputs in this input filter * From 1d07094a855596bf48239a28409f02bf03e657a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C3=ABl=20Gallego?= Date: Fri, 26 Apr 2013 22:27:58 +0200 Subject: [PATCH 17/24] Feedbacks --- src/BaseInputFilter.php | 2 +- src/InputFilterPluginManager.php | 13 +++++++------ test/InputFilterManagerTest.php | 4 +--- 3 files changed, 9 insertions(+), 10 deletions(-) diff --git a/src/BaseInputFilter.php b/src/BaseInputFilter.php index 470b844c..50757c36 100644 --- a/src/BaseInputFilter.php +++ b/src/BaseInputFilter.php @@ -35,7 +35,7 @@ class BaseInputFilter implements InputFilterInterface, UnknownInputsCapableInter public function init() { } - + /** * Countable: number of inputs in this input filter * diff --git a/src/InputFilterPluginManager.php b/src/InputFilterPluginManager.php index e4b03673..63e2b878 100644 --- a/src/InputFilterPluginManager.php +++ b/src/InputFilterPluginManager.php @@ -12,6 +12,7 @@ use Zend\InputFilter\Exception; use Zend\ServiceManager\AbstractPluginManager; use Zend\ServiceManager\ConfigInterface; +use Zend\ServiceManager\ServiceLocatorInterface; use Zend\Stdlib\InitializableInterface; /** @@ -36,7 +37,7 @@ public function __construct(ConfigInterface $configuration = null) */ public function populateFactory($element) { - if ($element instanceof InputFilter) { + if ($element instanceof InputFilter && $this->serviceLocator instanceof ServiceLocatorInterface) { $factory = $element->getFactory(); $factory->getDefaultFilterChain()->setPluginManager($this->serviceLocator->get('FilterManager')); $factory->getDefaultValidatorChain()->setPluginManager($this->serviceLocator->get('ValidatorManager')); @@ -48,12 +49,12 @@ public function populateFactory($element) */ public function validatePlugin($plugin) { - // Hook to perform various initialization, when the element is not created through the factory - if ($plugin instanceof InitializableInterface) { - $plugin->init(); - } - if ($plugin instanceof InputFilterInterface) { + // Hook to perform various initialization, when the element is not created through the factory + if ($plugin instanceof InitializableInterface) { + $plugin->init(); + } + // we're okay return; } diff --git a/test/InputFilterManagerTest.php b/test/InputFilterManagerTest.php index db424971..5993bc6c 100644 --- a/test/InputFilterManagerTest.php +++ b/test/InputFilterManagerTest.php @@ -5,7 +5,6 @@ * @link http://github.com/zendframework/zf2 for the canonical source repository * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com) * @license http://framework.zend.com/license/new-bsd New BSD License - * @package Zend_Form */ namespace ZendTest\InputFilter; @@ -14,8 +13,7 @@ use Zend\InputFilter\InputFilterPluginManager; /** - * @category Zend - * @group Zend_Stdlib + * @group Zend_Stdlib */ class InputFilterManagerTest extends \PHPUnit_Framework_TestCase { From 082aca056a7a088f647d1e1f70227cf6c5e7b143 Mon Sep 17 00:00:00 2001 From: Matthew Weier O'Phinney Date: Fri, 26 Apr 2013 16:06:45 -0500 Subject: [PATCH 18/24] [zendframework/zf2#4319] Fix tests - Intention changed mid-PR, but tests were not updated; demonstrate that Factory composes a default filter chain and validator chain by default. --- test/FactoryTest.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/FactoryTest.php b/test/FactoryTest.php index b5947d61..8c590bba 100644 --- a/test/FactoryTest.php +++ b/test/FactoryTest.php @@ -19,16 +19,16 @@ class FactoryTest extends TestCase { - public function testFactoryDoesNotComposeFilterChainByDefault() + public function testFactoryComposesFilterChainByDefault() { $factory = new Factory(); - $this->assertNull($factory->getDefaultFilterChain()); + $this->assertInstanceOf('Zend\Filter\FilterChain', $factory->getDefaultFilterChain()); } - public function testFactoryDoesNotComposeValidatorChainByDefault() + public function testFactoryComposesValidatorChainByDefault() { $factory = new Factory(); - $this->assertNull($factory->getDefaultValidatorChain()); + $this->assertInstanceOf('Zend\Validator\ValidatorChain', $factory->getDefaultValidatorChain()); } public function testFactoryAllowsInjectingFilterChain() From c875fbc6e4cd8abb3910d2a7e11b527c554a2fe6 Mon Sep 17 00:00:00 2001 From: Matthew Weier O'Phinney Date: Fri, 26 Apr 2013 16:08:24 -0500 Subject: [PATCH 19/24] [zendframework/zf2#4319] Do not share input filter instances by default --- src/InputFilterPluginManager.php | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/InputFilterPluginManager.php b/src/InputFilterPluginManager.php index 63e2b878..8a145b02 100644 --- a/src/InputFilterPluginManager.php +++ b/src/InputFilterPluginManager.php @@ -20,6 +20,13 @@ */ class InputFilterPluginManager extends AbstractPluginManager { + /** + * Whether or not to share by default + * + * @var bool + */ + protected $shareByDefault = false; + /** * @param ConfigInterface $configuration */ From 9cae362b89122799fec77c6cc8202e7f60d8e415 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20M=C3=B6ller?= Date: Sun, 28 Apr 2013 19:35:44 +0200 Subject: [PATCH 20/24] Alphabetically order use statements (related to zendframework/zf2#4338) --- src/Factory.php | 2 +- src/Input.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Factory.php b/src/Factory.php index 77b2f865..89584853 100644 --- a/src/Factory.php +++ b/src/Factory.php @@ -12,8 +12,8 @@ use Traversable; use Zend\Filter\FilterChain; use Zend\Stdlib\ArrayUtils; -use Zend\Validator\ValidatorChain; use Zend\Validator\ValidatorInterface; +use Zend\Validator\ValidatorChain; class Factory { diff --git a/src/Input.php b/src/Input.php index 759e44b1..e4cf2bf0 100644 --- a/src/Input.php +++ b/src/Input.php @@ -10,8 +10,8 @@ namespace Zend\InputFilter; use Zend\Filter\FilterChain; -use Zend\Validator\ValidatorChain; use Zend\Validator\NotEmpty; +use Zend\Validator\ValidatorChain; class Input implements InputInterface, EmptyContextInterface { From fa9d1ef2c6345332ab9288ecb36ce622d1858cca Mon Sep 17 00:00:00 2001 From: Nicolas Eeckeloo Date: Mon, 29 Apr 2013 08:41:10 +0200 Subject: [PATCH 21/24] Fix doc blocks consistency --- src/BaseInputFilter.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/BaseInputFilter.php b/src/BaseInputFilter.php index 50757c36..5416276a 100644 --- a/src/BaseInputFilter.php +++ b/src/BaseInputFilter.php @@ -171,7 +171,7 @@ public function isValid() * Validate a set of inputs against the current data * * @param array $inputs - * @return boolean + * @return bool */ protected function validateInputs(array $inputs) { From fbdeaf1df4f1148a000771cdc30a61e767ed9820 Mon Sep 17 00:00:00 2001 From: Daniel Gimenes Date: Tue, 30 Apr 2013 20:30:19 -0300 Subject: [PATCH 22/24] Register default invokables --- src/InputFilterPluginManager.php | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/InputFilterPluginManager.php b/src/InputFilterPluginManager.php index 8a145b02..04ffcb5b 100644 --- a/src/InputFilterPluginManager.php +++ b/src/InputFilterPluginManager.php @@ -20,6 +20,16 @@ */ class InputFilterPluginManager extends AbstractPluginManager { + /** + * Default set of plugins + * + * @var array + */ + protected $invokableClasses = array( + 'inputfilter' => 'Zend\InputFilter\InputFilter', + 'collection' => 'Zend\InputFilter\CollectionInputFilter', + ); + /** * Whether or not to share by default * From 8d545b65188b9bac549a176cb1cfb9e6d6d3b030 Mon Sep 17 00:00:00 2001 From: Daniel Gimenes Date: Tue, 30 Apr 2013 21:45:25 -0300 Subject: [PATCH 23/24] Use InputFilterPluginManager in InputFilter\Factory --- src/Factory.php | 63 ++++++++++++++++++++++++++++++++++++------------- 1 file changed, 47 insertions(+), 16 deletions(-) diff --git a/src/Factory.php b/src/Factory.php index e4e42676..3382afde 100644 --- a/src/Factory.php +++ b/src/Factory.php @@ -27,8 +27,20 @@ class Factory */ protected $defaultValidatorChain; - public function __construct() + /** + * @var InputFilterPluginManager + */ + protected $inputFilterManager; + + /** + * @param InputFilterPluginManager $inputFilterManager + */ + public function __construct(InputFilterPluginManager $inputFilterManager = null) { + if ($inputFilterManager) { + $this->setInputFilterManager($inputFilterManager); + } + $this->defaultFilterChain = new FilterChain(); $this->defaultValidatorChain = new ValidatorChain(); } @@ -97,6 +109,29 @@ public function clearDefaultValidatorChain() $this->defaultValidatorChain = null; } + /** + * @param InputFilterPluginManager $inputFilterManager + * @return self + */ + public function setInputFilterManager(InputFilterPluginManager $inputFilterManager) + { + $this->inputFilterManager = $inputFilterManager; + + return $this; + } + + /** + * @return InputFilterPluginManager + */ + public function getInputFilterManager() + { + if (null === $this->inputFilterManager) { + $this->inputFilterManager = new InputFilterPluginManager; + } + + return $this->inputFilterManager; + } + /** * Factory for input objects * @@ -119,8 +154,14 @@ public function createInput($inputSpecification) } $class = 'Zend\InputFilter\Input'; + if (isset($inputSpecification['type'])) { $class = $inputSpecification['type']; + + if ($this->getInputFilterManager()->has($class)) { + return $this->createInputFilter($inputSpecification); + } + if (!class_exists($class)) { throw new Exception\RuntimeException(sprintf( 'Input factory expects the "type" to be a valid class; received "%s"', @@ -232,24 +273,14 @@ public function createInputFilter($inputFilterSpecification) $inputFilterSpecification = ArrayUtils::iteratorToArray($inputFilterSpecification); } - $class = 'Zend\InputFilter\InputFilter'; - if (isset($inputFilterSpecification['type']) && is_string($inputFilterSpecification['type'])) { - $class = $inputFilterSpecification['type']; - if (!class_exists($class)) { - throw new Exception\RuntimeException(sprintf( - 'Input factory expects the "type" to be a valid class; received "%s"', - $class - )); - } + $type = 'Zend\InputFilter\InputFilter'; + + if (isset($inputFilterSpecification['type'])) { + $type = $inputFilterSpecification['type']; unset($inputFilterSpecification['type']); } - $inputFilter = new $class(); - if (!$inputFilter instanceof InputFilterInterface) { - throw new Exception\RuntimeException(sprintf( - 'InputFilter factory expects the "type" to be a class implementing %s; received "%s"', - 'Zend\InputFilter\InputFilterInterface', $class)); - } + $inputFilter = $this->getInputFilterManager()->get($type); if ($inputFilter instanceof CollectionInputFilter) { if (isset($inputFilterSpecification['input_filter'])) { From df700a55f1a4e3ae02b300236335eac3cfc01495 Mon Sep 17 00:00:00 2001 From: Daniel Gimenes Date: Tue, 30 Apr 2013 21:47:03 -0300 Subject: [PATCH 24/24] Inject InputFilterPluginManager in InputFilter\Factory And rename $element to $inputFilter --- src/InputFilterPluginManager.php | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/src/InputFilterPluginManager.php b/src/InputFilterPluginManager.php index 04ffcb5b..757e3dc2 100644 --- a/src/InputFilterPluginManager.php +++ b/src/InputFilterPluginManager.php @@ -48,16 +48,21 @@ public function __construct(ConfigInterface $configuration = null) } /** - * Populate the factory with filter chain and validator chain + * Inject this and populate the factory with filter chain and validator chain * - * @param $element + * @param $inputfilter */ - public function populateFactory($element) + public function populateFactory($inputfilter) { - if ($element instanceof InputFilter && $this->serviceLocator instanceof ServiceLocatorInterface) { - $factory = $element->getFactory(); - $factory->getDefaultFilterChain()->setPluginManager($this->serviceLocator->get('FilterManager')); - $factory->getDefaultValidatorChain()->setPluginManager($this->serviceLocator->get('ValidatorManager')); + if ($inputfilter instanceof InputFilter) { + $factory = $inputfilter->getFactory(); + + $factory->setInputFilterManager($this); + + if ($this->serviceLocator instanceof ServiceLocatorInterface) { + $factory->getDefaultFilterChain()->setPluginManager($this->serviceLocator->get('FilterManager')); + $factory->getDefaultValidatorChain()->setPluginManager($this->serviceLocator->get('ValidatorManager')); + } } } @@ -67,7 +72,7 @@ public function populateFactory($element) public function validatePlugin($plugin) { if ($plugin instanceof InputFilterInterface) { - // Hook to perform various initialization, when the element is not created through the factory + // Hook to perform various initialization, when the inputfilter is not created through the factory if ($plugin instanceof InitializableInterface) { $plugin->init(); }