Merge branch '2.7' into 2.8

* 2.7:
  [Console] SymfonyStyle : Fix blocks wordwrapping
  [Console] SymfonyStyle : Fix blocks output is broken on windows cmd
  [Validator] remove partial deprecation annotation
  Updated UPGRADE-2.4.md
  [Form] Support DateTimeImmutable in transform()
  Show the FormType and FormTypeExtension in case of deprecated use of setDefaultOptions
  [FrameworkBundle] Document form.csrf_provider service deprecation
  [Form] add test to avoid regression of #14891
  without this change allways the legacy code get called
  [Form] Fix call to removed method (BC broken in 2.3)
  Fix ask and askHidden methods
  [HttpFoundation] Get response content as resource several times for PHP >= 5.6
  Change error message to reflect SecurityContext deprecation.
  fixed merge
  Issue #14815
  [Console] SymfonyStyle : fix & automate block gaps.
  [Console] SymfonyStyle : Improve EOL consistency by relying on output instance
  Improved duplicated code in FileLocator
This commit is contained in:
Fabien Potencier 2015-06-09 17:06:55 +02:00
commit f38296b58c
39 changed files with 609 additions and 74 deletions

View File

@ -7,3 +7,44 @@ Form
* The constructor parameter `$precision` in `IntegerToLocalizedStringTransformer`
is now ignored completely, because a precision does not make sense for
integers.
EventDispatcher
----------------
* The `getDispatcher()` and `getName()` methods from `Symfony\Component\EventDispatcher\Event`
are deprecated, the event dispatcher instance and event name can be received in the listener call instead.
Before:
```php
use Symfony\Component\EventDispatcher\Event;
class Foo
{
public function myFooListener(Event $event)
{
$dispatcher = $event->getDispatcher();
$eventName = $event->getName();
$dispatcher->dispatch('log', $event);
// ... more code
}
}
```
After:
```php
use Symfony\Component\EventDispatcher\Event;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
class Foo
{
public function myFooListener(Event $event, $eventName, EventDispatcherInterface $dispatcher)
{
$dispatcher->dispatch('log', $event);
// ... more code
}
}
```

View File

