merged branch vicb/file (PR #1317)
Commits -------9d6357c
[HttpFoundation] Document the changes to the File classes136b80a
[HttFoundation] Add File::getExtension() as \SplFileInfo::getExtension() was introduced in PHP 5.3.638b3b74
[HttpKernel] Fix and test previous commitac0c00c
[HttpFoundation] Make File extends \SplFileInfo Discussion ---------- [HttpFoundation] Make File extends \SplFileInfo This is a rebased version of [PR 674](https://github.com/symfony/symfony/pull/674). * File: The API has changed (now extends \SplFileInfo), * File: move() creates the target directory when it does not exist * UploadedFile: introduction of getClientXXX() methods (for Size, OriginalName, MimeType) If this PR does not get merged UploadedFile should at least be fixed: [Client.php](https://github.com/symfony/symfony/blob/master/src/Symfony/Component/HttpKernel/Client.php#L124) relies on a last parameter which is no more defined and which is used to bypass [move_uploaded_file()](https://github.com/symfony/symfony/blob/master/src/Symfony/Component/HttpFoundation/File/UploadedFile.php#L155) in test mode. If this could be merged, I'll detail the changes in UPDATE.md --------------------------------------------------------------------------- by fabpot at 2011/06/14 08:20:59 -0700 I'll merge it. Can you update the UPDATE file? --------------------------------------------------------------------------- by vicb at 2011/06/14 09:24:01 -0700 done
This commit is contained in:
commit
c5223bbcd1
33
UPDATE.md
33
UPDATE.md
@ -14,6 +14,36 @@ beta4 to beta5
|
||||
* Exception classes have been moved to their own namespace
|
||||
* `Yaml::load()` has been renamed to `Yaml::parse()`
|
||||
|
||||
* The File classes from `HttpFoundation` have been refactored:
|
||||
|
||||
* `Symfony\Component\HttpFoundation\File\File` has a new API:
|
||||
|
||||
* It now extends `\splFileInfo`:
|
||||
|
||||
* former `getName()` equivalent is `getBasename()`,
|
||||
* former `getDirectory()` equivalent is `getPath()`,
|
||||
* former `getPath()` equivalent is `getRealPath()`.
|
||||
|
||||
* the `move()` method now creates the target directory when it does not exist,
|
||||
|
||||
* `getExtension()` and `guessExtension()` do not return the extension
|
||||
with a leading `.` anymore
|
||||
|
||||
* `Symfony\Component\HttpFoundation\File\UploadedFile` has a new API:
|
||||
|
||||
* The constructor has a new Boolean parameter that must be set to true
|
||||
in test mode only in order to be able to move the file. This parameter
|
||||
is not intended to be set to true from outside of the core files.
|
||||
|
||||
* `getMimeType()` now always returns the mime type of the underlying file.
|
||||
Use `getClientMimeType()` to get the mime type from the request.
|
||||
|
||||
* `getSize()` now always returns the size of the underlying file.
|
||||
Use `getClientSize()` to get the file size from the request.
|
||||
|
||||
* Use `getClientOriginalName()` to retrieve the original name from the
|
||||
request.
|
||||
|
||||
* The `extensions` setting for Twig has been removed. There is now only one
|
||||
way to register Twig extensions, via the `twig.extension` tag.
|
||||
|
||||
@ -33,9 +63,6 @@ beta4 to beta5
|
||||
|
||||
* The file input is now rendered as any other input field.
|
||||
|
||||
* The `Symfony\Component\HttpFoundation\File\File::getExtension()` and
|
||||
`guessExtension()` methods do not return the extension with a `.` anymore.
|
||||
|
||||
* The `em` option of the Doctrine `EntityType` class now takes the entity
|
||||
manager name instead of the EntityManager instance. If you don't pass this
|
||||
option, the default Entity Manager will be used as before.
|
||||
|
@ -20,7 +20,7 @@ use Symfony\Component\HttpFoundation\File\MimeType\MimeTypeGuesser;
|
||||
*
|
||||
* @author Bernhard Schussek <bernhard.schussek@symfony.com>
|
||||
*/
|
||||
class File
|
||||
class File extends \SplFileInfo
|
||||
{
|
||||
/**
|
||||
* A map of mime types and their default extensions.
|
||||
@ -440,13 +440,6 @@ class File
|
||||
'x-world/x-vrml' => 'wrl',
|
||||
);
|
||||
|
||||
/**
|
||||
* The absolute path to the file without dots.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $path;
|
||||
|
||||
/**
|
||||
* Constructs a new file from the given path.
|
||||
*
|
||||
@ -460,41 +453,7 @@ class File
|
||||
throw new FileNotFoundException($path);
|
||||
}
|
||||
|
||||
$this->path = realpath($path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Alias for getPath().
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
return (string) $this->path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the file name.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return basename($this->path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the file extension.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getExtension()
|
||||
{
|
||||
if ($ext = pathinfo($this->getName(), PATHINFO_EXTENSION)) {
|
||||
return $ext;
|
||||
}
|
||||
|
||||
return '';
|
||||
parent::__construct($path);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -508,31 +467,7 @@ class File
|
||||
{
|
||||
$type = $this->getMimeType();
|
||||
|
||||
if (isset(self::$defaultExtensions[$type])) {
|
||||
return self::$defaultExtensions[$type];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the directory of the file.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getDirectory()
|
||||
{
|
||||
return dirname($this->path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the absolute file path, without dots.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getPath()
|
||||
{
|
||||
return $this->path;
|
||||
return isset(static::$defaultExtensions[$type]) ? static::$defaultExtensions[$type] : null;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -542,28 +477,25 @@ class File
|
||||
* and the system binary "file" (in this order), depending on which of those
|
||||
* is available on the current operating system.
|
||||
*
|
||||
* @return string The guessed mime type (i.e. "application/pdf")
|
||||
* @return string|null The guessed mime type (i.e. "application/pdf")
|
||||
*/
|
||||
public function getMimeType()
|
||||
{
|
||||
$guesser = MimeTypeGuesser::getInstance();
|
||||
|
||||
return $guesser->guess($this->getPath());
|
||||
return $guesser->guess($this->getPathname());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the size of this file.
|
||||
* Returns the extension of the file.
|
||||
*
|
||||
* @return integer The file size in bytes
|
||||
* \SplFileInfo::getExtension() is not available before PHP 5.3.6
|
||||
*
|
||||
* @return string The extension
|
||||
*/
|
||||
public function getSize()
|
||||
public function getExtension()
|
||||
{
|
||||
if (false === $size = @filesize($this->getPath())) {
|
||||
$error = error_get_last();
|
||||
throw new FileException(sprintf('Could not read file size of %s (%s)', $this->getPath(), strip_tags($error['message'])));
|
||||
}
|
||||
|
||||
return $size;
|
||||
return pathinfo($this->getBasename(), PATHINFO_EXTENSION);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -571,16 +503,30 @@ class File
|
||||
*
|
||||
* @param string $directory The destination folder
|
||||
* @param string $name The new file name
|
||||
*
|
||||
* @return File A File object representing the new file
|
||||
*
|
||||
* @throws FileException if the target file could not be created
|
||||
*/
|
||||
public function move($directory, $name = null)
|
||||
{
|
||||
$newPath = $directory.DIRECTORY_SEPARATOR.(null === $name ? $this->getName() : $name);
|
||||
|
||||
if (!@rename($this->getPath(), $newPath)) {
|
||||
$error = error_get_last();
|
||||
throw new FileException(sprintf('Could not move file %s to %s (%s)', $this->getPath(), $newPath, strip_tags($error['message'])));
|
||||
if (!is_dir($directory)) {
|
||||
if (false === @mkdir($directory, 0777, true)) {
|
||||
throw new FileException(sprintf('Unable to create the "%s" directory', $directory));
|
||||
}
|
||||
} elseif (!is_writable($directory)) {
|
||||
throw new FileException(sprintf('Unable to write in the "%s" directory', $directory));
|
||||
}
|
||||
|
||||
$this->path = realpath($newPath);
|
||||
$target = $directory.DIRECTORY_SEPARATOR.(null === $name ? $this->getBasename() : basename($name));
|
||||
|
||||
if (!@rename($this->getPathname(), $target)) {
|
||||
$error = error_get_last();
|
||||
throw new FileException(sprintf('Could not move the file "%s" to "%s" (%s)', $this->getPathname(), $target, strip_tags($error['message'])));
|
||||
}
|
||||
|
||||
chmod($target, 0666);
|
||||
|
||||
return new File($target);
|
||||
}
|
||||
}
|
||||
}
|
@ -23,33 +23,42 @@ use Symfony\Component\HttpFoundation\File\Exception\FileNotFoundException;
|
||||
*/
|
||||
class UploadedFile extends File
|
||||
{
|
||||
/**
|
||||
* Whether the test mode is activated.
|
||||
*
|
||||
* Local files are used in test mode hence the code should not enforce HTTP uploads.
|
||||
*
|
||||
* @var Boolean
|
||||
*/
|
||||
private $test = false;
|
||||
|
||||
/**
|
||||
* The original name of the uploaded file.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $originalName;
|
||||
private $originalName;
|
||||
|
||||
/**
|
||||
* The mime type provided by the uploader.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $mimeType;
|
||||
private $mimeType;
|
||||
|
||||
/**
|
||||
* The file size provided by the uploader.
|
||||
*
|
||||
* @var integer
|
||||
* @var string
|
||||
*/
|
||||
protected $size;
|
||||
private $size;
|
||||
|
||||
/**
|
||||
* The UPLOAD_ERR_XXX constant provided by the uploader.
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
protected $error;
|
||||
private $error;
|
||||
|
||||
/**
|
||||
* Accepts the information of the uploaded file as provided by the PHP global $_FILES.
|
||||
@ -59,69 +68,65 @@ class UploadedFile extends File
|
||||
* @param string $mimeType The type of the file as provided by PHP
|
||||
* @param integer $size The file size
|
||||
* @param integer $error The error constant of the upload (one of PHP's UPLOAD_ERR_XXX constants)
|
||||
* @param Boolean $test Whether the test mode is active
|
||||
*
|
||||
* @throws FileException If file_uploads is disabled
|
||||
* @throws FileNotFoundException If the file does not exist
|
||||
*/
|
||||
public function __construct($path, $originalName, $mimeType = null, $size = null, $error = null)
|
||||
public function __construct($path, $originalName, $mimeType = null, $size = null, $error = null, $test = false)
|
||||
{
|
||||
if (!ini_get('file_uploads')) {
|
||||
throw new FileException(sprintf('Unable to create UploadedFile because "file_uploads" is disabled in your php.ini file (%s)', get_cfg_var('cfg_file_path')));
|
||||
}
|
||||
|
||||
if (!is_file($path)) {
|
||||
throw new FileNotFoundException($path);
|
||||
}
|
||||
|
||||
$this->path = realpath($path);
|
||||
$this->originalName = basename($originalName);
|
||||
$this->mimeType = $mimeType ?: 'application/octet-stream';
|
||||
$this->size = $size;
|
||||
$this->error = $error ?: UPLOAD_ERR_OK;
|
||||
$this->test = (Boolean) $test;
|
||||
|
||||
parent::__construct($path);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getMimeType()
|
||||
{
|
||||
return parent::getMimeType() ?: $this->mimeType;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getSize()
|
||||
{
|
||||
return null === $this->size ? parent::getSize() : $this->size;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getExtension()
|
||||
{
|
||||
if ($ext = pathinfo($this->getOriginalName(), PATHINFO_EXTENSION)) {
|
||||
return $ext;
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the original uploaded name.
|
||||
* Returns the original file name.
|
||||
*
|
||||
* Warning: This name is not safe as it can have been manipulated by the end-user.
|
||||
* Moreover, it can contain characters that are not allowed in file names.
|
||||
* Never use it in a path.
|
||||
* It is extracted from the request from which the file has been uploaded.
|
||||
* Then is should not be considered as a safe value.
|
||||
*
|
||||
* @return string
|
||||
* @return string|null The original name
|
||||
*/
|
||||
public function getOriginalName()
|
||||
public function getClientOriginalName()
|
||||
{
|
||||
return $this->originalName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the file mime type.
|
||||
*
|
||||
* It is extracted from the request from which the file has been uploaded.
|
||||
* Then is should not be considered as a safe value.
|
||||
*
|
||||
* @return string|null The mime type
|
||||
*/
|
||||
public function getClientMimeType()
|
||||
{
|
||||
return $this->mimeType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the file size.
|
||||
*
|
||||
* It is extracted from the request from which the file has been uploaded.
|
||||
* Then is should not be considered as a safe value.
|
||||
*
|
||||
* @return integer|null The file size
|
||||
*/
|
||||
public function getClientSize()
|
||||
{
|
||||
return $this->size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the upload error.
|
||||
*
|
||||
@ -146,17 +151,21 @@ class UploadedFile extends File
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* Moves the file to a new location.
|
||||
*
|
||||
* @param string $directory The destination folder
|
||||
* @param string $name The new file name
|
||||
*
|
||||
* @return File A File object representing the new file
|
||||
*
|
||||
* @throws FileException if the file has not been uploaded via Http
|
||||
*/
|
||||
public function move($directory, $name = null)
|
||||
{
|
||||
$newPath = $directory.DIRECTORY_SEPARATOR.(null === $name ? $this->getName() : $name);
|
||||
|
||||
if (!@move_uploaded_file($this->getPath(), $newPath)) {
|
||||
$error = error_get_last();
|
||||
throw new FileException(sprintf('Could not move file %s to %s (%s)', $this->getPath(), $newPath, strip_tags($error['message'])));
|
||||
if (!$this->test && !is_uploaded_file($this->getPathname())) {
|
||||
throw new FileException(sprintf('The file "%s" has not been uploaded via Http', $this->getPathname()));
|
||||
}
|
||||
|
||||
$this->path = realpath($newPath);
|
||||
return parent::move($directory, $name);
|
||||
}
|
||||
}
|
||||
}
|
@ -120,8 +120,15 @@ EOF;
|
||||
if (is_array($value)) {
|
||||
$filtered[$key] = $this->filterFiles($value);
|
||||
} elseif ($value instanceof UploadedFile) {
|
||||
// create an already-moved uploaded file
|
||||
$filtered[$key] = new UploadedFile($value->getPath(), $value->getName(), $value->getMimeType(), $value->getSize(), $value->getError(), true);
|
||||
// Create a test mode UploadedFile
|
||||
$filtered[$key] = new UploadedFile(
|
||||
$value->getPathname(),
|
||||
$value->getClientOriginalName(),
|
||||
$value->getClientMimeType(),
|
||||
$value->getClientSize(),
|
||||
$value->getError(),
|
||||
true
|
||||
);
|
||||
} else {
|
||||
$filtered[$key] = $value;
|
||||
}
|
||||
|
@ -29,11 +29,7 @@ class FileValidator extends ConstraintValidator
|
||||
throw new UnexpectedTypeException($value, 'string');
|
||||
}
|
||||
|
||||
if ($value instanceof FileObject && null === $value->getPath()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$path = $value instanceof FileObject ? $value->getPath() : (string) $value;
|
||||
$path = $value instanceof FileObject ? $value->getPathname() : (string) $value;
|
||||
|
||||
if (!file_exists($path)) {
|
||||
$this->setMessage($constraint->notFoundMessage, array('{{ file }}' => $path));
|
||||
@ -66,9 +62,9 @@ class FileValidator extends ConstraintValidator
|
||||
|
||||
if ($size > $limit) {
|
||||
$this->setMessage($constraint->maxSizeMessage, array(
|
||||
'{{ size }}' => $size . $suffix,
|
||||
'{{ limit }}' => $limit . $suffix,
|
||||
'{{ file }}' => $path,
|
||||
'{{ size }}' => $size . $suffix,
|
||||
'{{ limit }}' => $limit . $suffix,
|
||||
'{{ file }}' => $path,
|
||||
));
|
||||
|
||||
return false;
|
||||
@ -82,9 +78,9 @@ class FileValidator extends ConstraintValidator
|
||||
|
||||
if (!in_array($value->getMimeType(), (array) $constraint->mimeTypes)) {
|
||||
$this->setMessage($constraint->mimeTypesMessage, array(
|
||||
'{{ type }}' => '"'.$value->getMimeType().'"',
|
||||
'{{ types }}' => '"'.implode('", "', (array) $constraint->mimeTypes).'"',
|
||||
'{{ file }}' => $path,
|
||||
'{{ type }}' => '"'.$value->getMimeType().'"',
|
||||
'{{ types }}' => '"'.implode('", "', (array) $constraint->mimeTypes).'"',
|
||||
'{{ file }}' => $path,
|
||||
));
|
||||
|
||||
return false;
|
||||
|
@ -30,18 +30,26 @@ class FileTypeTest extends TypeTestCase
|
||||
|
||||
private function createUploadedFileMock($name, $originalName, $valid)
|
||||
{
|
||||
$file = $this->getMockBuilder('Symfony\Component\HttpFoundation\File\UploadedFile')
|
||||
$file = $this
|
||||
->getMockBuilder('Symfony\Component\HttpFoundation\File\UploadedFile')
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
$file->expects($this->any())
|
||||
->method('getName')
|
||||
->will($this->returnValue($name));
|
||||
$file->expects($this->any())
|
||||
->method('getOriginalName')
|
||||
->will($this->returnValue($originalName));
|
||||
$file->expects($this->any())
|
||||
->getMock()
|
||||
;
|
||||
$file
|
||||
->expects($this->any())
|
||||
->method('getBasename')
|
||||
->will($this->returnValue($name))
|
||||
;
|
||||
$file
|
||||
->expects($this->any())
|
||||
->method('getClientOriginalName')
|
||||
->will($this->returnValue($originalName))
|
||||
;
|
||||
$file
|
||||
->expects($this->any())
|
||||
->method('isValid')
|
||||
->will($this->returnValue($valid));
|
||||
->will($this->returnValue($valid))
|
||||
;
|
||||
|
||||
return $file;
|
||||
}
|
||||
|
@ -19,49 +19,15 @@ class FileTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
protected $file;
|
||||
|
||||
protected function setUp()
|
||||
{
|
||||
$this->file = new File(__DIR__.'/Fixtures/test.gif');
|
||||
}
|
||||
|
||||
public function testGetPathReturnsAbsolutePath()
|
||||
{
|
||||
$this->assertEquals(__DIR__.DIRECTORY_SEPARATOR.'Fixtures'.DIRECTORY_SEPARATOR.'test.gif', $this->file->getPath());
|
||||
}
|
||||
|
||||
public function test__toString()
|
||||
{
|
||||
$this->assertEquals(__DIR__.DIRECTORY_SEPARATOR.'Fixtures'.DIRECTORY_SEPARATOR.'test.gif', (string) $this->file);
|
||||
}
|
||||
|
||||
public function testGetNameReturnsNameWithExtension()
|
||||
{
|
||||
$this->assertEquals('test.gif', $this->file->getName());
|
||||
}
|
||||
|
||||
public function testGetExtensionReturnsEmptyString()
|
||||
{
|
||||
$file = new File(__DIR__.'/Fixtures/test');
|
||||
$this->assertEquals('', $file->getExtension());
|
||||
}
|
||||
|
||||
public function testGetExtensionReturnsExtensionWithDot()
|
||||
{
|
||||
$this->assertEquals('gif', $this->file->getExtension());
|
||||
}
|
||||
|
||||
public function testGetDirectoryReturnsDirectoryName()
|
||||
{
|
||||
$this->assertEquals(__DIR__.DIRECTORY_SEPARATOR.'Fixtures', $this->file->getDirectory());
|
||||
}
|
||||
|
||||
public function testGetMimeTypeUsesMimeTypeGuessers()
|
||||
{
|
||||
$guesser = $this->createMockGuesser($this->file->getPath(), 'image/gif');
|
||||
$file = new File(__DIR__.'/Fixtures/test.gif');
|
||||
$guesser = $this->createMockGuesser($file->getPathname(), 'image/gif');
|
||||
|
||||
MimeTypeGuesser::getInstance()->register($guesser);
|
||||
|
||||
$this->assertEquals('image/gif', $this->file->getMimeType());
|
||||
$this->assertEquals('image/gif', $file->getMimeType());
|
||||
}
|
||||
|
||||
public function testGuessExtensionWithoutGuesser()
|
||||
@ -74,7 +40,7 @@ class FileTest extends \PHPUnit_Framework_TestCase
|
||||
public function testGuessExtensionIsBasedOnMimeType()
|
||||
{
|
||||
$file = new File(__DIR__.'/Fixtures/test');
|
||||
$guesser = $this->createMockGuesser($file->getPath(), 'image/gif');
|
||||
$guesser = $this->createMockGuesser($file->getPathname(), 'image/gif');
|
||||
|
||||
MimeTypeGuesser::getInstance()->register($guesser);
|
||||
|
||||
@ -88,100 +54,83 @@ class FileTest extends \PHPUnit_Framework_TestCase
|
||||
new File(__DIR__.'/Fixtures/not_here');
|
||||
}
|
||||
|
||||
public function testSizeReturnsFileSize()
|
||||
{
|
||||
$this->assertEquals(filesize($this->file->getPath()), $this->file->getSize());
|
||||
}
|
||||
|
||||
public function testSizeFailing()
|
||||
{
|
||||
$dir = __DIR__.DIRECTORY_SEPARATOR.'Fixtures'.DIRECTORY_SEPARATOR.'directory';
|
||||
$path = $dir.DIRECTORY_SEPARATOR.'test.copy.gif';
|
||||
@unlink($path);
|
||||
copy(__DIR__.'/Fixtures/test.gif', $path);
|
||||
|
||||
$file = new File($path);
|
||||
@unlink($path);
|
||||
|
||||
try {
|
||||
$file->getSize();
|
||||
$this->fail('File::getSize should throw an exception.');
|
||||
} catch (FileException $e) {
|
||||
}
|
||||
}
|
||||
|
||||
public function testMove()
|
||||
{
|
||||
$path = __DIR__.'/Fixtures/test.copy.gif';
|
||||
$targetDir = __DIR__.DIRECTORY_SEPARATOR.'Fixtures'.DIRECTORY_SEPARATOR.'directory';
|
||||
$targetPath = $targetDir.DIRECTORY_SEPARATOR.'test.copy.gif';
|
||||
$targetDir = __DIR__.'/Fixtures/directory';
|
||||
$targetPath = $targetDir.'/test.copy.gif';
|
||||
@unlink($path);
|
||||
@unlink($targetPath);
|
||||
copy(__DIR__.'/Fixtures/test.gif', $path);
|
||||
|
||||
$file = new File($path);
|
||||
$file->move($targetDir);
|
||||
$movedFile = $file->move($targetDir);
|
||||
$this->assertInstanceOf('Symfony\Component\HttpFoundation\File\File', $movedFile);
|
||||
|
||||
$this->assertTrue(file_exists($targetPath));
|
||||
$this->assertFalse(file_exists($path));
|
||||
$this->assertEquals($targetPath, $file->getPath());
|
||||
$this->assertEquals(realpath($targetPath), $movedFile->getRealPath());
|
||||
|
||||
@unlink($path);
|
||||
@unlink($targetPath);
|
||||
}
|
||||
|
||||
public function testMoveWithNewName()
|
||||
{
|
||||
$path = __DIR__.'/Fixtures/test.copy.gif';
|
||||
$targetDir = __DIR__.DIRECTORY_SEPARATOR.'Fixtures'.DIRECTORY_SEPARATOR.'directory';
|
||||
$targetPath = $targetDir.DIRECTORY_SEPARATOR.'test.newname.gif';
|
||||
$targetDir = __DIR__.'/Fixtures/directory';
|
||||
$targetPath = $targetDir.'/test.newname.gif';
|
||||
@unlink($path);
|
||||
@unlink($targetPath);
|
||||
copy(__DIR__.'/Fixtures/test.gif', $path);
|
||||
|
||||
$file = new File($path);
|
||||
$file->move($targetDir, 'test.newname.gif');
|
||||
$movedFile = $file->move($targetDir, 'test.newname.gif');
|
||||
|
||||
$this->assertTrue(file_exists($targetPath));
|
||||
$this->assertFalse(file_exists($path));
|
||||
$this->assertEquals($targetPath, $file->getPath());
|
||||
$this->assertEquals(realpath($targetPath), $movedFile->getRealPath());
|
||||
|
||||
@unlink($path);
|
||||
@unlink($targetPath);
|
||||
}
|
||||
|
||||
public function testMoveFailing()
|
||||
public function testMoveToAnUnexistentDirectory()
|
||||
{
|
||||
$path = __DIR__.DIRECTORY_SEPARATOR.'Fixtures'.DIRECTORY_SEPARATOR.'test.copy.gif';
|
||||
$targetPath = '/thisfolderwontexist';
|
||||
@unlink($path);
|
||||
$sourcePath = __DIR__.'/Fixtures/test.copy.gif';
|
||||
$targetDir = __DIR__.'/Fixtures/directory/sub';
|
||||
$targetPath = $targetDir.'/test.copy.gif';
|
||||
@unlink($sourcePath);
|
||||
@unlink($targetPath);
|
||||
copy(__DIR__.'/Fixtures/test.gif', $path);
|
||||
@rmdir($targetDir);
|
||||
copy(__DIR__.'/Fixtures/test.gif', $sourcePath);
|
||||
|
||||
$file = new File($path);
|
||||
$file = new File($sourcePath);
|
||||
$movedFile = $file->move($targetDir);
|
||||
|
||||
try {
|
||||
$file->move($targetPath);
|
||||
$this->fail('File::move should throw an exception.');
|
||||
} catch (FileException $e) {
|
||||
}
|
||||
$this->assertFileExists($targetPath);
|
||||
$this->assertFileNotExists($sourcePath);
|
||||
$this->assertEquals(realpath($targetPath), $movedFile->getRealPath());
|
||||
|
||||
$this->assertFileExists($path);
|
||||
$this->assertFileNotExists($path.$targetPath.'test.gif');
|
||||
$this->assertEquals($path, $file->getPath());
|
||||
|
||||
@unlink($path);
|
||||
@unlink($sourcePath);
|
||||
@unlink($targetPath);
|
||||
@rmdir($targetDir);
|
||||
}
|
||||
|
||||
public function testGetExtension()
|
||||
{
|
||||
$file = new File(__DIR__.'/Fixtures/test.gif');
|
||||
$this->assertEquals('gif', $file->getExtension());
|
||||
}
|
||||
|
||||
protected function createMockGuesser($path, $mimeType)
|
||||
{
|
||||
$guesser = $this->getMock('Symfony\Component\HttpFoundation\File\MimeType\MimeTypeGuesserInterface');
|
||||
$guesser->expects($this->once())
|
||||
->method('guess')
|
||||
->with($this->equalTo($path))
|
||||
->will($this->returnValue($mimeType));
|
||||
$guesser
|
||||
->expects($this->once())
|
||||
->method('guess')
|
||||
->with($this->equalTo($path))
|
||||
->will($this->returnValue($mimeType))
|
||||
;
|
||||
|
||||
return $guesser;
|
||||
}
|
||||
}
|
||||
}
|
@ -32,11 +32,10 @@ class UploadedFileTest extends \PHPUnit_Framework_TestCase
|
||||
UPLOAD_ERR_OK
|
||||
);
|
||||
|
||||
$this->assertAttributeEquals('application/octet-stream', 'mimeType', $file);
|
||||
$this->assertEquals('application/octet-stream', $file->getClientMimeType());
|
||||
|
||||
if (extension_loaded('fileinfo')) {
|
||||
$this->assertEquals('image/gif', $file->getMimeType());
|
||||
} else {
|
||||
$this->assertEquals('application/octet-stream', $file->getMimeType());
|
||||
}
|
||||
}
|
||||
|
||||
@ -50,8 +49,7 @@ class UploadedFileTest extends \PHPUnit_Framework_TestCase
|
||||
UPLOAD_ERR_OK
|
||||
);
|
||||
|
||||
$this->assertAttributeEquals('application/octet-stream', 'mimeType', $file);
|
||||
$this->assertEquals('application/octet-stream', $file->getMimeType());
|
||||
$this->assertEquals('application/octet-stream', $file->getClientMimeType());
|
||||
}
|
||||
|
||||
public function testErrorIsOkByDefault()
|
||||
@ -67,7 +65,7 @@ class UploadedFileTest extends \PHPUnit_Framework_TestCase
|
||||
$this->assertEquals(UPLOAD_ERR_OK, $file->getError());
|
||||
}
|
||||
|
||||
public function testGetOriginalName()
|
||||
public function testGetClientOriginalName()
|
||||
{
|
||||
$file = new UploadedFile(
|
||||
__DIR__.'/Fixtures/test.gif',
|
||||
@ -77,10 +75,54 @@ class UploadedFileTest extends \PHPUnit_Framework_TestCase
|
||||
null
|
||||
);
|
||||
|
||||
$this->assertEquals('original.gif', $file->getOriginalName());
|
||||
$this->assertEquals('original.gif', $file->getClientOriginalName());
|
||||
}
|
||||
|
||||
public function testGetOriginalNameSanitizeFilename()
|
||||
/**
|
||||
* @expectedException Symfony\Component\HttpFoundation\File\Exception\FileException
|
||||
*/
|
||||
public function testMoveLocalFileIsNotAllowed()
|
||||
{
|
||||
$file = new UploadedFile(
|
||||
__DIR__.'/Fixtures/test.gif',
|
||||
'original.gif',
|
||||
'image/gif',
|
||||
filesize(__DIR__.'/Fixtures/test.gif'),
|
||||
UPLOAD_ERR_OK
|
||||
);
|
||||
|
||||
$movedFile = $file->move(__DIR__.'/Fixtures/directory');
|
||||
}
|
||||
|
||||
public function testMoveLocalFileIsAllowedInTestMode()
|
||||
{
|
||||
$path = __DIR__.'/Fixtures/test.copy.gif';
|
||||
$targetDir = __DIR__.'/Fixtures/directory';
|
||||
$targetPath = $targetDir.'/test.copy.gif';
|
||||
@unlink($path);
|
||||
@unlink($targetPath);
|
||||
copy(__DIR__.'/Fixtures/test.gif', $path);
|
||||
|
||||
$file = new UploadedFile(
|
||||
$path,
|
||||
'original.gif',
|
||||
'image/gif',
|
||||
filesize($path),
|
||||
UPLOAD_ERR_OK,
|
||||
true
|
||||
);
|
||||
|
||||
$movedFile = $file->move(__DIR__.'/Fixtures/directory');
|
||||
|
||||
$this->assertTrue(file_exists($targetPath));
|
||||
$this->assertFalse(file_exists($path));
|
||||
$this->assertEquals(realpath($targetPath), $movedFile->getRealPath());
|
||||
|
||||
@unlink($targetPath);
|
||||
}
|
||||
|
||||
|
||||
public function testGetClientOriginalNameSanitizeFilename()
|
||||
{
|
||||
$file = new UploadedFile(
|
||||
__DIR__.'/Fixtures/test.gif',
|
||||
@ -90,6 +132,6 @@ class UploadedFileTest extends \PHPUnit_Framework_TestCase
|
||||
null
|
||||
);
|
||||
|
||||
$this->assertEquals('original.gif', $file->getOriginalName());
|
||||
$this->assertEquals('original.gif', $file->getClientOriginalName());
|
||||
}
|
||||
}
|
||||
}
|
@ -16,6 +16,7 @@ use Symfony\Component\HttpKernel\HttpKernel;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\HttpFoundation\Cookie;
|
||||
use Symfony\Component\HttpFoundation\File\UploadedFile;
|
||||
|
||||
require_once __DIR__.'/TestHttpKernel.php';
|
||||
|
||||
@ -76,4 +77,32 @@ class ClientTest extends \PHPUnit_Framework_TestCase
|
||||
$domResponse = $m->invoke($client, $response);
|
||||
$this->assertEquals('foo=bar; expires=Sun, 15-Feb-2009 20:00:00 GMT; domain=http://example.com; path=/foo; secure; httponly, foo1=bar1; expires=Sun, 15-Feb-2009 20:00:00 GMT; domain=http://example.com; path=/foo; secure; httponly', $domResponse->getHeader('Set-Cookie'));
|
||||
}
|
||||
|
||||
public function testUploadedFile()
|
||||
{
|
||||
$source = tempnam(sys_get_temp_dir(), 'source');
|
||||
$target = sys_get_temp_dir().'/sf.moved.file';
|
||||
@unlink($target);
|
||||
|
||||
$kernel = new TestHttpKernel();
|
||||
$client = new Client($kernel);
|
||||
|
||||
$client->request('POST', '/', array(), array(new UploadedFile($source, 'original', 'mime/original', 123, UPLOAD_ERR_OK)));
|
||||
|
||||
$files = $kernel->request->files->all();
|
||||
|
||||
$this->assertEquals(1, count($files));
|
||||
|
||||
$file = $files[0];
|
||||
|
||||
$this->assertEquals('original', $file->getClientOriginalName());
|
||||
$this->assertEquals('mime/original', $file->getClientMimeType());
|
||||
$this->assertEquals('123', $file->getClientSize());
|
||||
$this->assertTrue($file->isValid());
|
||||
|
||||
$file->move(dirname($target), basename($target));
|
||||
|
||||
$this->assertFileExists($target);
|
||||
unlink($target);
|
||||
}
|
||||
}
|
||||
|
@ -19,6 +19,8 @@ use Symfony\Component\EventDispatcher\EventDispatcher;
|
||||
|
||||
class TestHttpKernel extends HttpKernel implements ControllerResolverInterface
|
||||
{
|
||||
public $request;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct(new EventDispatcher(), $this);
|
||||
@ -36,6 +38,7 @@ class TestHttpKernel extends HttpKernel implements ControllerResolverInterface
|
||||
|
||||
public function callController(Request $request)
|
||||
{
|
||||
$this->request = $request;
|
||||
return new Response('Request: '.$request->getRequestUri());
|
||||
}
|
||||
}
|
||||
|
@ -13,6 +13,7 @@ namespace Symfony\Tests\Component\Validator\Constraints;
|
||||
|
||||
use Symfony\Component\Validator\Constraints\File;
|
||||
use Symfony\Component\Validator\Constraints\FileValidator;
|
||||
use Symfony\Component\HttpFoundation\File\File as FileObject;
|
||||
|
||||
class FileValidatorTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
@ -42,10 +43,11 @@ class FileValidatorTest extends \PHPUnit_Framework_TestCase
|
||||
$this->assertTrue($this->validator->isValid('', new File()));
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException Symfony\Component\Validator\Exception\UnexpectedTypeException
|
||||
*/
|
||||
public function testExpectsStringCompatibleTypeOrFile()
|
||||
{
|
||||
$this->setExpectedException('Symfony\Component\Validator\Exception\UnexpectedTypeException');
|
||||
|
||||
$this->validator->isValid(new \stdClass(), new File());
|
||||
}
|
||||
|
||||
@ -59,16 +61,16 @@ class FileValidatorTest extends \PHPUnit_Framework_TestCase
|
||||
fwrite($this->file, str_repeat('0', 11));
|
||||
|
||||
$constraint = new File(array(
|
||||
'maxSize' => 10,
|
||||
'maxSizeMessage' => 'myMessage',
|
||||
'maxSize' => 10,
|
||||
'maxSizeMessage' => 'myMessage',
|
||||
));
|
||||
|
||||
$this->assertFalse($this->validator->isValid($this->path, $constraint));
|
||||
$this->assertFileValid($this->path, $constraint, false);
|
||||
$this->assertEquals($this->validator->getMessageTemplate(), 'myMessage');
|
||||
$this->assertEquals($this->validator->getMessageParameters(), array(
|
||||
'{{ limit }}' => '10 bytes',
|
||||
'{{ size }}' => '11 bytes',
|
||||
'{{ file }}' => $this->path,
|
||||
'{{ limit }}' => '10 bytes',
|
||||
'{{ size }}' => '11 bytes',
|
||||
'{{ file }}' => $this->path,
|
||||
));
|
||||
}
|
||||
|
||||
@ -77,16 +79,16 @@ class FileValidatorTest extends \PHPUnit_Framework_TestCase
|
||||
fwrite($this->file, str_repeat('0', 1400));
|
||||
|
||||
$constraint = new File(array(
|
||||
'maxSize' => '1k',
|
||||
'maxSizeMessage' => 'myMessage',
|
||||
'maxSize' => '1k',
|
||||
'maxSizeMessage' => 'myMessage',
|
||||
));
|
||||
|
||||
$this->assertFalse($this->validator->isValid($this->path, $constraint));
|
||||
$this->assertFileValid($this->path, $constraint, false);
|
||||
$this->assertEquals($this->validator->getMessageTemplate(), 'myMessage');
|
||||
$this->assertEquals($this->validator->getMessageParameters(), array(
|
||||
'{{ limit }}' => '1 kB',
|
||||
'{{ size }}' => '1.4 kB',
|
||||
'{{ file }}' => $this->path,
|
||||
'{{ limit }}' => '1 kB',
|
||||
'{{ size }}' => '1.4 kB',
|
||||
'{{ file }}' => $this->path,
|
||||
));
|
||||
}
|
||||
|
||||
@ -95,27 +97,28 @@ class FileValidatorTest extends \PHPUnit_Framework_TestCase
|
||||
fwrite($this->file, str_repeat('0', 1400000));
|
||||
|
||||
$constraint = new File(array(
|
||||
'maxSize' => '1M',
|
||||
'maxSizeMessage' => 'myMessage',
|
||||
'maxSize' => '1M',
|
||||
'maxSizeMessage' => 'myMessage',
|
||||
));
|
||||
|
||||
$this->assertFalse($this->validator->isValid($this->path, $constraint));
|
||||
$this->assertFileValid($this->path, $constraint, false);
|
||||
$this->assertEquals($this->validator->getMessageTemplate(), 'myMessage');
|
||||
$this->assertEquals($this->validator->getMessageParameters(), array(
|
||||
'{{ limit }}' => '1 MB',
|
||||
'{{ size }}' => '1.4 MB',
|
||||
'{{ file }}' => $this->path,
|
||||
'{{ limit }}' => '1 MB',
|
||||
'{{ size }}' => '1.4 MB',
|
||||
'{{ file }}' => $this->path,
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException Symfony\Component\Validator\Exception\ConstraintDefinitionException
|
||||
*/
|
||||
public function testInvalidMaxSize()
|
||||
{
|
||||
$constraint = new File(array(
|
||||
'maxSize' => '1abc',
|
||||
));
|
||||
|
||||
$this->setExpectedException('Symfony\Component\Validator\Exception\ConstraintDefinitionException');
|
||||
|
||||
$this->validator->isValid($this->path, $constraint);
|
||||
}
|
||||
|
||||
@ -125,7 +128,7 @@ class FileValidatorTest extends \PHPUnit_Framework_TestCase
|
||||
'notFoundMessage' => 'myMessage',
|
||||
));
|
||||
|
||||
$this->assertFalse($this->validator->isValid('foobar', $constraint));
|
||||
$this->assertFileValid('foobar', $constraint, false);
|
||||
$this->assertEquals($this->validator->getMessageTemplate(), 'myMessage');
|
||||
$this->assertEquals($this->validator->getMessageParameters(), array(
|
||||
'{{ file }}' => 'foobar',
|
||||
@ -134,13 +137,21 @@ class FileValidatorTest extends \PHPUnit_Framework_TestCase
|
||||
|
||||
public function testValidMimeType()
|
||||
{
|
||||
$file = $this->getMock('Symfony\Component\HttpFoundation\File\File', array(), array(), '', false);
|
||||
$file->expects($this->any())
|
||||
->method('getPath')
|
||||
->will($this->returnValue($this->path));
|
||||
$file->expects($this->any())
|
||||
->method('getMimeType')
|
||||
->will($this->returnValue('image/jpg'));
|
||||
$file = $this
|
||||
->getMockBuilder('Symfony\Component\HttpFoundation\File\File')
|
||||
->disableOriginalConstructor()
|
||||
->getMock()
|
||||
;
|
||||
$file
|
||||
->expects($this->once())
|
||||
->method('getPathname')
|
||||
->will($this->returnValue($this->path))
|
||||
;
|
||||
$file
|
||||
->expects($this->once())
|
||||
->method('getMimeType')
|
||||
->will($this->returnValue('image/jpg'))
|
||||
;
|
||||
|
||||
$constraint = new File(array(
|
||||
'mimeTypes' => array('image/png', 'image/jpg'),
|
||||
@ -151,13 +162,21 @@ class FileValidatorTest extends \PHPUnit_Framework_TestCase
|
||||
|
||||
public function testInvalidMimeType()
|
||||
{
|
||||
$file = $this->getMock('Symfony\Component\HttpFoundation\File\File', array(), array(), '', false);
|
||||
$file->expects($this->any())
|
||||
->method('getPath')
|
||||
->will($this->returnValue($this->path));
|
||||
$file->expects($this->any())
|
||||
->method('getMimeType')
|
||||
->will($this->returnValue('application/pdf'));
|
||||
$file = $this
|
||||
->getMockBuilder('Symfony\Component\HttpFoundation\File\File')
|
||||
->disableOriginalConstructor()
|
||||
->getMock()
|
||||
;
|
||||
$file
|
||||
->expects($this->once())
|
||||
->method('getPathname')
|
||||
->will($this->returnValue($this->path))
|
||||
;
|
||||
$file
|
||||
->expects($this->exactly(2))
|
||||
->method('getMimeType')
|
||||
->will($this->returnValue('application/pdf'))
|
||||
;
|
||||
|
||||
$constraint = new File(array(
|
||||
'mimeTypes' => array('image/png', 'image/jpg'),
|
||||
@ -167,9 +186,17 @@ class FileValidatorTest extends \PHPUnit_Framework_TestCase
|
||||
$this->assertFalse($this->validator->isValid($file, $constraint));
|
||||
$this->assertEquals($this->validator->getMessageTemplate(), 'myMessage');
|
||||
$this->assertEquals($this->validator->getMessageParameters(), array(
|
||||
'{{ type }}' => '"application/pdf"',
|
||||
'{{ types }}' => '"image/png", "image/jpg"',
|
||||
'{{ file }}' => $this->path,
|
||||
'{{ type }}' => '"application/pdf"',
|
||||
'{{ types }}' => '"image/png", "image/jpg"',
|
||||
'{{ file }}' => $this->path,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
protected function assertFileValid($filename, File $constraint, $valid = true)
|
||||
{
|
||||
$this->assertEquals($this->validator->isValid($filename, $constraint), $valid);
|
||||
if (file_exists($filename)) {
|
||||
$this->assertEquals($this->validator->isValid(new FileObject($filename), $constraint), $valid);
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user