[Form] removed the file upload temporary storage feature
The current implementation is not ready for inclusion in 2.0. It has several known problems (security, not possible to disable it, not "cloud-compatible", ...) and it's not a must have feature anyway. Some references: * Security issue in FileType: https://github.com/symfony/symfony/issues/1001 * Validation fails on file, still stored in TemporaryStorage: https://github.com/symfony/symfony/issues/908 * Add a size argument & ability to configure TemporaryStorage: https://github.com/symfony/symfony/pull/748 This feature should be reworked and discussed for inclusion in 2.1.
This commit is contained in:
parent
1e8cd6d34d
commit
852a4c9c6a
@ -9,6 +9,8 @@ timeline closely anyway.
|
|||||||
beta4 to beta5
|
beta4 to beta5
|
||||||
--------------
|
--------------
|
||||||
|
|
||||||
|
* The temporary storage for file uploads has been removed
|
||||||
|
|
||||||
* The `Symfony\Component\HttpFoundation\File\File::getExtension()` and
|
* The `Symfony\Component\HttpFoundation\File\File::getExtension()` and
|
||||||
`guessExtension()` methods do not return the extension with a `.` anymore.
|
`guessExtension()` methods do not return the extension with a `.` anymore.
|
||||||
|
|
||||||
|
@ -247,9 +247,6 @@
|
|||||||
{% spaceless %}
|
{% spaceless %}
|
||||||
<div {{ block('container_attributes') }}>
|
<div {{ block('container_attributes') }}>
|
||||||
{{ form_widget(form.file) }}
|
{{ form_widget(form.file) }}
|
||||||
{{ form_widget(form.token) }}
|
|
||||||
{{ form_widget(form.name) }}
|
|
||||||
{{ form_widget(form.originalName) }}
|
|
||||||
</div>
|
</div>
|
||||||
{% endspaceless %}
|
{% endspaceless %}
|
||||||
{% endblock file_widget %}
|
{% endblock file_widget %}
|
||||||
|
@ -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.enabled', $config['csrf_protection']['enabled']);
|
||||||
$container->setParameter('form.type_extension.csrf.field_name', $config['csrf_protection']['field_name']);
|
$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');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -8,8 +8,6 @@
|
|||||||
<parameter key="form.extension.class">Symfony\Component\Form\Extension\DependencyInjection\DependencyInjectionExtension</parameter>
|
<parameter key="form.extension.class">Symfony\Component\Form\Extension\DependencyInjection\DependencyInjectionExtension</parameter>
|
||||||
<parameter key="form.factory.class">Symfony\Component\Form\FormFactory</parameter>
|
<parameter key="form.factory.class">Symfony\Component\Form\FormFactory</parameter>
|
||||||
<parameter key="form.type_guesser.validator.class">Symfony\Component\Form\Extension\Validator\ValidatorTypeGuesser</parameter>
|
<parameter key="form.type_guesser.validator.class">Symfony\Component\Form\Extension\Validator\ValidatorTypeGuesser</parameter>
|
||||||
<parameter key="file.temporary_storage.class">Symfony\Component\HttpFoundation\File\TemporaryStorage</parameter>
|
|
||||||
<parameter key="file.temporary_storage.session.class">Symfony\Component\HttpFoundation\File\SessionBasedTemporaryStorage</parameter>
|
|
||||||
</parameters>
|
</parameters>
|
||||||
|
|
||||||
<services>
|
<services>
|
||||||
@ -51,18 +49,6 @@
|
|||||||
<argument type="service" id="validator.mapping.class_metadata_factory" />
|
<argument type="service" id="validator.mapping.class_metadata_factory" />
|
||||||
</service>
|
</service>
|
||||||
|
|
||||||
<!-- TemporaryStorage - where should we put this? -->
|
|
||||||
<service id="file.temporary_storage.session" class="%file.temporary_storage.session.class%">
|
|
||||||
<argument type="service" id="session" />
|
|
||||||
<argument>%kernel.secret%</argument>
|
|
||||||
<argument>%kernel.cache_dir%/upload</argument>
|
|
||||||
</service>
|
|
||||||
|
|
||||||
<service id="file.temporary_storage" class="%file.temporary_storage.class%">
|
|
||||||
<argument>%kernel.secret%</argument>
|
|
||||||
<argument>%kernel.cache_dir%/upload</argument>
|
|
||||||
</service>
|
|
||||||
|
|
||||||
<!-- CoreExtension -->
|
<!-- CoreExtension -->
|
||||||
<service id="form.type.field" class="Symfony\Component\Form\Extension\Core\Type\FieldType">
|
<service id="form.type.field" class="Symfony\Component\Form\Extension\Core\Type\FieldType">
|
||||||
<tag name="form.type" alias="field" />
|
<tag name="form.type" alias="field" />
|
||||||
@ -97,7 +83,6 @@
|
|||||||
</service>
|
</service>
|
||||||
<service id="form.type.file" class="Symfony\Component\Form\Extension\Core\Type\FileType">
|
<service id="form.type.file" class="Symfony\Component\Form\Extension\Core\Type\FileType">
|
||||||
<tag name="form.type" alias="file" />
|
<tag name="form.type" alias="file" />
|
||||||
<argument type="service" id="file.temporary_storage" />
|
|
||||||
</service>
|
</service>
|
||||||
<service id="form.type.hidden" class="Symfony\Component\Form\Extension\Core\Type\HiddenType">
|
<service id="form.type.hidden" class="Symfony\Component\Form\Extension\Core\Type\HiddenType">
|
||||||
<tag name="form.type" alias="hidden" />
|
<tag name="form.type" alias="hidden" />
|
||||||
|
@ -5,8 +5,4 @@
|
|||||||
<?php if ($form['file']->get('disabled')): ?>disabled="disabled"<?php endif ?>
|
<?php if ($form['file']->get('disabled')): ?>disabled="disabled"<?php endif ?>
|
||||||
<?php if ($form['file']->get('required')): ?>required="required"<?php endif ?>
|
<?php if ($form['file']->get('required')): ?>required="required"<?php endif ?>
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<?php echo $view['form']->widget($form['token']) ?>
|
|
||||||
<?php echo $view['form']->widget($form['name']) ?>
|
|
||||||
<?php echo $view['form']->widget($form['originalName']) ?>
|
|
||||||
</div>
|
</div>
|
||||||
|
@ -13,7 +13,6 @@ namespace Symfony\Component\Form\Extension\Core;
|
|||||||
|
|
||||||
use Symfony\Component\Form\Extension\Core\Type;
|
use Symfony\Component\Form\Extension\Core\Type;
|
||||||
use Symfony\Component\Form\AbstractExtension;
|
use Symfony\Component\Form\AbstractExtension;
|
||||||
use Symfony\Component\HttpFoundation\File\TemporaryStorage;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents the main form extension, which loads the core functionality.
|
* Represents the main form extension, which loads the core functionality.
|
||||||
@ -22,13 +21,6 @@ use Symfony\Component\HttpFoundation\File\TemporaryStorage;
|
|||||||
*/
|
*/
|
||||||
class CoreExtension extends AbstractExtension
|
class CoreExtension extends AbstractExtension
|
||||||
{
|
{
|
||||||
private $storage;
|
|
||||||
|
|
||||||
public function __construct(TemporaryStorage $storage)
|
|
||||||
{
|
|
||||||
$this->storage = $storage;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function loadTypes()
|
protected function loadTypes()
|
||||||
{
|
{
|
||||||
return array(
|
return array(
|
||||||
@ -58,7 +50,7 @@ class CoreExtension extends AbstractExtension
|
|||||||
new Type\TimeType(),
|
new Type\TimeType(),
|
||||||
new Type\TimezoneType(),
|
new Type\TimezoneType(),
|
||||||
new Type\UrlType(),
|
new Type\UrlType(),
|
||||||
new Type\FileType($this->storage),
|
new Type\FileType(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,86 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This file is part of the Symfony package.
|
|
||||||
*
|
|
||||||
* (c) Fabien Potencier <fabien@symfony.com>
|
|
||||||
*
|
|
||||||
* 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 <bernhard.schussek@symfony-project.com>
|
|
||||||
*/
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
@ -14,22 +14,13 @@ namespace Symfony\Component\Form\Extension\Core\Type;
|
|||||||
use Symfony\Component\Form\AbstractType;
|
use Symfony\Component\Form\AbstractType;
|
||||||
use Symfony\Component\Form\FormInterface;
|
use Symfony\Component\Form\FormInterface;
|
||||||
use Symfony\Component\Form\FormBuilder;
|
use Symfony\Component\Form\FormBuilder;
|
||||||
use Symfony\Component\Form\Extension\Core\EventListener\FixFileUploadListener;
|
|
||||||
use Symfony\Component\Form\ReversedTransformer;
|
use Symfony\Component\Form\ReversedTransformer;
|
||||||
use Symfony\Component\Form\Extension\Core\DataTransformer\FileToStringTransformer;
|
use Symfony\Component\Form\Extension\Core\DataTransformer\FileToStringTransformer;
|
||||||
use Symfony\Component\Form\Extension\Core\DataTransformer\FileToArrayTransformer;
|
use Symfony\Component\Form\Extension\Core\DataTransformer\FileToArrayTransformer;
|
||||||
use Symfony\Component\Form\FormView;
|
use Symfony\Component\Form\FormView;
|
||||||
use Symfony\Component\HttpFoundation\File\TemporaryStorage;
|
|
||||||
|
|
||||||
class FileType extends AbstractType
|
class FileType extends AbstractType
|
||||||
{
|
{
|
||||||
private $storage;
|
|
||||||
|
|
||||||
public function __construct(TemporaryStorage $storage)
|
|
||||||
{
|
|
||||||
$this->storage = $storage;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function buildForm(FormBuilder $builder, array $options)
|
public function buildForm(FormBuilder $builder, array $options)
|
||||||
{
|
{
|
||||||
if ($options['type'] === 'string') {
|
if ($options['type'] === 'string') {
|
||||||
@ -40,11 +31,7 @@ class FileType extends AbstractType
|
|||||||
|
|
||||||
$builder
|
$builder
|
||||||
->appendNormTransformer(new FileToArrayTransformer())
|
->appendNormTransformer(new FileToArrayTransformer())
|
||||||
->addEventSubscriber(new FixFileUploadListener($this->storage), 10)
|
|
||||||
->add('file', 'field')
|
->add('file', 'field')
|
||||||
->add('token', 'hidden')
|
|
||||||
->add('name', 'hidden')
|
|
||||||
->add('originalName', 'hidden')
|
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,36 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This file is part of the Symfony package.
|
|
||||||
*
|
|
||||||
* (c) Fabien Potencier <fabien@symfony.com>
|
|
||||||
*
|
|
||||||
* 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 <bernhard.schussek@symfony-project.com>
|
|
||||||
*/
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,61 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This file is part of the Symfony package.
|
|
||||||
*
|
|
||||||
* (c) Fabien Potencier <fabien@symfony.com>
|
|
||||||
*
|
|
||||||
* 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 <bernhard.schussek@symfony-project.com>
|
|
||||||
*/
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
@ -51,13 +51,6 @@ class UploadedFile extends File
|
|||||||
*/
|
*/
|
||||||
protected $error;
|
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.
|
* 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 string $mimeType The type of the file as provided by PHP
|
||||||
* @param integer $size The file size
|
* @param integer $size The file size
|
||||||
* @param integer $error The error constant of the upload (one of PHP's UPLOAD_ERR_XXX constants)
|
* @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 FileException If file_uploads is disabled
|
||||||
* @throws FileNotFoundException If the file does not exist
|
* @throws FileNotFoundException If the file does not exist
|
||||||
*/
|
*/
|
||||||
public function __construct($path, $originalName, $mimeType = null,
|
public function __construct($path, $originalName, $mimeType = null, $size = null, $error = null)
|
||||||
$size = null, $error = null, $moved = false)
|
|
||||||
{
|
{
|
||||||
if (!ini_get('file_uploads')) {
|
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')));
|
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->mimeType = $mimeType ?: 'application/octet-stream';
|
||||||
$this->size = $size;
|
$this->size = $size;
|
||||||
$this->error = $error ?: UPLOAD_ERR_OK;
|
$this->error = $error ?: UPLOAD_ERR_OK;
|
||||||
$this->moved = (Boolean) $moved;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -111,10 +101,6 @@ class UploadedFile extends File
|
|||||||
*/
|
*/
|
||||||
public function getExtension()
|
public function getExtension()
|
||||||
{
|
{
|
||||||
if ($this->moved) {
|
|
||||||
return parent::getExtension();
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($ext = pathinfo($this->getOriginalName(), PATHINFO_EXTENSION)) {
|
if ($ext = pathinfo($this->getOriginalName(), PATHINFO_EXTENSION)) {
|
||||||
return $ext;
|
return $ext;
|
||||||
}
|
}
|
||||||
@ -164,10 +150,6 @@ class UploadedFile extends File
|
|||||||
*/
|
*/
|
||||||
public function move($directory, $name = null)
|
public function move($directory, $name = null)
|
||||||
{
|
{
|
||||||
if ($this->moved) {
|
|
||||||
return parent::move($directory, $name);
|
|
||||||
}
|
|
||||||
|
|
||||||
$newPath = $directory.DIRECTORY_SEPARATOR.(null === $name ? $this->getName() : $name);
|
$newPath = $directory.DIRECTORY_SEPARATOR.(null === $name ? $this->getName() : $name);
|
||||||
|
|
||||||
if (!@move_uploaded_file($this->getPath(), $newPath)) {
|
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'])));
|
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);
|
$this->path = realpath($newPath);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -30,10 +30,9 @@ abstract class AbstractLayoutTest extends \PHPUnit_Framework_TestCase
|
|||||||
|
|
||||||
$dispatcher = new EventDispatcher();
|
$dispatcher = new EventDispatcher();
|
||||||
$this->csrfProvider = $this->getMock('Symfony\Component\Form\Extension\Csrf\CsrfProvider\CsrfProviderInterface');
|
$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(
|
$this->factory = new FormFactory(array(
|
||||||
new CoreExtension($storage),
|
new CoreExtension(),
|
||||||
new CsrfExtension($this->csrfProvider),
|
new CsrfExtension($this->csrfProvider),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
@ -757,11 +756,8 @@ abstract class AbstractLayoutTest extends \PHPUnit_Framework_TestCase
|
|||||||
'/div
|
'/div
|
||||||
[
|
[
|
||||||
./input[@type="file"][@id="na&me_file"]
|
./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]
|
||||||
'
|
'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,167 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This file is part of the Symfony package.
|
|
||||||
*
|
|
||||||
* (c) Fabien Potencier <fabien@symfony.com>
|
|
||||||
*
|
|
||||||
* 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;
|
|
||||||
}
|
|
||||||
}
|
|
@ -18,8 +18,6 @@ use Symfony\Component\EventDispatcher\EventDispatcher;
|
|||||||
|
|
||||||
abstract class TypeTestCase extends \PHPUnit_Framework_TestCase
|
abstract class TypeTestCase extends \PHPUnit_Framework_TestCase
|
||||||
{
|
{
|
||||||
protected $storage;
|
|
||||||
|
|
||||||
protected $factory;
|
protected $factory;
|
||||||
|
|
||||||
protected $builder;
|
protected $builder;
|
||||||
@ -31,9 +29,6 @@ abstract class TypeTestCase extends \PHPUnit_Framework_TestCase
|
|||||||
protected function setUp()
|
protected function setUp()
|
||||||
{
|
{
|
||||||
$this->dispatcher = $this->getMock('Symfony\Component\EventDispatcher\EventDispatcherInterface');
|
$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->factory = new FormFactory($this->getExtensions());
|
||||||
$this->builder = new FormBuilder(null, $this->factory, $this->dispatcher);
|
$this->builder = new FormBuilder(null, $this->factory, $this->dispatcher);
|
||||||
}
|
}
|
||||||
@ -41,7 +36,7 @@ abstract class TypeTestCase extends \PHPUnit_Framework_TestCase
|
|||||||
protected function getExtensions()
|
protected function getExtensions()
|
||||||
{
|
{
|
||||||
return array(
|
return array(
|
||||||
new CoreExtension($this->storage),
|
new CoreExtension(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user