Skip to content
This repository has been archived by the owner on Jan 30, 2020. It is now read-only.

Commit

Permalink
Merge branch 'hotfix/3246' into develop
Browse files Browse the repository at this point in the history
  • Loading branch information
Show file tree
Hide file tree
Showing 2 changed files with 90 additions and 41 deletions.
30 changes: 16 additions & 14 deletions src/FileInput.php
Original file line number Diff line number Diff line change
Expand Up @@ -51,22 +51,24 @@ public function getAutoPrependUploadValidator()
*/
public function getValue()
{
$filter = $this->getFilterChain();
$value = (is_array($this->value) && isset($this->value['tmp_name']))
? $this->value['tmp_name'] : $this->value;
if (is_scalar($value) && $this->isValid) {
// Single file input
$value = $filter->filter($value);
} elseif (is_array($value)) {
// Multi file input (multiple attribute set)
$newValue = array();
foreach ($value as $multiFileData) {
$fileName = (is_array($multiFileData) && isset($multiFileData['tmp_name']))
? $multiFileData['tmp_name'] : $multiFileData;
$newValue[] = ($this->isValid) ? $filter->filter($fileName) : $fileName;
$value = $this->value;
if ($this->isValid && is_array($value)) {
$filter = $this->getFilterChain();
if (isset($value['tmp_name'])) {
// Single file input
$value = $filter->filter($value);
} else {
// Multi file input (multiple attribute set)
$newValue = array();
foreach ($value as $fileData) {
if (is_array($fileData) && isset($fileData['tmp_name'])) {
$newValue[] = $filter->filter($fileData);
}
}
$value = $newValue;
}
$value = $newValue;
}

return $value;
}

Expand Down
101 changes: 74 additions & 27 deletions test/FileInputTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -86,29 +86,36 @@ public function testValueIsNullByDefault()

public function testValueMayBeInjected()
{
$this->input->setValue(array('tmp_name' => 'bar'));
$this->assertEquals('bar', $this->input->getValue());
$value = array('tmp_name' => 'bar');
$this->input->setValue($value);
$this->assertEquals($value, $this->input->getValue());
}

public function testRetrievingValueFiltersTheValueOnlyAfterValidating()
{
$this->input->setValue(array('tmp_name' => 'bar'));
$filter = new Filter\StringToUpper();
$this->input->getFilterChain()->attach($filter);
$this->assertEquals('bar', $this->input->getValue());
$this->assertTrue($this->input->isValid());
$this->assertEquals('BAR', $this->input->getValue());
}

public function testCanFilterArrayOfFileData()
{
$value = array('tmp_name' => 'foo');
$value = array('tmp_name' => 'bar');
$this->input->setValue($value);
$filter = new Filter\StringToUpper();
$this->input->getFilterChain()->attach($filter);
$this->assertEquals('foo', $this->input->getValue());

$newValue = array('tmp_name' => 'foo');
$filterMock = $this->getMockBuilder('Zend\Filter\File\Rename')
->disableOriginalConstructor()
->getMock();
$filterMock->expects($this->any())
->method('filter')
->will($this->returnValue($newValue));

// Why not attach mocked filter directly?
// No worky without wrapping in a callback.
// Missing something in mock setup?
$this->input->getFilterChain()->attach(
function ($value) use ($filterMock) {
return $filterMock->filter($value);
}
);

$this->assertEquals($value, $this->input->getValue());
$this->assertTrue($this->input->isValid());
$this->assertEquals('FOO', $this->input->getValue());
$this->assertEquals($newValue, $this->input->getValue());
}

public function testCanFilterArrayOfMultiFileData()
Expand All @@ -119,11 +126,30 @@ public function testCanFilterArrayOfMultiFileData()
array('tmp_name' => 'baz'),
);
$this->input->setValue($values);
$filter = new Filter\StringToUpper();
$this->input->getFilterChain()->attach($filter);
$this->assertEquals(array('foo', 'bar', 'baz'), $this->input->getValue());

$newValue = array('tmp_name' => 'new');
$filterMock = $this->getMockBuilder('Zend\Filter\File\Rename')
->disableOriginalConstructor()
->getMock();
$filterMock->expects($this->any())
->method('filter')
->will($this->returnValue($newValue));

// Why not attach mocked filter directly?
// No worky without wrapping in a callback.
// Missing something in mock setup?
$this->input->getFilterChain()->attach(
function ($value) use ($filterMock) {
return $filterMock->filter($value);
}
);

$this->assertEquals($values, $this->input->getValue());
$this->assertTrue($this->input->isValid());
$this->assertEquals(array('FOO', 'BAR', 'BAZ'), $this->input->getValue());
$this->assertEquals(
array($newValue, $newValue, $newValue),
$this->input->getValue()
);
}

public function testCanRetrieveRawValue()
Expand Down Expand Up @@ -153,24 +179,45 @@ public function testIsValidReturnsTrueIfValidationChainSucceeds()

public function testValidationOperatesBeforeFiltering()
{
$this->input->setValue(array(
$badValue = array(
'tmp_name' => ' ' . __FILE__ . ' ',
'name' => 'foo',
'size' => 1,
'error' => 0,
));
$filter = new Filter\StringTrim();
$this->input->getFilterChain()->attach($filter);
);
$this->input->setValue($badValue);

$filteredValue = array('tmp_name' => 'new');
$filterMock = $this->getMockBuilder('Zend\Filter\File\Rename')
->disableOriginalConstructor()
->getMock();
$filterMock->expects($this->any())
->method('filter')
->will($this->returnValue($filteredValue));

// Why not attach mocked filter directly?
// No worky without wrapping in a callback.
// Missing something in mock setup?
$this->input->getFilterChain()->attach(
function ($value) use ($filterMock) {
return $filterMock->filter($value);
}
);

$validator = new Validator\File\Exists();
$this->input->getValidatorChain()->attach($validator);
$this->assertFalse($this->input->isValid());
$this->input->setValue(array(
$this->assertEquals($badValue, $this->input->getValue());

$goodValue = array(
'tmp_name' => __FILE__,
'name' => 'foo',
'size' => 1,
'error' => 0,
));
);
$this->input->setValue($goodValue);
$this->assertTrue($this->input->isValid());
$this->assertEquals($filteredValue, $this->input->getValue());
}

public function testGetMessagesReturnsValidationMessages()
Expand Down

0 comments on commit ecabb9a

Please sign in to comment.