[HttpFoundation] moved File Component into the HttpFoundation one

This commit is contained in:
Fabien Potencier 2010-09-09 14:40:40 +02:00
parent fc9325a737
commit a141c98917
20 changed files with 178 additions and 235 deletions

View File

@ -162,7 +162,7 @@ class Form extends FieldGroup
* already merged into the data array.
*
* @param array $taintedValues The form data of the $_POST array
* @param array $taintedFiles The form data of the $_FILES array
* @param array $taintedFiles An array of uploaded files
* @return boolean Whether the form is valid
*/
final public function bind($taintedValues, array $taintedFiles = null)
@ -173,8 +173,6 @@ class Form extends FieldGroup
}
$taintedFiles = array();
} else {
$taintedFiles = self::convertFileInformation(self::fixPhpFilesArray($taintedFiles));
}
if (null === $taintedValues) {
@ -458,69 +456,4 @@ class Form extends FieldGroup
return $array1;
}
/**
* Fixes a malformed PHP $_FILES array.
*
* PHP has a bug that the format of the $_FILES array differs, depending on
* whether the uploaded file fields had normal field names or array-like
* field names ("normal" vs. "parent[child]").
*
* This method fixes the array to look like the "normal" $_FILES array.
*
* @param array $data
* @return array
*/
static protected function fixPhpFilesArray(array $data)
{
$fileKeys = array('error', 'name', 'size', 'tmp_name', 'type');
$keys = array_keys($data);
sort($keys);
$files = $data;
if ($fileKeys == $keys && isset($data['name']) && is_array($data['name'])) {
foreach ($fileKeys as $k) {
unset($files[$k]);
}
foreach (array_keys($data['name']) as $key) {
$files[$key] = self::fixPhpFilesArray(array(
'error' => $data['error'][$key],
'name' => $data['name'][$key],
'type' => $data['type'][$key],
'tmp_name' => $data['tmp_name'][$key],
'size' => $data['size'][$key],
));
}
}
return $files;
}
/**
* Converts uploaded files to instances of clsas UploadedFile.
*
* @param array $files A (multi-dimensional) array of uploaded file information
* @return array A (multi-dimensional) array of UploadedFile instances
*/
static protected function convertFileInformation(array $files)
{
$fileKeys = array('error', 'name', 'size', 'tmp_name', 'type');
foreach ($files as $key => $data) {
if (is_array($data)) {
$keys = array_keys($data);
sort($keys);
if ($keys == $fileKeys) {
$files[$key] = new UploadedFile($data['tmp_name'], $data['name'], $data['type'], $data['size'], $data['error']);
} else {
$files[$key] = self::convertFileInformation($data);
}
}
}
return $files;
}
}

View File

