Merge branch '2.7' into 2.8
* 2.7: Remove 3.1 from PR template fixed test name Casting TableCell value to string. [FrameworkBundle] fixed custom domain for translations in php templates [Form] Fixed DateType format option
This commit is contained in:
commit
47a8b4dc58
2
.github/PULL_REQUEST_TEMPLATE.md
vendored
2
.github/PULL_REQUEST_TEMPLATE.md
vendored
@ -1,6 +1,6 @@
|
||||
| Q | A
|
||||
| ------------- | ---
|
||||
| Branch? | master / 2.7, 2.8, 3.1 or 3.2 <!--see comment below-->
|
||||
| Branch? | master / 2.7, 2.8 or 3.2 <!--see comment below-->
|
||||
| Bug fix? | yes/no
|
||||
| New feature? | yes/no
|
||||
| BC breaks? | yes/no
|
||||
|
@ -31,3 +31,19 @@ EOF
|
||||
10,
|
||||
array('%count%' => 10)
|
||||
) ?>
|
||||
|
||||
<?php echo $view['translator']->trans('other-domain-test-no-params-short-array', [], 'not_messages'); ?>
|
||||
|
||||
<?php echo $view['translator']->trans('other-domain-test-no-params-long-array', array(), 'not_messages'); ?>
|
||||
|
||||
<?php echo $view['translator']->trans('other-domain-test-params-short-array', ['foo' => 'bar'], 'not_messages'); ?>
|
||||
|
||||
<?php echo $view['translator']->trans('other-domain-test-params-long-array', array('foo' => 'bar'), 'not_messages'); ?>
|
||||
|
||||
<?php echo $view['translator']->transChoice('other-domain-test-trans-choice-short-array-%count%', 10, ['%count%' => 10], 'not_messages'); ?>
|
||||
|
||||
<?php echo $view['translator']->transChoice('other-domain-test-trans-choice-long-array-%count%', 10, array('%count%' => 10), 'not_messages'); ?>
|
||||
|
||||
<?php echo $view['translator']->trans('typecast', ['a' => (int) '123'], 'not_messages'); ?>
|
||||
<?php echo $view['translator']->transChoice('msg1', 10 + 1, [], 'not_messages'); ?>
|
||||
<?php echo $view['translator']->transChoice('msg2', intval(4.5), [], 'not_messages'); ?>
|
||||
|
@ -39,7 +39,8 @@ EOF;
|
||||
nowdoc key with whitespace and nonescaped \$\n sequences
|
||||
EOF;
|
||||
// Assert
|
||||
$expectedCatalogue = array('messages' => array(
|
||||
$expectedCatalogue = array(
|
||||
'messages' => array(
|
||||
'single-quoted key' => 'prefixsingle-quoted key',
|
||||
'double-quoted key' => 'prefixdouble-quoted key',
|
||||
'heredoc key' => 'prefixheredoc key',
|
||||
@ -50,7 +51,19 @@ EOF;
|
||||
$expectedHeredoc => 'prefix'.$expectedHeredoc,
|
||||
$expectedNowdoc => 'prefix'.$expectedNowdoc,
|
||||
'{0} There is no apples|{1} There is one apple|]1,Inf[ There are %count% apples' => 'prefix{0} There is no apples|{1} There is one apple|]1,Inf[ There are %count% apples',
|
||||
));
|
||||
),
|
||||
'not_messages' => array(
|
||||
'other-domain-test-no-params-short-array' => 'prefixother-domain-test-no-params-short-array',
|
||||
'other-domain-test-no-params-long-array' => 'prefixother-domain-test-no-params-long-array',
|
||||
'other-domain-test-params-short-array' => 'prefixother-domain-test-params-short-array',
|
||||
'other-domain-test-params-long-array' => 'prefixother-domain-test-params-long-array',
|
||||
'other-domain-test-trans-choice-short-array-%count%' => 'prefixother-domain-test-trans-choice-short-array-%count%',
|
||||
'other-domain-test-trans-choice-long-array-%count%' => 'prefixother-domain-test-trans-choice-long-array-%count%',
|
||||
'typecast' => 'prefixtypecast',
|
||||
'msg1' => 'prefixmsg1',
|
||||
'msg2' => 'prefixmsg2',
|
||||
),
|
||||
);
|
||||
$actualCatalogue = $catalogue->all();
|
||||
|
||||
$this->assertEquals($expectedCatalogue, $actualCatalogue);
|
||||
|
@ -24,6 +24,8 @@ use Symfony\Component\Translation\Extractor\ExtractorInterface;
|
||||
class PhpExtractor extends AbstractFileExtractor implements ExtractorInterface
|
||||
{
|
||||
const MESSAGE_TOKEN = 300;
|
||||
const METHOD_ARGUMENTS_TOKEN = 1000;
|
||||
const DOMAIN_TOKEN = 1001;
|
||||
|
||||
/**
|
||||
* Prefix for new found message.
|
||||
@ -38,6 +40,28 @@ class PhpExtractor extends AbstractFileExtractor implements ExtractorInterface
|
||||
* @var array
|
||||
*/
|
||||
protected $sequences = array(
|
||||
array(
|
||||
'->',
|
||||
'trans',
|
||||
'(',
|
||||
self::MESSAGE_TOKEN,
|
||||
',',
|
||||
self::METHOD_ARGUMENTS_TOKEN,
|
||||
',',
|
||||
self::DOMAIN_TOKEN,
|
||||
),
|
||||
array(
|
||||
'->',
|
||||
'transChoice',
|
||||
'(',
|
||||
self::MESSAGE_TOKEN,
|
||||
',',
|
||||
self::METHOD_ARGUMENTS_TOKEN,
|
||||
',',
|
||||
self::METHOD_ARGUMENTS_TOKEN,
|
||||
',',
|
||||
self::DOMAIN_TOKEN,
|
||||
),
|
||||
array(
|
||||
'->',
|
||||
'trans',
|
||||
@ -105,11 +129,32 @@ class PhpExtractor extends AbstractFileExtractor implements ExtractorInterface
|
||||
}
|
||||
}
|
||||
|
||||
private function skipMethodArgument(\Iterator $tokenIterator)
|
||||
{
|
||||
$openBraces = 0;
|
||||
|
||||
for (; $tokenIterator->valid(); $tokenIterator->next()) {
|
||||
$t = $tokenIterator->current();
|
||||
|
||||
if ('[' === $t[0] || '(' === $t[0]) {
|
||||
++$openBraces;
|
||||
}
|
||||
|
||||
if (']' === $t[0] || ')' === $t[0]) {
|
||||
--$openBraces;
|
||||
}
|
||||
|
||||
if ((0 === $openBraces && ',' === $t[0]) || (-1 === $openBraces && ')' === $t[0])) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts the message from the iterator while the tokens
|
||||
* match allowed message tokens.
|
||||
*/
|
||||
private function getMessage(\Iterator $tokenIterator)
|
||||
private function getValue(\Iterator $tokenIterator)
|
||||
{
|
||||
$message = '';
|
||||
$docToken = '';
|
||||
@ -155,16 +200,26 @@ class PhpExtractor extends AbstractFileExtractor implements ExtractorInterface
|
||||
for ($key = 0; $key < $tokenIterator->count(); ++$key) {
|
||||
foreach ($this->sequences as $sequence) {
|
||||
$message = '';
|
||||
$domain = 'messages';
|
||||
$tokenIterator->seek($key);
|
||||
|
||||
foreach ($sequence as $item) {
|
||||
foreach ($sequence as $sequenceKey => $item) {
|
||||
$this->seekToNextRelevantToken($tokenIterator);
|
||||
|
||||
if ($this->normalizeToken($tokenIterator->current()) == $item) {
|
||||
if ($this->normalizeToken($tokenIterator->current()) === $item) {
|
||||
$tokenIterator->next();
|
||||
continue;
|
||||
} elseif (self::MESSAGE_TOKEN == $item) {
|
||||
$message = $this->getMessage($tokenIterator);
|
||||
} elseif (self::MESSAGE_TOKEN === $item) {
|
||||
$message = $this->getValue($tokenIterator);
|
||||
|
||||
if (count($sequence) === ($sequenceKey + 1)) {
|
||||
break;
|
||||
}
|
||||
} elseif (self::METHOD_ARGUMENTS_TOKEN === $item) {
|
||||
$this->skipMethodArgument($tokenIterator);
|
||||
} elseif (self::DOMAIN_TOKEN === $item) {
|
||||
$domain = $this->getValue($tokenIterator);
|
||||
|
||||
break;
|
||||
} else {
|
||||
break;
|
||||
@ -172,7 +227,7 @@ class PhpExtractor extends AbstractFileExtractor implements ExtractorInterface
|
||||
}
|
||||
|
||||
if ($message) {
|
||||
$catalog->set($message, $this->prefix.$message);
|
||||
$catalog->set($message, $this->prefix.$message, $domain);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -37,6 +37,10 @@ class TableCell
|
||||
*/
|
||||
public function __construct($value = '', array $options = array())
|
||||
{
|
||||
if (is_numeric($value) && !is_string($value)) {
|
||||
$value = (string) $value;
|
||||
}
|
||||
|
||||
$this->value = $value;
|
||||
|
||||
// check option names
|
||||
|
@ -535,6 +535,42 @@ TABLE
|
||||
| 1234 |
|
||||
+------+
|
||||
|
||||
TABLE;
|
||||
|
||||
$this->assertEquals($expected, $this->getOutputContent($output));
|
||||
}
|
||||
|
||||
public function testTableCellWithNumericIntValue()
|
||||
{
|
||||
$table = new Table($output = $this->getOutputStream());
|
||||
|
||||
$table->setRows(array(array(new TableCell(12345))));
|
||||
$table->render();
|
||||
|
||||
$expected =
|
||||
<<<'TABLE'
|
||||
+-------+
|
||||
| 12345 |
|
||||
+-------+
|
||||
|
||||
TABLE;
|
||||
|
||||
$this->assertEquals($expected, $this->getOutputContent($output));
|
||||
}
|
||||
|
||||
public function testTableCellWithNumericFloatValue()
|
||||
{
|
||||
$table = new Table($output = $this->getOutputStream());
|
||||
|
||||
$table->setRows(array(array(new TableCell(12345.01))));
|
||||
$table->render();
|
||||
|
||||
$expected =
|
||||
<<<'TABLE'
|
||||
+----------+
|
||||
| 12345.01 |
|
||||
+----------+
|
||||
|
||||
TABLE;
|
||||
|
||||
$this->assertEquals($expected, $this->getOutputContent($output));
|
||||
|
@ -56,11 +56,11 @@ class DateType extends AbstractType
|
||||
throw new InvalidOptionsException('The "format" option must be one of the IntlDateFormatter constants (FULL, LONG, MEDIUM, SHORT) or a string representing a custom format.');
|
||||
}
|
||||
|
||||
if (null !== $pattern && (false === strpos($pattern, 'y') || false === strpos($pattern, 'M') || false === strpos($pattern, 'd'))) {
|
||||
throw new InvalidOptionsException(sprintf('The "format" option should contain the letters "y", "M" and "d". Its current value is "%s".', $pattern));
|
||||
if ('single_text' === $options['widget']) {
|
||||
if (null !== $pattern && false === strpos($pattern, 'y') && false === strpos($pattern, 'M') && false === strpos($pattern, 'd')) {
|
||||
throw new InvalidOptionsException(sprintf('The "format" option should contain the letters "y", "M" or "d". Its current value is "%s".', $pattern));
|
||||
}
|
||||
|
||||
if ('single_text' === $options['widget']) {
|
||||
$builder->addViewTransformer(new DateTimeToLocalizedStringTransformer(
|
||||
$options['model_timezone'],
|
||||
$options['view_timezone'],
|
||||
@ -70,6 +70,10 @@ class DateType extends AbstractType
|
||||
$pattern
|
||||
));
|
||||
} else {
|
||||
if (null !== $pattern && (false === strpos($pattern, 'y') || false === strpos($pattern, 'M') || false === strpos($pattern, 'd'))) {
|
||||
throw new InvalidOptionsException(sprintf('The "format" option should contain the letters "y", "M" and "d". Its current value is "%s".', $pattern));
|
||||
}
|
||||
|
||||
$yearOptions = $monthOptions = $dayOptions = array(
|
||||
'error_bubbling' => true,
|
||||
);
|
||||
|
@ -77,6 +77,22 @@ class DateTypeTest extends TestCase
|
||||
$this->assertEquals('2010-06-02', $form->getViewData());
|
||||
}
|
||||
|
||||
public function testSubmitFromSingleTextDateTimeWithCustomFormat()
|
||||
{
|
||||
$form = $this->factory->create('date', null, array(
|
||||
'model_timezone' => 'UTC',
|
||||
'view_timezone' => 'UTC',
|
||||
'widget' => 'single_text',
|
||||
'input' => 'datetime',
|
||||
'format' => 'yyyy',
|
||||
));
|
||||
|
||||
$form->submit('2010');
|
||||
|
||||
$this->assertDateTimeEquals(new \DateTime('2010-01-01 UTC'), $form->getData());
|
||||
$this->assertEquals('2010', $form->getViewData());
|
||||
}
|
||||
|
||||
public function testSubmitFromSingleTextDateTime()
|
||||
{
|
||||
// we test against "de_DE", so we need the full implementation
|
||||
@ -347,6 +363,7 @@ class DateTypeTest extends TestCase
|
||||
|
||||
/**
|
||||
* @expectedException \Symfony\Component\OptionsResolver\Exception\InvalidOptionsException
|
||||
* @expectedExceptionMessage The "format" option should contain the letters "y", "M" and "d". Its current value is "yy".
|
||||
*/
|
||||
public function testThrowExceptionIfFormatDoesNotContainYearMonthAndDay()
|
||||
{
|
||||
@ -356,6 +373,18 @@ class DateTypeTest extends TestCase
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \Symfony\Component\OptionsResolver\Exception\InvalidOptionsException
|
||||
* @expectedExceptionMessage The "format" option should contain the letters "y", "M" or "d". Its current value is "wrong".
|
||||
*/
|
||||
public function testThrowExceptionIfFormatMissesYearMonthAndDayWithSingleTextWidget()
|
||||
{
|
||||
$this->factory->create('date', null, array(
|
||||
'widget' => 'single_text',
|
||||
'format' => 'wrong',
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \Symfony\Component\OptionsResolver\Exception\InvalidOptionsException
|
||||
*/
|
||||
|
Reference in New Issue
Block a user