diff --git a/UPDATE.md b/UPDATE.md index 38ac238c91..c1066b0fbe 100644 --- a/UPDATE.md +++ b/UPDATE.md @@ -9,6 +9,8 @@ timeline closely anyway. beta4 to beta5 -------------- +* The temporary storage for file uploads has been removed + * The `Symfony\Component\HttpFoundation\File\File::getExtension()` and `guessExtension()` methods do not return the extension with a `.` anymore. diff --git a/src/Symfony/Bridge/Twig/Resources/views/Form/div_layout.html.twig b/src/Symfony/Bridge/Twig/Resources/views/Form/div_layout.html.twig index 544f2f13ec..c295dee585 100644 --- a/src/Symfony/Bridge/Twig/Resources/views/Form/div_layout.html.twig +++ b/src/Symfony/Bridge/Twig/Resources/views/Form/div_layout.html.twig @@ -247,9 +247,6 @@ {% spaceless %}
{{ form_widget(form.file) }} - {{ form_widget(form.token) }} - {{ form_widget(form.name) }} - {{ form_widget(form.originalName) }}
{% endspaceless %} {% endblock file_widget %} diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php index e7c87e75c7..2e631829c2 100644 --- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php @@ -156,14 +156,6 @@ class FrameworkExtension extends Extension $container->setParameter('form.type_extension.csrf.enabled', $config['csrf_protection']['enabled']); $container->setParameter('form.type_extension.csrf.field_name', $config['csrf_protection']['field_name']); } - - if ($container->hasDefinition('session')) { - $container->removeDefinition('file.temporary_storage'); - $container->setDefinition('file.temporary_storage', $container->getDefinition('file.temporary_storage.session')); - $container->removeDefinition('file.temporary_storage.session'); - } else { - $container->removeDefinition('file.temporary_storage.session'); - } } /** diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/form.xml b/src/Symfony/Bundle/FrameworkBundle/Resources/config/form.xml index 5b520a4e0f..1422e792b8 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/form.xml +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/form.xml @@ -8,8 +8,6 @@ Symfony\Component\Form\Extension\DependencyInjection\DependencyInjectionExtension Symfony\Component\Form\FormFactory Symfony\Component\Form\Extension\Validator\ValidatorTypeGuesser - Symfony\Component\HttpFoundation\File\TemporaryStorage - Symfony\Component\HttpFoundation\File\SessionBasedTemporaryStorage @@ -51,18 +49,6 @@ - - - - %kernel.secret% - %kernel.cache_dir%/upload - - - - %kernel.secret% - %kernel.cache_dir%/upload - - @@ -97,7 +83,6 @@ - diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/file_widget.html.php b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/file_widget.html.php index b08fed24a8..51b985b4f7 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/file_widget.html.php +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/file_widget.html.php @@ -5,8 +5,4 @@ get('disabled')): ?>disabled="disabled" get('required')): ?>required="required" /> - - widget($form['token']) ?> - widget($form['name']) ?> - widget($form['originalName']) ?> diff --git a/src/Symfony/Component/Form/Extension/Core/CoreExtension.php b/src/Symfony/Component/Form/Extension/Core/CoreExtension.php index e8fde072a0..d733b8c545 100644 --- a/src/Symfony/Component/Form/Extension/Core/CoreExtension.php +++ b/src/Symfony/Component/Form/Extension/Core/CoreExtension.php @@ -13,7 +13,6 @@ namespace Symfony\Component\Form\Extension\Core; use Symfony\Component\Form\Extension\Core\Type; use Symfony\Component\Form\AbstractExtension; -use Symfony\Component\HttpFoundation\File\TemporaryStorage; /** * Represents the main form extension, which loads the core functionality. @@ -22,13 +21,6 @@ use Symfony\Component\HttpFoundation\File\TemporaryStorage; */ class CoreExtension extends AbstractExtension { - private $storage; - - public function __construct(TemporaryStorage $storage) - { - $this->storage = $storage; - } - protected function loadTypes() { return array( @@ -58,7 +50,7 @@ class CoreExtension extends AbstractExtension new Type\TimeType(), new Type\TimezoneType(), new Type\UrlType(), - new Type\FileType($this->storage), + new Type\FileType(), ); } } diff --git a/src/Symfony/Component/Form/Extension/Core/EventListener/FixFileUploadListener.php b/src/Symfony/Component/Form/Extension/Core/EventListener/FixFileUploadListener.php deleted file mode 100644 index 694b17250b..0000000000 --- a/src/Symfony/Component/Form/Extension/Core/EventListener/FixFileUploadListener.php +++ /dev/null @@ -1,86 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Form\Extension\Core\EventListener; - -use Symfony\Component\Form\FormEvents; -use Symfony\Component\Form\Exception\UnexpectedTypeException; -use Symfony\Component\Form\Event\FilterDataEvent; -use Symfony\Component\EventDispatcher\EventSubscriberInterface; -use Symfony\Component\HttpFoundation\File\UploadedFile; -use Symfony\Component\HttpFoundation\File\TemporaryStorage; - -/** - * Moves uploaded files to a temporary location - * - * @author Bernhard Schussek - */ -class FixFileUploadListener implements EventSubscriberInterface -{ - private $storage; - - public function __construct(TemporaryStorage $storage) - { - $this->storage = $storage; - } - - public static function getSubscribedEvents() - { - return array(FormEvents::BIND_CLIENT_DATA => 'onBindClientData'); - } - - public function onBindClientData(FilterDataEvent $event) - { - $form = $event->getForm(); - $data = $event->getData(); - - if (null === $data) { - $data = array(); - } - - if (!is_array($data)) { - throw new UnexpectedTypeException($data, 'array'); - } - - $data = array_replace(array( - 'file' => '', - 'token' => '', - 'name' => '', - 'originalName' => '', - ), $data); - - // Newly uploaded file - if ($data['file'] instanceof UploadedFile && $data['file']->isValid()) { - $data['token'] = (string)rand(100000, 999999); - $directory = $this->storage->getTempDir($data['token']); - $data['file']->move($directory); - $data['name'] = $data['file']->getName(); - $data['originalName'] = $data['file']->getOriginalName(); - } - - // Existing uploaded file - if (!$data['file'] && $data['token'] && $data['name']) { - $path = $this->storage->getTempDir($data['token']) . DIRECTORY_SEPARATOR . $data['name']; - - if (file_exists($path)) { - $data['file'] = new UploadedFile($path, $data['originalName'], null, null, null, true); - } - } - - // Clear other fields if we still don't have a file, but keep - // possible existing files of the field - if (!$data['file']) { - $data = $form->getNormData(); - } - - $event->setData($data); - } -} diff --git a/src/Symfony/Component/Form/Extension/Core/Type/FileType.php b/src/Symfony/Component/Form/Extension/Core/Type/FileType.php index efe760767e..fa7af5fb3f 100644 --- a/src/Symfony/Component/Form/Extension/Core/Type/FileType.php +++ b/src/Symfony/Component/Form/Extension/Core/Type/FileType.php @@ -14,22 +14,13 @@ namespace Symfony\Component\Form\Extension\Core\Type; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\FormInterface; use Symfony\Component\Form\FormBuilder; -use Symfony\Component\Form\Extension\Core\EventListener\FixFileUploadListener; use Symfony\Component\Form\ReversedTransformer; use Symfony\Component\Form\Extension\Core\DataTransformer\FileToStringTransformer; use Symfony\Component\Form\Extension\Core\DataTransformer\FileToArrayTransformer; use Symfony\Component\Form\FormView; -use Symfony\Component\HttpFoundation\File\TemporaryStorage; class FileType extends AbstractType { - private $storage; - - public function __construct(TemporaryStorage $storage) - { - $this->storage = $storage; - } - public function buildForm(FormBuilder $builder, array $options) { if ($options['type'] === 'string') { @@ -40,11 +31,7 @@ class FileType extends AbstractType $builder ->appendNormTransformer(new FileToArrayTransformer()) - ->addEventSubscriber(new FixFileUploadListener($this->storage), 10) ->add('file', 'field') - ->add('token', 'hidden') - ->add('name', 'hidden') - ->add('originalName', 'hidden') ; } diff --git a/src/Symfony/Component/HttpFoundation/File/SessionBasedTemporaryStorage.php b/src/Symfony/Component/HttpFoundation/File/SessionBasedTemporaryStorage.php deleted file mode 100644 index a13b44b659..0000000000 --- a/src/Symfony/Component/HttpFoundation/File/SessionBasedTemporaryStorage.php +++ /dev/null @@ -1,36 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\HttpFoundation\File; - -use Symfony\Component\HttpFoundation\Session; - -/** - * @author Bernhard Schussek - */ -class SessionBasedTemporaryStorage extends TemporaryStorage -{ - private $session; - - public function __construct(Session $session, $secret, $directory) - { - parent::__construct($secret, $directory); - - $this->session = $session; - } - - protected function generateHashInfo($token) - { - $this->session->start(); - - return $this->session->getId().parent::generateHashInfo($token); - } -} diff --git a/src/Symfony/Component/HttpFoundation/File/TemporaryStorage.php b/src/Symfony/Component/HttpFoundation/File/TemporaryStorage.php deleted file mode 100644 index a583465022..0000000000 --- a/src/Symfony/Component/HttpFoundation/File/TemporaryStorage.php +++ /dev/null @@ -1,61 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\HttpFoundation\File; - -use Symfony\Component\HttpFoundation\File\Exception\FileException; -use Symfony\Component\HttpFoundation\File\Exception\UnexpectedTypeException; - -/** - * @author Bernhard Schussek - */ -class TemporaryStorage -{ - private $directory; - private $secret; - - public function __construct($secret, $directory) - { - if (!file_exists($directory)) { - mkdir($directory, 0777, true); - } - - $this->directory = realpath($directory); - $this->secret = $secret; - } - - protected function generateHashInfo($token) - { - return $this->secret.$token; - } - - protected function generateHash($token) - { - return md5($this->generateHashInfo($token)); - } - - public function getTempDir($token) - { - if (!is_string($token)) { - throw new UnexpectedTypeException($token, 'string'); - } - - $hash = $this->generateHash($token); - - $directory = $this->directory.DIRECTORY_SEPARATOR.substr($hash, 0, 2).DIRECTORY_SEPARATOR.substr($hash, 2); - - if (!file_exists($directory)) { - mkdir($directory, 0777, true); - } - - return $directory; - } -} diff --git a/src/Symfony/Component/HttpFoundation/File/UploadedFile.php b/src/Symfony/Component/HttpFoundation/File/UploadedFile.php index b463add604..fe9449ce74 100644 --- a/src/Symfony/Component/HttpFoundation/File/UploadedFile.php +++ b/src/Symfony/Component/HttpFoundation/File/UploadedFile.php @@ -51,13 +51,6 @@ class UploadedFile extends File */ protected $error; - /** - * Whether the uploaded file has already been moved. - * - * @var Boolean - */ - protected $moved; - /** * Accepts the information of the uploaded file as provided by the PHP global $_FILES. * @@ -66,13 +59,11 @@ 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 $moved Whether the file has been moved from its original location * * @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, $moved = false) + public function __construct($path, $originalName, $mimeType = null, $size = null, $error = null) { 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'))); @@ -87,7 +78,6 @@ class UploadedFile extends File $this->mimeType = $mimeType ?: 'application/octet-stream'; $this->size = $size; $this->error = $error ?: UPLOAD_ERR_OK; - $this->moved = (Boolean) $moved; } /** @@ -111,10 +101,6 @@ class UploadedFile extends File */ public function getExtension() { - if ($this->moved) { - return parent::getExtension(); - } - if ($ext = pathinfo($this->getOriginalName(), PATHINFO_EXTENSION)) { return $ext; } @@ -164,10 +150,6 @@ class UploadedFile extends File */ public function move($directory, $name = null) { - if ($this->moved) { - return parent::move($directory, $name); - } - $newPath = $directory.DIRECTORY_SEPARATOR.(null === $name ? $this->getName() : $name); if (!@move_uploaded_file($this->getPath(), $newPath)) { @@ -175,7 +157,6 @@ class UploadedFile extends File throw new FileException(sprintf('Could not move file %s to %s (%s)', $this->getPath(), $newPath, strip_tags($error['message']))); } - $this->moved = true; $this->path = realpath($newPath); } } diff --git a/tests/Symfony/Tests/Component/Form/AbstractLayoutTest.php b/tests/Symfony/Tests/Component/Form/AbstractLayoutTest.php index b9b2c89cee..02efbbfbc9 100644 --- a/tests/Symfony/Tests/Component/Form/AbstractLayoutTest.php +++ b/tests/Symfony/Tests/Component/Form/AbstractLayoutTest.php @@ -30,10 +30,9 @@ abstract class AbstractLayoutTest extends \PHPUnit_Framework_TestCase $dispatcher = new EventDispatcher(); $this->csrfProvider = $this->getMock('Symfony\Component\Form\Extension\Csrf\CsrfProvider\CsrfProviderInterface'); - $storage = new \Symfony\Component\HttpFoundation\File\TemporaryStorage('foo', \sys_get_temp_dir()); $this->factory = new FormFactory(array( - new CoreExtension($storage), + new CoreExtension(), new CsrfExtension($this->csrfProvider), )); } @@ -757,11 +756,8 @@ abstract class AbstractLayoutTest extends \PHPUnit_Framework_TestCase '/div [ ./input[@type="file"][@id="na&me_file"] - /following-sibling::input[@type="hidden"][@id="na&me_token"] - /following-sibling::input[@type="hidden"][@id="na&me_name"] - /following-sibling::input[@type="hidden"][@id="na&me_originalName"] ] - [count(./input)=4] + [count(./input)=1] ' ); } diff --git a/tests/Symfony/Tests/Component/Form/Extension/Core/EventListener/FixFileUploadListenerTest.php b/tests/Symfony/Tests/Component/Form/Extension/Core/EventListener/FixFileUploadListenerTest.php deleted file mode 100644 index a6a5c78d2e..0000000000 --- a/tests/Symfony/Tests/Component/Form/Extension/Core/EventListener/FixFileUploadListenerTest.php +++ /dev/null @@ -1,167 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Tests\Component\Form\Extension\Core\EventListener; - -use Symfony\Component\Form\Event\FilterDataEvent; -use Symfony\Component\Form\Extension\Core\EventListener\FixFileUploadListener; -use Symfony\Component\HttpFoundation\File\UploadedFile; - -class FixFileUploadListenerTest extends \PHPUnit_Framework_TestCase -{ - private $storage; - - private $destination; - - public function setUp() - { - $this->storage = $this->getMockBuilder('Symfony\Component\HttpFoundation\File\TemporaryStorage') - ->disableOriginalConstructor() - ->getMock(); - } - - public function testValidNewlyUploadedFile() - { - $passedToken = null; - - $this->storage->expects($this->any()) - ->method('getTempDir') - ->will($this->returnCallback(function ($token) use (&$passedToken) { - $passedToken = $token; - - return __DIR__.DIRECTORY_SEPARATOR.'tmp'; - })); - - $file = $this->createUploadedFileMock('randomhash', 'original.jpg', true); - $file->expects($this->once()) - ->method('move') - ->with(__DIR__.DIRECTORY_SEPARATOR.'tmp'); - - $data = array( - 'file' => $file, - 'token' => '', - 'name' => '', - 'originalName' => '', - ); - - $form = $this->getMock('Symfony\Tests\Component\Form\FormInterface'); - $event = new FilterDataEvent($form, $data); - - $filter = new FixFileUploadListener($this->storage); - $filter->onBindClientData($event); - - $this->assertEquals(array( - 'file' => $file, - 'name' => 'randomhash', - 'originalName' => 'original.jpg', - 'token' => $passedToken, - ), $event->getData()); - } - - public function testExistingUploadedFile() - { - $test = $this; - - $this->storage->expects($this->any()) - ->method('getTempDir') - ->will($this->returnCallback(function ($token) use ($test) { - $test->assertSame('abcdef', $token); - - return __DIR__.DIRECTORY_SEPARATOR.'Fixtures'; - })); - - $data = array( - 'file' => '', - 'token' => 'abcdef', - 'name' => 'randomhash', - 'originalName' => 'original.jpg', - ); - - $form = $this->getMock('Symfony\Tests\Component\Form\FormInterface'); - $event = new FilterDataEvent($form, $data); - - $filter = new FixFileUploadListener($this->storage); - $filter->onBindClientData($event); - - $this->assertEquals(array( - 'file' => new UploadedFile( - __DIR__.DIRECTORY_SEPARATOR.'Fixtures'.DIRECTORY_SEPARATOR.'randomhash', - 'original.jpg', - null, - null, - null, - true // already moved - ), - 'name' => 'randomhash', - 'originalName' => 'original.jpg', - 'token' => 'abcdef', - ), $event->getData()); - } - - public function testNullAndExistingFile() - { - $existingData = array( - 'file' => new UploadedFile( - __DIR__.DIRECTORY_SEPARATOR.'Fixtures'.DIRECTORY_SEPARATOR.'randomhash', - 'original.jpg', - null, - null, - null, - true // already moved - ), - 'name' => 'randomhash', - 'originalName' => 'original.jpg', - 'token' => 'abcdef', - ); - - $form = $this->getMock('Symfony\Tests\Component\Form\FormInterface'); - $form->expects($this->any()) - ->method('getNormData') - ->will($this->returnValue($existingData)); - - $event = new FilterDataEvent($form, null); - - $filter = new FixFileUploadListener($this->storage); - $filter->onBindClientData($event); - - $this->assertSame($existingData, $event->getData()); - } - - /** - * @expectedException Symfony\Component\Form\Exception\UnexpectedTypeException - */ - public function testExpectNullOrArray() - { - $form = $this->getMock('Symfony\Tests\Component\Form\FormInterface'); - $event = new FilterDataEvent($form, 'foobar'); - - $filter = new FixFileUploadListener($this->storage); - $filter->onBindClientData($event); - } - - private function createUploadedFileMock($name, $originalName, $valid) - { - $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()) - ->method('isValid') - ->will($this->returnValue($valid)); - - return $file; - } -} diff --git a/tests/Symfony/Tests/Component/Form/Extension/Core/Type/TypeTestCase.php b/tests/Symfony/Tests/Component/Form/Extension/Core/Type/TypeTestCase.php index f184abc44b..5f56c8211b 100644 --- a/tests/Symfony/Tests/Component/Form/Extension/Core/Type/TypeTestCase.php +++ b/tests/Symfony/Tests/Component/Form/Extension/Core/Type/TypeTestCase.php @@ -18,8 +18,6 @@ use Symfony\Component\EventDispatcher\EventDispatcher; abstract class TypeTestCase extends \PHPUnit_Framework_TestCase { - protected $storage; - protected $factory; protected $builder; @@ -31,9 +29,6 @@ abstract class TypeTestCase extends \PHPUnit_Framework_TestCase protected function setUp() { $this->dispatcher = $this->getMock('Symfony\Component\EventDispatcher\EventDispatcherInterface'); - $this->storage = $this->getMockBuilder('Symfony\Component\HttpFoundation\File\TemporaryStorage') - ->disableOriginalConstructor() - ->getMock(); $this->factory = new FormFactory($this->getExtensions()); $this->builder = new FormBuilder(null, $this->factory, $this->dispatcher); } @@ -41,7 +36,7 @@ abstract class TypeTestCase extends \PHPUnit_Framework_TestCase protected function getExtensions() { return array( - new CoreExtension($this->storage), + new CoreExtension(), ); }