@ -1,6 +1,6 @@
<?php
namespace Symfony\Component\File\Exception;
namespace Symfony\Component\HttpFoundation\File\Exception;
/*
* This file is part of the symfony package.

View File

@ -1,6 +1,6 @@
<?php
namespace Symfony\Component\File\Exception;
namespace Symfony\Component\HttpFoundation\File\Exception;
/*
* This file is part of the symfony package.

View File

@ -1,6 +1,6 @@
<?php
namespace Symfony\Component\File\Exception;
namespace Symfony\Component\HttpFoundation\File\Exception;
/*
* This file is part of the symfony package.

View File

@ -1,10 +1,10 @@
<?php
namespace Symfony\Component\File;
namespace Symfony\Component\HttpFoundation\File;
use Symfony\Component\File\Exception\FileException;
use Symfony\Component\File\Exception\FileNotFoundException;
use Symfony\Component\File\MimeType\MimeTypeGuesser;
use Symfony\Component\HttpFoundation\File\Exception\FileException;
use Symfony\Component\HttpFoundation\File\Exception\FileNotFoundException;
use Symfony\Component\HttpFoundation\File\MimeType\MimeTypeGuesser;
/*
* This file is part of the symfony package.

View File

@ -1,9 +1,9 @@
<?php
namespace Symfony\Component\File\MimeType;
namespace Symfony\Component\HttpFoundation\File\MimeType;
use Symfony\Component\File\Exception\FileNotFoundException;
use Symfony\Component\File\Exception\AccessDeniedException;
use Symfony\Component\HttpFoundation\File\Exception\FileNotFoundException;
use Symfony\Component\HttpFoundation\File\Exception\AccessDeniedException;
/*
* This file is part of the symfony package.

View File

@ -1,9 +1,9 @@
<?php
namespace Symfony\Component\File\MimeType;
namespace Symfony\Component\HttpFoundation\File\MimeType;
use Symfony\Component\File\Exception\FileNotFoundException;
use Symfony\Component\File\Exception\AccessDeniedException;
use Symfony\Component\HttpFoundation\File\Exception\FileNotFoundException;
use Symfony\Component\HttpFoundation\File\Exception\AccessDeniedException;
/*
* This file is part of the symfony package.

View File

@ -1,9 +1,9 @@
<?php
namespace Symfony\Component\File\MimeType;
namespace Symfony\Component\HttpFoundation\File\MimeType;
use Symfony\Component\File\Exception\FileNotFoundException;
use Symfony\Component\File\Exception\AccessDeniedException;
use Symfony\Component\HttpFoundation\File\Exception\FileNotFoundException;
use Symfony\Component\HttpFoundation\File\Exception\AccessDeniedException;
/*
* This file is part of the symfony package.

View File

@ -1,9 +1,9 @@
<?php
namespace Symfony\Component\File\MimeType;
namespace Symfony\Component\HttpFoundation\File\MimeType;
use Symfony\Component\File\Exception\FileNotFoundException;
use Symfony\Component\File\Exception\AccessDeniedException;
use Symfony\Component\HttpFoundation\File\Exception\FileNotFoundException;
use Symfony\Component\HttpFoundation\File\Exception\AccessDeniedException;
/*
* This file is part of the symfony package.

View File

@ -1,6 +1,6 @@
<?php
namespace Symfony\Component\File\MimeType;
namespace Symfony\Component\HttpFoundation\File\MimeType;
/*
* This file is part of the symfony package.

View File

@ -1,8 +1,8 @@
<?php
namespace Symfony\Component\File;
namespace Symfony\Component\HttpFoundation\File;
use Symfony\Component\File\Exception\FileException;
use Symfony\Component\HttpFoundation\File\Exception\FileException;
/*
* This file is part of the symfony package.

View File

@ -3,6 +3,7 @@
namespace Symfony\Component\HttpFoundation;
use Symfony\Component\HttpFoundation\SessionStorage\NativeSessionStorage;
use Symfony\Component\HttpFoundation\File\UploadedFile;
/*
* This file is part of the Symfony package.
@ -846,19 +847,74 @@ class Request
}
/**
* Converts uploaded file array to a format following the $_GET and $POST naming convention.
* Converts uploaded files to UploadedFile instances.
*
* It's safe to pass an already converted array, in which case this method just returns the original array unmodified.
* @param array $files A (multi-dimensional) array of uploaded file information
*
* @param array $taintedFiles An array representing uploaded file information
*
* @return array An array of re-ordered uploaded file information
* @return array A (multi-dimensional) array of UploadedFile instances
*/
protected function convertFileInformation(array $taintedFiles)
protected function convertFileInformation(array $files)
{
$files = array();
foreach ($taintedFiles as $key => $data) {
$files[$key] = $this->fixPhpFilesArray($data);
$fixedFiles = array();
foreach ($files as $key => $data) {
$fixedFiles[$key] = $this->fixPhpFilesArray($data);
}
$fileKeys = array('error', 'name', 'size', 'tmp_name', 'type');
foreach ($fixedFiles as $key => $data) {
if (is_array($data)) {
$keys = array_keys($data);
sort($keys);
if ($keys == $fileKeys) {
$fixedFiles[$key] = new UploadedFile($data['tmp_name'], $data['name'], $data['type'], $data['size'], $data['error']);
} else {
$fixedFiles[$key] = $this->convertFileInformation($data);
}
}
}
return $fixedFiles;
}
/**
* Fixes a malformed PHP $_FILES array.
*
* PHP has a bug that the format of the $_FILES array differs, depending on
* whether the uploaded file fields had normal field names or array-like
* field names ("normal" vs. "parent[child]").
*
* This method fixes the array to look like the "normal" $_FILES array.
*
* It's safe to pass an already converted array, in which case this method
* just returns the original array unmodified.
*
* @param array $data
* @return array
*/
protected function fixPhpFilesArray($data)
{
$fileKeys = array('error', 'name', 'size', 'tmp_name', 'type');
$keys = array_keys($data);
sort($keys);
if ($fileKeys != $keys || !isset($data['name']) || !is_array($data['name'])) {
return $data;
}
$files = $data;
foreach ($fileKeys as $k) {
unset($files[$k]);
}
foreach (array_keys($data['name']) as $key) {
$files[$key] = $this->fixPhpFilesArray(array(
'error' => $data['error'][$key],
'name' => $data['name'][$key],
'type' => $data['type'][$key],
'tmp_name' => $data['tmp_name'][$key],
'size' => $data['size'][$key],
));
}
return $files;
@ -888,31 +944,4 @@ class Request
'atom' => 'application/atom+xml',
);
}
static protected function fixPhpFilesArray($data)
{
$fileKeys = array('error', 'name', 'size', 'tmp_name', 'type');
$keys = array_keys($data);
sort($keys);
if ($fileKeys != $keys || !isset($data['name']) || !is_array($data['name'])) {
return $data;
}
$files = $data;
foreach ($fileKeys as $k) {
unset($files[$k]);
}
foreach (array_keys($data['name']) as $key) {
$files[$key] = self::fixPhpFilesArray(array(
'error' => $data['error'][$key],
'name' => $data['name'][$key],
'type' => $data['type'][$key],
'tmp_name' => $data['tmp_name'][$key],
'size' => $data['size'][$key],
));
}
return $files;
}
}