@ -455,6 +455,12 @@ UPGRADE FROM 2.x to 3.0
engines: ['php']
```
* The `form.csrf_provider` service is removed as it implements an adapter for
the new token manager to the deprecated
`Symfony\Component\Form\Extension\Csrf\CsrfProvider\CsrfProviderInterface`
interface.
The `security.csrf.token_manager` should be used instead.
### HttpKernel
* The `Symfony\Component\HttpKernel\Log\LoggerInterface` has been removed in

View File

@ -47,15 +47,15 @@ class FileLocator implements FileLocatorInterface
return $name;
}
$filepaths = array();
if (null !== $currentPath && file_exists($file = $currentPath.DIRECTORY_SEPARATOR.$name)) {
if (true === $first) {
return $file;
}
$filepaths[] = $file;
$paths = $this->paths;
if (null !== $currentPath) {
array_unshift($paths, $currentPath);
}
foreach ($this->paths as $path) {
$filepaths = array();
foreach ($paths as $path) {
if (file_exists($file = $path.DIRECTORY_SEPARATOR.$name)) {
if (true === $first) {
return $file;
@ -65,7 +65,7 @@ class FileLocator implements FileLocatorInterface
}
if (!$filepaths) {
throw new \InvalidArgumentException(sprintf('The file "%s" does not exist (in: %s%s).', $name, null !== $currentPath ? $currentPath.', ' : '', implode(', ', $this->paths)));
throw new \InvalidArgumentException(sprintf('The file "%s" does not exist (in: %s).', $name, implode(', ', $paths)));
}
return array_values(array_unique($filepaths));

View File

@ -18,6 +18,7 @@ use Symfony\Component\Console\Helper\ProgressBar;
use Symfony\Component\Console\Helper\SymfonyQuestionHelper;
use Symfony\Component\Console\Helper\Table;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\BufferedOutput;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Question\ChoiceQuestion;
use Symfony\Component\Console\Question\ConfirmationQuestion;
@ -36,6 +37,7 @@ class SymfonyStyle extends OutputStyle
private $questionHelper;
private $progressBar;
private $lineLength;
private $bufferedOutput;
/**
* @param InputInterface $input
@ -44,7 +46,9 @@ class SymfonyStyle extends OutputStyle
public function __construct(InputInterface $input, OutputInterface $output)
{
$this->input = $input;
$this->lineLength = min($this->getTerminalWidth(), self::MAX_LINE_LENGTH);
$this->bufferedOutput = new BufferedOutput($output->getVerbosity(), false, clone $output->getFormatter());
// Windows cmd wraps lines as soon as the terminal width is reached, whether there are following chars or not.
$this->lineLength = min($this->getTerminalWidth() - (int) (DIRECTORY_SEPARATOR === '\\'), self::MAX_LINE_LENGTH);
parent::__construct($output);
}
@ -60,6 +64,7 @@ class SymfonyStyle extends OutputStyle
*/
public function block($messages, $type = null, $style = null, $prefix = ' ', $padding = false)
{
$this->autoPrependBlock();
$messages = is_array($messages) ? array_values($messages) : array($messages);
$lines = array();
@ -71,7 +76,7 @@ class SymfonyStyle extends OutputStyle
// wrap and add newlines for each element
foreach ($messages as $key => $message) {
$message = OutputFormatter::escape($message);
$lines = array_merge($lines, explode("\n", wordwrap($message, $this->lineLength - Helper::strlen($prefix))));
$lines = array_merge($lines, explode(PHP_EOL, wordwrap($message, $this->lineLength - Helper::strlen($prefix), PHP_EOL, true)));
if (count($messages) > 1 && $key < count($messages) - 1) {
$lines[] = '';
@ -92,7 +97,8 @@ class SymfonyStyle extends OutputStyle
}
}
$this->writeln(implode("\n", $lines)."\n");
$this->writeln($lines);
$this->newLine();
}
/**
@ -100,7 +106,12 @@ class SymfonyStyle extends OutputStyle
*/
public function title($message)
{
$this->writeln(sprintf("\n<comment>%s</>\n<comment>%s</>\n", $message, str_repeat('=', strlen($message))));
$this->autoPrependBlock();
$this->writeln(array(
sprintf('<comment>%s</>', $message),
sprintf('<comment>%s</>', str_repeat('=', strlen($message))),
));
$this->newLine();
}
/**
@ -108,7 +119,12 @@ class SymfonyStyle extends OutputStyle
*/
public function section($message)
{
$this->writeln(sprintf("<comment>%s</>\n<comment>%s</>\n", $message, str_repeat('-', strlen($message))));
$this->autoPrependBlock();
$this->writeln(array(
sprintf('<comment>%s</>', $message),
sprintf('<comment>%s</>', str_repeat('-', strlen($message))),
));
$this->newLine();
}
/**
@ -116,13 +132,13 @@ class SymfonyStyle extends OutputStyle
*/
public function listing(array $elements)
{
$this->autoPrependText();
$elements = array_map(function ($element) {
return sprintf(' * %s', $element);
},
$elements
);
return sprintf(' * %s', $element);
}, $elements);
$this->writeln(implode("\n", $elements)."\n");
$this->writeln($elements);
$this->newLine();
}
/**
@ -130,6 +146,8 @@ class SymfonyStyle extends OutputStyle
*/
public function text($message)
{
$this->autoPrependText();
if (!is_array($message)) {
$this->writeln(sprintf(' // %s', $message));
@ -205,7 +223,7 @@ class SymfonyStyle extends OutputStyle
$question = new Question($question, $default);
$question->setValidator($validator);
return $this->askQuestion($question, $validator);
return $this->askQuestion($question);
}
/**
@ -214,9 +232,11 @@ class SymfonyStyle extends OutputStyle
public function askHidden($question, $validator = null)
{
$question = new Question($question);
$question->setHidden(true);
return $this->askQuestion($question, $validator);
$question->setHidden(true);
$question->setValidator($validator);
return $this->askQuestion($question);
}
/**
@ -290,17 +310,51 @@ class SymfonyStyle extends OutputStyle
*/
public function askQuestion(Question $question)
{
if ($this->input->isInteractive()) {
$this->autoPrependBlock();
}
if (!$this->questionHelper) {
$this->questionHelper = new SymfonyQuestionHelper();
}
$answer = $this->questionHelper->ask($this->input, $this, $question);
$this->newLine();
if ($this->input->isInteractive()) {
$this->newLine();
$this->bufferedOutput->write("\n");
}
return $answer;
}
/**
* {@inheritdoc}
*/
public function writeln($messages, $type = self::OUTPUT_NORMAL)
{
parent::writeln($messages, $type);
$this->bufferedOutput->writeln($this->reduceBuffer($messages), $type);
}
/**
* {@inheritdoc}
*/
public function write($messages, $newline = false, $type = self::OUTPUT_NORMAL)
{
parent::write($messages, $newline, $type);
$this->bufferedOutput->write($this->reduceBuffer($messages), $newline, $type);
}
/**
* {@inheritdoc}
*/
public function newLine($count = 1)
{
parent::newLine($count);
$this->bufferedOutput->write(str_repeat("\n", $count));
}
/**
* @return ProgressBar
*/
@ -320,4 +374,33 @@ class SymfonyStyle extends OutputStyle
return $dimensions[0] ?: self::MAX_LINE_LENGTH;
}
private function autoPrependBlock()
{
$chars = substr(str_replace(PHP_EOL, "\n", $this->bufferedOutput->fetch()), -2);
if (false === $chars) {
return $this->newLine(); //empty history, so we should start with a new line.
}
//Prepend new line for each non LF chars (This means no blank line was output before)
$this->newLine(2 - substr_count($chars, "\n"));
}
private function autoPrependText()
{
$fetched = $this->bufferedOutput->fetch();
//Prepend new line if last char isn't EOL:
if ("\n" !== substr($fetched, -1)) {
$this->newLine();
}
}
private function reduceBuffer($messages)
{
// We need to know if the two last chars are PHP_EOL
// Preserve the last 4 chars inserted (PHP_EOL on windows is two chars) in the history buffer
return array_map(function ($value) {
return substr($value, -4);
}, array_merge(array($this->bufferedOutput->fetch()), (array) $messages));
}
}

View File

@ -0,0 +1,11 @@
<?php
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;
//Ensure has single blank line at start when using block element
return function (InputInterface $input, OutputInterface $output) {
$output = new SymfonyStyle($input, $output);
$output->caution('Lorem ipsum dolor sit amet');
};

View File

@ -0,0 +1,13 @@
<?php
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;
//Ensure has single blank line between titles and blocks
return function (InputInterface $input, OutputInterface $output) {
$output = new SymfonyStyle($input, $output);
$output->title('Title');
$output->warning('Lorem ipsum dolor sit amet');
$output->title('Title');
};

View File

@ -0,0 +1,16 @@
<?php
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;
//Ensure has single blank line between blocks
return function (InputInterface $input, OutputInterface $output) {
$output = new SymfonyStyle($input, $output);
$output->warning('Warning');
$output->caution('Caution');
$output->error('Error');
$output->success('Success');
$output->note('Note');
$output->block('Custom block', 'CUSTOM', 'fg=white;bg=green', 'X ', true);
};

View File

@ -0,0 +1,12 @@
<?php
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;
//Ensure has single blank line between two titles
return function (InputInterface $input, OutputInterface $output) {
$output = new SymfonyStyle($input, $output);
$output->title('First title');
$output->title('Second title');
};

View File

@ -0,0 +1,34 @@
<?php
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;
//Ensure has single blank line after any text and a title
return function (InputInterface $input, OutputInterface $output) {
$output = new SymfonyStyle($input, $output);
$output->write('Lorem ipsum dolor sit amet');
$output->title('First title');
$output->writeln('Lorem ipsum dolor sit amet');
$output->title('Second title');
$output->write('Lorem ipsum dolor sit amet');
$output->write('');
$output->title('Third title');
//Ensure edge case by appending empty strings to history:
$output->write('Lorem ipsum dolor sit amet');
$output->write(array('', '', ''));
$output->title('Fourth title');
//Ensure have manual control over number of blank lines:
$output->writeln('Lorem ipsum dolor sit amet');
$output->writeln(array('', '')); //Should append an extra blank line
$output->title('Fifth title');
$output->writeln('Lorem ipsum dolor sit amet');
$output->newLine(2); //Should append an extra blank line
$output->title('Fifth title');
};

View File

@ -0,0 +1,29 @@
<?php
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;
//Ensure has proper line ending before outputing a text block like with SymfonyStyle::listing() or SymfonyStyle::text()
return function (InputInterface $input, OutputInterface $output) {
$output = new SymfonyStyle($input, $output);
$output->writeln('Lorem ipsum dolor sit amet');
$output->listing(array(
'Lorem ipsum dolor sit amet',
'consectetur adipiscing elit',
));
//Even using write:
$output->write('Lorem ipsum dolor sit amet');
$output->listing(array(
'Lorem ipsum dolor sit amet',
'consectetur adipiscing elit',
));
$output->write('Lorem ipsum dolor sit amet');
$output->text(array(
'Lorem ipsum dolor sit amet',
'consectetur adipiscing elit',
));
};

View File

@ -0,0 +1,16 @@
<?php
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;
//Ensure has proper blank line after text block when using a block like with SymfonyStyle::success
return function (InputInterface $input, OutputInterface $output) {
$output = new SymfonyStyle($input, $output);
$output->listing(array(
'Lorem ipsum dolor sit amet',
'consectetur adipiscing elit',
));
$output->success('Lorem ipsum dolor sit amet');
};

View File

@ -0,0 +1,15 @@
<?php
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;
//Ensure questions do not output anything when input is non-interactive
return function (InputInterface $input, OutputInterface $output) {
$output = new SymfonyStyle($input, $output);
$output->title('Title');
$output->askHidden('Hidden question');
$output->choice('Choice question with default', array('choice1', 'choice2'), 'choice1');
$output->confirm('Confirmation with yes default', true);
$output->text('Duis aute irure dolor in reprehenderit in voluptate velit esse');
};

View File

@ -0,0 +1,3 @@
! [CAUTION] Lorem ipsum dolor sit amet

View File

@ -0,0 +1,9 @@
Title
=====
[WARNING] Lorem ipsum dolor sit amet
Title
=====

View File

@ -0,0 +1,13 @@
[WARNING] Warning
! [CAUTION] Caution
[ERROR] Error
[OK] Success
! [NOTE] Note
X [CUSTOM] Custom block

View File

@ -0,0 +1,7 @@
First title
===========
Second title
============

View File

@ -0,0 +1,32 @@
Lorem ipsum dolor sit amet
First title
===========
Lorem ipsum dolor sit amet
Second title
============
Lorem ipsum dolor sit amet
Third title
===========
Lorem ipsum dolor sit amet
Fourth title
============
Lorem ipsum dolor sit amet
Fifth title
===========
Lorem ipsum dolor sit amet
Fifth title
===========

View File

@ -0,0 +1,11 @@
Lorem ipsum dolor sit amet
* Lorem ipsum dolor sit amet
* consectetur adipiscing elit
Lorem ipsum dolor sit amet
* Lorem ipsum dolor sit amet
* consectetur adipiscing elit
Lorem ipsum dolor sit amet
// Lorem ipsum dolor sit amet
// consectetur adipiscing elit

View File

@ -0,0 +1,6 @@
* Lorem ipsum dolor sit amet
* consectetur adipiscing elit
[OK] Lorem ipsum dolor sit amet

View File

@ -0,0 +1,5 @@
Title
=====
// Duis aute irure dolor in reprehenderit in voluptate velit esse

View File

@ -0,0 +1,64 @@
<?php
namespace Symfony\Component\Console\Tests\Style;
use PHPUnit_Framework_TestCase;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;
use Symfony\Component\Console\Tester\CommandTester;
class SymfonyStyleTest extends PHPUnit_Framework_TestCase
{
/** @var Command */
protected $command;
/** @var CommandTester */
protected $tester;
protected function setUp()
{
$this->command = new Command('sfstyle');
$this->tester = new CommandTester($this->command);
}
protected function tearDown()
{
$this->command = null;
$this->tester = null;
}
/**
* @dataProvider inputCommandToOutputFilesProvider
*/
public function testOutputs($inputCommandFilepath, $outputFilepath)
{
$code = require $inputCommandFilepath;
$this->command->setCode($code);
$this->tester->execute(array(), array('interactive' => false, 'decorated' => false));
$this->assertStringEqualsFile($outputFilepath, $this->tester->getDisplay(true));
}
public function inputCommandToOutputFilesProvider()
{
$baseDir = __DIR__.'/../Fixtures/Style/SymfonyStyle';
return array_map(null, glob($baseDir.'/command/command_*.php'), glob($baseDir.'/output/output_*.txt'));
}
public function testLongWordsBlockWrapping()
{
$word = 'Lopadotemachoselachogaleokranioleipsanodrimhypotrimmatosilphioparaomelitokatakechymenokichlepikossyphophattoperisteralektryonoptekephalliokigklopeleiolagoiosiraiobaphetraganopterygon';
$wordLength = strlen($word);
$maxLineLength = SymfonyStyle::MAX_LINE_LENGTH - 3;
$this->command->setCode(function (InputInterface $input, OutputInterface $output) use ($word) {
$sfStyle = new SymfonyStyle($input, $output);
$sfStyle->block($word, 'CUSTOM', 'fg=white;bg=blue', ' § ', false);
});
$this->tester->execute(array(), array('interactive' => false, 'decorated' => false));
$expectedCount = (int) ceil($wordLength / ($maxLineLength)) + (int) ($wordLength > $maxLineLength - 5);
$this->assertSame($expectedCount, substr_count($this->tester->getDisplay(true), ' § '));
}
}

View File

@ -51,7 +51,7 @@ class DateTimeToArrayTransformer extends BaseDateTimeTransformer
/**
* Transforms a normalized date into a localized date.
*
* @param \DateTime $dateTime Normalized date.
* @param \DateTime|\DateTimeInterface $dateTime A DateTime object
*
* @return array Localized date.
*
@ -72,14 +72,17 @@ class DateTimeToArrayTransformer extends BaseDateTimeTransformer
), array_flip($this->fields));
}
if (!$dateTime instanceof \DateTime) {
throw new TransformationFailedException('Expected a \DateTime.');
if (!$dateTime instanceof \DateTime && !$dateTime instanceof \DateTimeInterface) {
throw new TransformationFailedException('Expected a \DateTime or \DateTimeInterface.');
}
$dateTime = clone $dateTime;
if ($this->inputTimezone !== $this->outputTimezone) {
if (!$dateTime instanceof \DateTimeImmutable) {
$dateTime = clone $dateTime;
}
try {
$dateTime->setTimezone(new \DateTimeZone($this->outputTimezone));
$dateTime = $dateTime->setTimezone(new \DateTimeZone($this->outputTimezone));
} catch (\Exception $e) {
throw new TransformationFailedException($e->getMessage(), $e->getCode(), $e);
}

View File

@ -70,7 +70,7 @@ class DateTimeToLocalizedStringTransformer extends BaseDateTimeTransformer
/**
* Transforms a normalized date into a localized date string/array.
*
* @param \DateTime $dateTime Normalized date.
* @param \DateTime|\DateTimeInterface $dateTime A DateTime object
*
* @return string|array Localized date string/array.
*
@ -84,17 +84,11 @@ class DateTimeToLocalizedStringTransformer extends BaseDateTimeTransformer
return '';
}
if (!$dateTime instanceof \DateTime) {
throw new TransformationFailedException('Expected a \DateTime.');
if (!$dateTime instanceof \DateTime && !$dateTime instanceof \DateTimeInterface) {
throw new TransformationFailedException('Expected a \DateTime or \DateTimeInterface.');
}
// convert time to UTC before passing it to the formatter
$dateTime = clone $dateTime;
if ('UTC' !== $this->inputTimezone) {
$dateTime->setTimezone(new \DateTimeZone('UTC'));
}
$value = $this->getIntlDateFormatter()->format((int) $dateTime->format('U'));
$value = $this->getIntlDateFormatter()->format($dateTime->getTimestamp());
if (intl_get_error_code() != 0) {
throw new TransformationFailedException(intl_get_error_message());

View File

@ -27,13 +27,13 @@ class DateTimeToRfc3339Transformer extends BaseDateTimeTransformer
return '';
}
if (!$dateTime instanceof \DateTime) {
throw new TransformationFailedException('Expected a \DateTime.');
if (!$dateTime instanceof \DateTime && !$dateTime instanceof \DateTimeInterface) {
throw new TransformationFailedException('Expected a \DateTime or \DateTimeInterface.');
}
if ($this->inputTimezone !== $this->outputTimezone) {
$dateTime = clone $dateTime;
$dateTime->setTimezone(new \DateTimeZone($this->outputTimezone));
$dateTime = $dateTime->setTimezone(new \DateTimeZone($this->outputTimezone));
}
return preg_replace('/\+00:00$/', 'Z', $dateTime->format('c'));

View File

@ -86,7 +86,7 @@ class DateTimeToStringTransformer extends BaseDateTimeTransformer
* Transforms a DateTime object into a date string with the configured format
* and timezone.
*
* @param \DateTime $value A DateTime object
* @param \DateTime|\DateTimeInterface $dateTime A DateTime object
*
* @return string A value as produced by PHP's date() function
*
@ -100,13 +100,16 @@ class DateTimeToStringTransformer extends BaseDateTimeTransformer
return '';
}
if (!$value instanceof \DateTime) {
throw new TransformationFailedException('Expected a \DateTime.');
if (!$value instanceof \DateTime && !$value instanceof \DateTimeInterface) {
throw new TransformationFailedException('Expected a \DateTime or \DateTimeInterface.');
}
if (!$value instanceof \DateTimeImmutable) {
$value = clone $value;
}
$value = clone $value;
try {
$value->setTimezone(new \DateTimeZone($this->outputTimezone));
$value = $value->setTimezone(new \DateTimeZone($this->outputTimezone));
} catch (\Exception $e) {
throw new TransformationFailedException($e->getMessage(), $e->getCode(), $e);
}

View File

@ -24,7 +24,7 @@ class DateTimeToTimestampTransformer extends BaseDateTimeTransformer
/**
* Transforms a DateTime object into a timestamp in the configured timezone.
*
* @param \DateTime $value A \DateTime object
* @param \DateTime|\DateTimeInterface $dateTime A DateTime object
*
* @return int A timestamp
*
@ -38,18 +38,11 @@ class DateTimeToTimestampTransformer extends BaseDateTimeTransformer
return;
}
if (!$value instanceof \DateTime) {
throw new TransformationFailedException('Expected a \DateTime.');
if (!$value instanceof \DateTime && !$value instanceof \DateTimeInterface) {
throw new TransformationFailedException('Expected a \DateTime or \DateTimeInterface.');
}
$value = clone $value;
try {
$value->setTimezone(new \DateTimeZone($this->outputTimezone));
} catch (\Exception $e) {
throw new TransformationFailedException($e->getMessage(), $e->getCode(), $e);
}
return (int) $value->format('U');
return $value->getTimestamp();
}
/**

View File

@ -59,13 +59,13 @@ class ValidatorExtension extends AbstractExtension
public function loadTypeGuesser()
{
// 2.4 API
if ($this->validator instanceof LegacyValidatorInterface) {
return new ValidatorTypeGuesser($this->validator->getMetadataFactory());
// 2.5 API
if ($this->validator instanceof ValidatorInterface) {
return new ValidatorTypeGuesser($this->validator);
}
// 2.5 API - ValidatorInterface extends MetadataFactoryInterface
return new ValidatorTypeGuesser($this->validator);
// 2.4 API
return new ValidatorTypeGuesser($this->validator->getMetadataFactory());
}
protected function loadTypeExtensions()

View File

@ -93,11 +93,6 @@ class ResolvedFormType implements ResolvedFormTypeInterface
*/
public function getTypeExtensions()
{
// BC
if ($this->innerType instanceof AbstractType) {
return $this->innerType->getExtensions();
}
return $this->typeExtensions;
}
@ -212,7 +207,7 @@ class ResolvedFormType implements ResolvedFormTypeInterface
$isNewOverwritten = $reflector->getDeclaringClass()->getName() !== 'Symfony\Component\Form\AbstractType';
if ($isOldOverwritten && !$isNewOverwritten) {
trigger_error('The FormTypeInterface::setDefaultOptions() method is deprecated since version 2.7 and will be removed in 3.0. Use configureOptions() instead. This method will be added to the FormTypeInterface with Symfony 3.0.', E_USER_DEPRECATED);
trigger_error(get_class($this->innerType).': The FormTypeInterface::setDefaultOptions() method is deprecated since version 2.7 and will be removed in 3.0. Use configureOptions() instead. This method will be added to the FormTypeInterface with Symfony 3.0.', E_USER_DEPRECATED);
}
foreach ($this->typeExtensions as $extension) {
@ -225,7 +220,7 @@ class ResolvedFormType implements ResolvedFormTypeInterface
$isNewOverwritten = $reflector->getDeclaringClass()->getName() !== 'Symfony\Component\Form\AbstractTypeExtension';
if ($isOldOverwritten && !$isNewOverwritten) {
trigger_error('The FormTypeExtensionInterface::setDefaultOptions() method is deprecated since version 2.7 and will be removed in 3.0. Use configureOptions() instead. This method will be added to the FormTypeExtensionInterface with Symfony 3.0.', E_USER_DEPRECATED);
trigger_error(get_class($extension).': The FormTypeExtensionInterface::setDefaultOptions() method is deprecated since version 2.7 and will be removed in 3.0. Use configureOptions() instead. This method will be added to the FormTypeExtensionInterface with Symfony 3.0.', E_USER_DEPRECATED);
}
}
}

View File

@ -116,6 +116,30 @@ class DateTimeToArrayTransformerTest extends DateTimeTestCase
$this->assertSame($output, $transformer->transform($input));
}
public function testTransformDateTimeImmutable()
{
if (PHP_VERSION_ID < 50500) {
$this->markTestSkipped('DateTimeImmutable was introduced in PHP 5.5.0');
}
$transformer = new DateTimeToArrayTransformer('America/New_York', 'Asia/Hong_Kong');
$input = new \DateTimeImmutable('2010-02-03 04:05:06 America/New_York');
$dateTime = new \DateTimeImmutable('2010-02-03 04:05:06 America/New_York');
$dateTime = $dateTime->setTimezone(new \DateTimeZone('Asia/Hong_Kong'));
$output = array(
'year' => (string) (int) $dateTime->format('Y'),
'month' => (string) (int) $dateTime->format('m'),
'day' => (string) (int) $dateTime->format('d'),
'hour' => (string) (int) $dateTime->format('H'),
'minute' => (string) (int) $dateTime->format('i'),
'second' => (string) (int) $dateTime->format('s'),
);
$this->assertSame($output, $transformer->transform($input));
}
/**
* @expectedException \Symfony\Component\Form\Exception\TransformationFailedException
*/

View File

@ -141,6 +141,22 @@ class DateTimeToLocalizedStringTransformerTest extends DateTimeTestCase
$this->assertEquals('02*2010*03 04|05|06', $transformer->transform($this->dateTime));
}
public function testTransformDateTimeImmutableTimezones()
{
if (PHP_VERSION_ID < 50500) {
$this->markTestSkipped('DateTimeImmutable was introduced in PHP 5.5.0');
}
$transformer = new DateTimeToLocalizedStringTransformer('America/New_York', 'Asia/Hong_Kong');
$input = new \DateTimeImmutable('2010-02-03 04:05:06 America/New_York');
$dateTime = clone $input;
$dateTime = $dateTime->setTimezone(new \DateTimeZone('Asia/Hong_Kong'));
$this->assertEquals($dateTime->format('d.m.Y H:i'), $transformer->transform($input));
}
/**
* @expectedException \Symfony\Component\Form\Exception\TransformationFailedException
*/

View File

@ -79,6 +79,20 @@ class DateTimeToRfc3339TransformerTest extends DateTimeTestCase
$this->assertSame($to, $transformer->transform(null !== $from ? new \DateTime($from) : null));
}
/**
* @dataProvider transformProvider
*/
public function testTransformDateTimeImmutable($fromTz, $toTz, $from, $to)
{
if (PHP_VERSION_ID < 50500) {
$this->markTestSkipped('DateTimeImmutable was introduced in PHP 5.5.0');
}
$transformer = new DateTimeToRfc3339Transformer($fromTz, $toTz);
$this->assertSame($to, $transformer->transform(null !== $from ? new \DateTimeImmutable($from) : null));
}
/**
* @expectedException \Symfony\Component\Form\Exception\TransformationFailedException
*/

View File

@ -94,6 +94,21 @@ class DateTimeToStringTransformerTest extends DateTimeTestCase
$this->assertEquals($output, $transformer->transform($input));
}
public function testTransformDateTimeImmutable()
{
if (PHP_VERSION_ID < 50500) {
$this->markTestSkipped('DateTimeImmutable was introduced in PHP 5.5.0');
}
$transformer = new DateTimeToStringTransformer('Asia/Hong_Kong', 'America/New_York', 'Y-m-d H:i:s');
$input = new \DateTimeImmutable('2010-02-03 12:05:06 America/New_York');
$output = $input->format('Y-m-d H:i:s');
$input = $input->setTimezone(new \DateTimeZone('Asia/Hong_Kong'));
$this->assertEquals($output, $transformer->transform($input));
}
public function testTransformExpectsDateTime()
{
$transformer = new DateTimeToStringTransformer();

View File

@ -56,6 +56,21 @@ class DateTimeToTimestampTransformerTest extends DateTimeTestCase
$this->assertEquals($output, $transformer->transform($input));
}
public function testTransformDateTimeImmutable()
{
if (PHP_VERSION_ID < 50500) {
$this->markTestSkipped('DateTimeImmutable was introduced in PHP 5.5.0');
}
$transformer = new DateTimeToTimestampTransformer('Asia/Hong_Kong', 'America/New_York');
$input = new \DateTimeImmutable('2010-02-03 04:05:06 America/New_York');
$output = $input->format('U');
$input = $input->setTimezone(new \DateTimeZone('Asia/Hong_Kong'));
$this->assertEquals($output, $transformer->transform($input));
}
public function testTransformExpectsDateTime()
{
$transformer = new DateTimeToTimestampTransformer();

View File

@ -17,7 +17,9 @@ class ValidatorExtensionTest extends \PHPUnit_Framework_TestCase
{
public function test2Dot5ValidationApi()
{
$validator = $this->getMock('Symfony\Component\Validator\Validator\ValidatorInterface');
$validator = $this->getMockBuilder('Symfony\Component\Validator\Validator\RecursiveValidator')
->disableOriginalConstructor()
->getMock();
$metadata = $this->getMockBuilder('Symfony\Component\Validator\Mapping\ClassMetadata')
->disableOriginalConstructor()
->getMock();
@ -36,6 +38,10 @@ class ValidatorExtensionTest extends \PHPUnit_Framework_TestCase
->method('addPropertyConstraint')
->with('children', $this->isInstanceOf('Symfony\Component\Validator\Constraints\Valid'));
$validator
->expects($this->never())
->method('getMetadataFactory');
$extension = new ValidatorExtension($validator);
$guesser = $extension->loadTypeGuesser();

View File

@ -1557,8 +1557,8 @@ class Request
*/
public function getContent($asResource = false)
{
if (false === $this->content || (true === $asResource && null !== $this->content)) {
throw new \LogicException('getContent() can only be called once when using the resource return type.');
if (PHP_VERSION_ID < 50600 && (false === $this->content || (true === $asResource && null !== $this->content))) {
throw new \LogicException('getContent() can only be called once when using the resource return type and PHP below 5.6.');
}
if (true === $asResource) {

View File

@ -975,11 +975,40 @@ class RequestTest extends \PHPUnit_Framework_TestCase
*/
public function testGetContentCantBeCalledTwiceWithResources($first, $second)
{
if (PHP_VERSION_ID >= 50600) {
$this->markTestSkipped('PHP >= 5.6 allows to open php://input several times.');
}
$req = new Request();
$req->getContent($first);
$req->getContent($second);
}
/**
*
* @dataProvider getContentCantBeCalledTwiceWithResourcesProvider
*/
public function testGetContentCanBeCalledTwiceWithResources($first, $second)
{
if (PHP_VERSION_ID < 50600) {
$this->markTestSkipped('PHP < 5.6 does not allow to open php://input several times.');
}
$req = new Request();
$a = $req->getContent($first);
$b = $req->getContent($second);
if ($first) {
$a = stream_get_contents($a);
}
if ($second) {
$b = stream_get_contents($b);
}
$this->assertEquals($a, $b);
}
public function getContentCantBeCalledTwiceWithResourcesProvider()
{
return array(

View File

@ -50,7 +50,7 @@ class AccessListener implements ListenerInterface
public function handle(GetResponseEvent $event)
{
if (null === $token = $this->tokenStorage->getToken()) {
throw new AuthenticationCredentialsNotFoundException('A Token was not found in the SecurityContext.');
throw new AuthenticationCredentialsNotFoundException('A Token was not found in the TokenStorage.');
}
$request = $event->getRequest();

View File

@ -91,6 +91,8 @@ interface ExecutionContextInterface
/**
* Adds a violation at the current node of the validation graph.
*
* Note: the parameters $invalidValue, $plural and $code are deprecated since version 2.5 and will be removed in 3.0.
*
* @param string $message The error message
* @param array $params The parameters substituted in the error message
* @param mixed $invalidValue The invalid, validated value
@ -98,8 +100,6 @@ interface ExecutionContextInterface
* @param int|null $code The violation code
*
* @api
*
* @deprecated the parameters $invalidValue, $plural and $code are deprecated since version 2.5 and will be removed in 3.0.
*/
public function addViolation($message, array $params = array(), $invalidValue = null, $plural = null, $code = null);

View File

@ -38,6 +38,8 @@ class Yaml
* you must validate the input before calling this method. Passing a file
* as an input is a deprecated feature and will be removed in 3.0.
*
* Note: the ability to pass file names to the Yaml::parse method is deprecated since version 2.2 and will be removed in 3.0. Pass the YAML contents of the file instead.
*
* @param string $input Path to a YAML file or a string containing YAML
* @param bool $exceptionOnInvalidType True if an exception must be thrown on invalid types false otherwise
* @param bool $objectSupport True if object support is enabled, false otherwise