Sfoglia il codice sorgente

[HttpFoundation] moved File Component into the HttpFoundation one

Fabien Potencier 15 anni fa
parent
commit
a141c98917

+ 1 - 68
src/Symfony/Component/Form/Form.php

@@ -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;
-    }
 }

+ 1 - 1
src/Symfony/Component/File/Exception/AccessDeniedException.php

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

+ 1 - 1
src/Symfony/Component/File/Exception/FileException.php

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

+ 1 - 1
src/Symfony/Component/File/Exception/FileNotFoundException.php

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

+ 4 - 4
src/Symfony/Component/File/File.php

@@ -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.

+ 3 - 3
src/Symfony/Component/File/MimeType/ContentTypeMimeTypeGuesser.php

@@ -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.

+ 3 - 3
src/Symfony/Component/File/MimeType/FileBinaryMimeTypeGuesser.php

@@ -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.

+ 3 - 3
src/Symfony/Component/File/MimeType/FileinfoMimeTypeGuesser.php

@@ -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.

+ 3 - 3
src/Symfony/Component/File/MimeType/MimeTypeGuesser.php

@@ -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.

+ 1 - 1
src/Symfony/Component/File/MimeType/MimeTypeGuesserInterface.php

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

+ 2 - 2
src/Symfony/Component/File/UploadedFile.php

@@ -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.

+ 62 - 33
src/Symfony/Component/HttpFoundation/Request.php

@@ -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,50 +847,53 @@ 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);
         }
 
-        return $files;
-    }
+        $fileKeys = array('error', 'name', 'size', 'tmp_name', 'type');
+        foreach ($fixedFiles as $key => $data) {
+            if (is_array($data)) {
+                $keys = array_keys($data);
+                sort($keys);
 
-    protected function initializeHeaders()
-    {
-        $headers = array();
-        foreach ($this->server->all() as $key => $value) {
-            if ('http_' === strtolower(substr($key, 0, 5))) {
-                $headers[substr($key, 5)] = $value;
+                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 $headers;
+        return $fixedFiles;
     }
 
-    static protected function initializeFormats()
-    {
-        static::$formats = array(
-            'txt'  => 'text/plain',
-            'js'   => array('application/javascript', 'application/x-javascript', 'text/javascript'),
-            'css'  => 'text/css',
-            'json' => array('application/json', 'application/x-json'),
-            'xml'  => array('text/xml', 'application/xml', 'application/x-xml'),
-            'rdf'  => 'application/rdf+xml',
-            'atom' => 'application/atom+xml',
-        );
-    }
-
-    static protected function fixPhpFilesArray($data)
+    /**
+     * 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);
@@ -904,7 +908,7 @@ class Request
             unset($files[$k]);
         }
         foreach (array_keys($data['name']) as $key) {
-            $files[$key] = self::fixPhpFilesArray(array(
+            $files[$key] = $this->fixPhpFilesArray(array(
                 'error'    => $data['error'][$key],
                 'name'     => $data['name'][$key],
                 'type'     => $data['type'][$key],
@@ -915,4 +919,29 @@ class Request
 
         return $files;
     }
+
+    protected function initializeHeaders()
+    {
+        $headers = array();
+        foreach ($this->server->all() as $key => $value) {
+            if ('http_' === strtolower(substr($key, 0, 5))) {
+                $headers[substr($key, 5)] = $value;
+            }
+        }
+
+        return $headers;
+    }
+
+    static protected function initializeFormats()
+    {
+        static::$formats = array(
+            'txt'  => 'text/plain',
+            'js'   => array('application/javascript', 'application/x-javascript', 'text/javascript'),
+            'css'  => 'text/css',
+            'json' => array('application/json', 'application/x-json'),
+            'xml'  => array('text/xml', 'application/xml', 'application/x-xml'),
+            'rdf'  => 'application/rdf+xml',
+            'atom' => 'application/atom+xml',
+        );
+    }
 }

+ 1 - 1
src/Symfony/Component/Validator/Constraints/FileValidator.php

@@ -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
 {

+ 0 - 99
tests/Symfony/Tests/Component/Form/FormTest.php

@@ -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');

+ 4 - 4
tests/Symfony/Tests/Component/File/FileTest.php

@@ -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))

tests/Symfony/Tests/Component/File/Fixtures/test → tests/Symfony/Tests/Component/HttpFoundation/File/Fixtures/test


tests/Symfony/Tests/Component/File/Fixtures/test.gif → tests/Symfony/Tests/Component/HttpFoundation/File/Fixtures/test.gif


+ 3 - 3
tests/Symfony/Tests/Component/File/UploadedFileTest.php

@@ -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',

+ 80 - 0
tests/Symfony/Tests/Component/HttpFoundation/RequestTest.php

@@ -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');
+    }
 }

+ 2 - 2
tests/Symfony/Tests/Component/Validator/Constraints/FileValidatorTest.php

@@ -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));