View File

@ -6,7 +6,7 @@ use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;
use Symfony\Component\Validator\Exception\ConstraintDefinitionException;
use Symfony\Component\Validator\Exception\UnexpectedTypeException;
use Symfony\Component\File\File as FileObject;
use Symfony\Component\HttpFoundation\File\File as FileObject;
class FileValidator extends ConstraintValidator
{

View File

@ -11,7 +11,6 @@ use Symfony\Component\Form\HiddenField;
use Symfony\Component\Form\FieldGroup;
use Symfony\Component\Form\HtmlGenerator;
use Symfony\Component\Form\PropertyPath;
use Symfony\Component\File\UploadedFile;
use Symfony\Component\Validator\ConstraintViolation;
use Symfony\Component\Validator\ConstraintViolationList;
use Symfony\Tests\Component\Form\Fixtures\Author;
@ -220,99 +219,6 @@ class FormTest extends \PHPUnit_Framework_TestCase
$form->bind(array()); // irrelevant
}
public function testBindConvertsUploadedFiles()
{
$tmpFile = $this->createTempFile();
$file = new UploadedFile($tmpFile, basename($tmpFile), 'text/plain', 100, 0);
$field = $this->createMockField('file');
$field->expects($this->once())
->method('bind')
->with($this->equalTo($file));
$form = new Form('author', new Author(), $this->validator);
$form->add($field);
// test
$form->bind(array(), array('file' => array(
'name' => basename($tmpFile),
'type' => 'text/plain',
'tmp_name' => $tmpFile,
'error' => 0,
'size' => 100
)));
}
public function testBindConvertsUploadedFilesWithPhpBug()
{
$tmpFile = $this->createTempFile();
$file = new UploadedFile($tmpFile, basename($tmpFile), 'text/plain', 100, 0);
$field = $this->createMockField('file');
$field->expects($this->once())
->method('bind')
->with($this->equalTo($file));
$form = new Form('author', new Author(), $this->validator);
$form->add($field);
// test
$form->bind(array(), array(
'name' => array(
'file' => basename($tmpFile),
),
'type' => array(
'file' => 'text/plain',
),
'tmp_name' => array(
'file' => $tmpFile,
),
'error' => array(
'file' => 0,
),
'size' => array(
'file' => 100,
),
));
}
public function testBindConvertsNestedUploadedFilesWithPhpBug()
{
$tmpFile = $this->createTempFile();
$file = new UploadedFile($tmpFile, basename($tmpFile), 'text/plain', 100, 0);
$group = $this->getMock(
'Symfony\Component\Form\FieldGroup',
array('bind'),
array('child', array('property_path' => null))
);
$group->expects($this->once())
->method('bind')
->with($this->equalTo(array('file' => $file)));
$form = new Form('author', new Author(), $this->validator);
$form->add($group);
// test
$form->bind(array(), array(
'name' => array(
'child' => array('file' => basename($tmpFile)),
),
'type' => array(
'child' => array('file' => 'text/plain'),
),
'tmp_name' => array(
'child' => array('file' => $tmpFile),
),
'error' => array(
'child' => array('file' => 0),
),
'size' => array(
'child' => array('file' => 100),
),
));
}
public function testMultipartFormsWithoutParentsRequireFiles()
{
$form = new Form('author', new Author(), $this->validator);
@ -405,11 +311,6 @@ class FormTest extends \PHPUnit_Framework_TestCase
return $field;
}
protected function createTempFile()
{
return tempnam(sys_get_temp_dir(), 'FormTest');
}
protected function createMockValidator()
{
return $this->getMock('Symfony\Component\Validator\ValidatorInterface');

View File

@ -1,9 +1,9 @@
<?php
namespace Symfony\Tests\Component\File;
namespace Symfony\Tests\Component\HttpFoundation\File;
use Symfony\Component\File\File;
use Symfony\Component\File\MimeType\MimeTypeGuesser;
use Symfony\Component\HttpFoundation\File\File;
use Symfony\Component\HttpFoundation\File\MimeType\MimeTypeGuesser;
class FileTest extends \PHPUnit_Framework_TestCase
@ -61,7 +61,7 @@ class FileTest extends \PHPUnit_Framework_TestCase
protected function createMockGuesser($path, $mimeType)
{
$guesser = $this->getMock('Symfony\Component\File\MimeType\MimeTypeGuesserInterface');
$guesser = $this->getMock('Symfony\Component\HttpFoundation\File\MimeType\MimeTypeGuesserInterface');
$guesser->expects($this->once())
->method('guess')
->with($this->equalTo($path))

View File

Before

Width:  |  Height:  |  Size: 35 B

After

Width:  |  Height:  |  Size: 35 B

View File

Before

Width:  |  Height:  |  Size: 35 B

After

Width:  |  Height:  |  Size: 35 B

View File

@ -1,8 +1,8 @@
<?php
namespace Symfony\Tests\Component\File;
namespace Symfony\Tests\Component\HttpFoundation\File;
use Symfony\Component\File\UploadedFile;
use Symfony\Component\HttpFoundation\File\UploadedFile;
class UploadedFileTest extends \PHPUnit_Framework_TestCase
@ -11,7 +11,7 @@ class UploadedFileTest extends \PHPUnit_Framework_TestCase
{
// we can't change this setting without modifying php.ini :(
if (!ini_get('file_uploads')) {
$this->setExpectedException('Symfony\Component\File\Exception\FileException');
$this->setExpectedException('Symfony\Component\HttpFoundation\File\Exception\FileException');
new UploadedFile(
__DIR__.'/Fixtures/test.gif',

View File

@ -12,6 +12,7 @@
namespace Symfony\Tests\Component\HttpFoundation;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\File\UploadedFile;
class RequestTest extends \PHPUnit_Framework_TestCase
{
@ -107,4 +108,83 @@ class RequestTest extends \PHPUnit_Framework_TestCase
$request->server->set('QUERY_STRING', 'foo=1&foo=2');
$this->assertEquals('foo=1&foo=2', $request->getQueryString(), '->getQueryString() allows repeated parameters');
}
public function testInitializeConvertsUploadedFiles()
{
$tmpFile = $this->createTempFile();
$file = new UploadedFile($tmpFile, basename($tmpFile), 'text/plain', 100, 0);
$request = Request::create('', 'get', array(), array(), array('file' => array(
'name' => basename($tmpFile),
'type' => 'text/plain',
'tmp_name' => $tmpFile,
'error' => 0,
'size' => 100
)));
$this->assertEquals($file, $request->files->get('file'));
}
public function testInitializeConvertsUploadedFilesWithPhpBug()
{
$tmpFile = $this->createTempFile();
$file = new UploadedFile($tmpFile, basename($tmpFile), 'text/plain', 100, 0);
$request = Request::create('', 'get', array(), array(), array(
'child' => array(
'name' => array(
'file' => basename($tmpFile),
),
'type' => array(
'file' => 'text/plain',
),
'tmp_name' => array(
'file' => $tmpFile,
),
'error' => array(
'file' => 0,
),
'size' => array(
'file' => 100,
),
)
));
$files = $request->files->all();
$this->assertEquals($file, $files['child']['file']);
}
public function testInitializeConvertsNestedUploadedFilesWithPhpBug()
{
$tmpFile = $this->createTempFile();
$file = new UploadedFile($tmpFile, basename($tmpFile), 'text/plain', 100, 0);
$request = Request::create('', 'get', array(), array(), array(
'child' => array(
'name' => array(
'sub' => array('file' => basename($tmpFile))
),
'type' => array(
'sub' => array('file' => 'text/plain')
),
'tmp_name' => array(
'sub' => array('file' => $tmpFile)
),
'error' => array(
'sub' => array('file' => 0)
),
'size' => array(
'sub' => array('file' => 100)
),
)
));
$files = $request->files->all();
$this->assertEquals($file, $files['child']['sub']['file']);
}
protected function createTempFile()
{
return tempnam(sys_get_temp_dir(), 'FormTest');
}
}

View File

@ -120,7 +120,7 @@ class FileValidatorTest extends \PHPUnit_Framework_TestCase
public function testValidMimeType()
{
$file = $this->getMock('Symfony\Component\File\File', array(), array(), '', false);
$file = $this->getMock('Symfony\Component\HttpFoundation\File\File', array(), array(), '', false);
$file->expects($this->any())
->method('getPath')
->will($this->returnValue($this->path));
@ -137,7 +137,7 @@ class FileValidatorTest extends \PHPUnit_Framework_TestCase
public function testInvalidMimeType()
{
$file = $this->getMock('Symfony\Component\File\File', array(), array(), '', false);
$file = $this->getMock('Symfony\Component\HttpFoundation\File\File', array(), array(), '', false);
$file->expects($this->any())
->method('getPath')
->will($this->returnValue($this->path));