Merge branch '5.0'
* 5.0: [HttpClient] Fix typo [Mime] Fix boundary header ignore microseconds submitted by Edge
This commit is contained in:
commit
66a46f0fab
@ -61,16 +61,20 @@ class TimeType extends AbstractType
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ('single_text' === $options['widget']) {
|
if ('single_text' === $options['widget']) {
|
||||||
// handle seconds ignored by user's browser when with_seconds enabled
|
$builder->addViewTransformer(new DateTimeToStringTransformer($options['model_timezone'], $options['view_timezone'], $format));
|
||||||
// https://codereview.chromium.org/450533009/
|
|
||||||
if ($options['with_seconds']) {
|
$builder->addEventListener(FormEvents::PRE_SUBMIT, function (FormEvent $e) use ($options) {
|
||||||
$builder->addEventListener(FormEvents::PRE_SUBMIT, function (FormEvent $e) {
|
$data = $e->getData();
|
||||||
$data = $e->getData();
|
if ($data && preg_match('/^(?P<hours>\d{2}):(?P<minutes>\d{2})(?::(?P<seconds>\d{2})(?:\.\d+)?)?$/', $data, $matches)) {
|
||||||
if ($data && preg_match('/^\d{2}:\d{2}$/', $data)) {
|
if ($options['with_seconds']) {
|
||||||
$e->setData($data.':00');
|
// handle seconds ignored by user's browser when with_seconds enabled
|
||||||
|
// https://codereview.chromium.org/450533009/
|
||||||
|
$e->setData(sprintf('%s:%s:%s', $matches['hours'], $matches['minutes'], isset($matches['seconds']) ? $matches['seconds'] : '00'));
|
||||||
|
} else {
|
||||||
|
$e->setData(sprintf('%s:%s', $matches['hours'], $matches['minutes']));
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
}
|
});
|
||||||
|
|
||||||
if (null !== $options['reference_date']) {
|
if (null !== $options['reference_date']) {
|
||||||
$format = 'Y-m-d '.$format;
|
$format = 'Y-m-d '.$format;
|
||||||
@ -83,8 +87,6 @@ class TimeType extends AbstractType
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
$builder->addViewTransformer(new DateTimeToStringTransformer($options['model_timezone'], $options['view_timezone'], $format));
|
|
||||||
} else {
|
} else {
|
||||||
$hourOptions = $minuteOptions = $secondOptions = [
|
$hourOptions = $minuteOptions = $secondOptions = [
|
||||||
'error_bubbling' => true,
|
'error_bubbling' => true,
|
||||||
|
@ -328,6 +328,54 @@ class TimeTypeTest extends BaseTypeTest
|
|||||||
$this->assertSame('14:09:10', $form->getData()->format('H:i:s'));
|
$this->assertSame('14:09:10', $form->getData()->format('H:i:s'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testSubmitWithoutSecondsAndBrowserAddingSeconds()
|
||||||
|
{
|
||||||
|
$form = $this->factory->create(static::TESTED_TYPE, null, [
|
||||||
|
'model_timezone' => 'UTC',
|
||||||
|
'view_timezone' => 'UTC',
|
||||||
|
'input' => 'string',
|
||||||
|
'widget' => 'single_text',
|
||||||
|
'with_seconds' => false,
|
||||||
|
]);
|
||||||
|
|
||||||
|
$form->submit('03:04:00');
|
||||||
|
|
||||||
|
$this->assertEquals('03:04:00', $form->getData());
|
||||||
|
$this->assertEquals('03:04', $form->getViewData());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testSubmitWithSecondsAndBrowserAddingMicroseconds()
|
||||||
|
{
|
||||||
|
$form = $this->factory->create(static::TESTED_TYPE, null, [
|
||||||
|
'model_timezone' => 'UTC',
|
||||||
|
'view_timezone' => 'UTC',
|
||||||
|
'input' => 'string',
|
||||||
|
'widget' => 'single_text',
|
||||||
|
'with_seconds' => true,
|
||||||
|
]);
|
||||||
|
|
||||||
|
$form->submit('03:04:00.000');
|
||||||
|
|
||||||
|
$this->assertEquals('03:04:00', $form->getData());
|
||||||
|
$this->assertEquals('03:04:00', $form->getViewData());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testSubmitWithoutSecondsAndBrowserAddingMicroseconds()
|
||||||
|
{
|
||||||
|
$form = $this->factory->create(static::TESTED_TYPE, null, [
|
||||||
|
'model_timezone' => 'UTC',
|
||||||
|
'view_timezone' => 'UTC',
|
||||||
|
'input' => 'string',
|
||||||
|
'widget' => 'single_text',
|
||||||
|
'with_seconds' => false,
|
||||||
|
]);
|
||||||
|
|
||||||
|
$form->submit('03:04:00.000');
|
||||||
|
|
||||||
|
$this->assertEquals('03:04:00', $form->getData());
|
||||||
|
$this->assertEquals('03:04', $form->getViewData());
|
||||||
|
}
|
||||||
|
|
||||||
public function testSetDataWithoutMinutes()
|
public function testSetDataWithoutMinutes()
|
||||||
{
|
{
|
||||||
$form = $this->factory->create(static::TESTED_TYPE, null, [
|
$form = $this->factory->create(static::TESTED_TYPE, null, [
|
||||||
|
@ -53,7 +53,7 @@ final class CurlHttpClient implements HttpClientInterface, LoggerAwareInterface,
|
|||||||
private static $curlVersion;
|
private static $curlVersion;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param array $defaultOptions Default requests' options
|
* @param array $defaultOptions Default request's options
|
||||||
* @param int $maxHostConnections The maximum number of connections to a single host
|
* @param int $maxHostConnections The maximum number of connections to a single host
|
||||||
* @param int $maxPendingPushes The maximum number of pushed responses to accept in the queue
|
* @param int $maxPendingPushes The maximum number of pushed responses to accept in the queue
|
||||||
*
|
*
|
||||||
|
@ -21,7 +21,7 @@ use Symfony\Contracts\HttpClient\HttpClientInterface;
|
|||||||
final class HttpClient
|
final class HttpClient
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @param array $defaultOptions Default requests' options
|
* @param array $defaultOptions Default request's options
|
||||||
* @param int $maxHostConnections The maximum number of connections to a single host
|
* @param int $maxHostConnections The maximum number of connections to a single host
|
||||||
* @param int $maxPendingPushes The maximum number of pushed responses to accept in the queue
|
* @param int $maxPendingPushes The maximum number of pushed responses to accept in the queue
|
||||||
*
|
*
|
||||||
|
@ -41,7 +41,7 @@ final class NativeHttpClient implements HttpClientInterface, LoggerAwareInterfac
|
|||||||
private $multi;
|
private $multi;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param array $defaultOptions Default requests' options
|
* @param array $defaultOptions Default request's options
|
||||||
* @param int $maxHostConnections The maximum number of connections to open
|
* @param int $maxHostConnections The maximum number of connections to open
|
||||||
*
|
*
|
||||||
* @see HttpClientInterface::OPTIONS_DEFAULTS for available options
|
* @see HttpClientInterface::OPTIONS_DEFAULTS for available options
|
||||||
|
@ -91,7 +91,7 @@ abstract class AbstractMultipartPart extends AbstractPart
|
|||||||
private function getBoundary(): string
|
private function getBoundary(): string
|
||||||
{
|
{
|
||||||
if (null === $this->boundary) {
|
if (null === $this->boundary) {
|
||||||
$this->boundary = '_=_symfony_'.time().'_'.bin2hex(random_bytes(16)).'_=_';
|
$this->boundary = strtr(base64_encode(random_bytes(6)), '+/', '-_');
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->boundary;
|
return $this->boundary;
|
||||||
|
@ -91,4 +91,16 @@ class FormDataPartTest extends TestCase
|
|||||||
$this->assertEquals($foo, $parts[0]->bodyToString());
|
$this->assertEquals($foo, $parts[0]->bodyToString());
|
||||||
$this->assertEquals($bar, $parts[1]->bodyToString());
|
$this->assertEquals($bar, $parts[1]->bodyToString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testBoundaryContentTypeHeader()
|
||||||
|
{
|
||||||
|
$f = new FormDataPart([
|
||||||
|
'file' => new DataPart('data.csv', 'data.csv', 'text/csv'),
|
||||||
|
]);
|
||||||
|
$headers = $f->getPreparedHeaders()->toArray();
|
||||||
|
$this->assertRegExp(
|
||||||
|
'/^Content-Type: multipart\/form-data; boundary=[a-zA-Z0-9\-_]{8}$/',
|
||||||
|
$headers[0]
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user