Merge branch '2.3' into 2.7

* 2.3:
  [2.7] Fixed flatten exception recursion with errors
  Embedded identifier support
  Change the ExtensionInterface load method definition to bo identical to the documentation.
  add and correct armenian translations
  [Config] Fix array sort on normalization in edge case
  [Yaml] fix indented line handling in folded blocks
  improve BrowserKit test coverage p1
This commit is contained in:
Fabien Potencier 2015-12-26 14:37:43 +01:00
commit 97cf53f9bd
16 changed files with 438 additions and 69 deletions

View File

@ -92,6 +92,7 @@ class ORMQueryBuilderLoader implements EntityLoaderInterface
$qb = clone $this->queryBuilder;
$alias = current($qb->getRootAliases());
$parameter = 'ORMQueryBuilderLoader_getEntitiesByIds_'.$identifier;
$parameter = str_replace('.', '_', $parameter);
$where = $qb->expr()->in($alias.'.'.$identifier, ':'.$parameter);
// Guess type

View File

@ -0,0 +1,28 @@
<?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\Bridge\Doctrine\Tests\Fixtures\Embeddable;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Embeddable
*/
class Identifier
{
/**
* @var int
*
* @ORM\Id
* @ORM\Column(type="integer")
*/
protected $value;
}

View File

@ -0,0 +1,27 @@
<?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\Bridge\Doctrine\Tests\Fixtures;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity
*/
class EmbeddedIdentifierEntity
{
/**
* @var Embeddable\Identifier
*
* @ORM\Embedded(class="Symfony\Bridge\Doctrine\Tests\Fixtures\Embeddable\Identifier")
*/
protected $id;
}

View File

@ -14,6 +14,7 @@ namespace Symfony\Bridge\Doctrine\Tests\Form\ChoiceList;
use Symfony\Bridge\Doctrine\Form\ChoiceList\ORMQueryBuilderLoader;
use Symfony\Bridge\Doctrine\Test\DoctrineTestHelper;
use Doctrine\DBAL\Connection;
use Doctrine\ORM\Version;
class ORMQueryBuilderLoaderTest extends \PHPUnit_Framework_TestCase
{
@ -104,4 +105,38 @@ class ORMQueryBuilderLoaderTest extends \PHPUnit_Framework_TestCase
$loader = new ORMQueryBuilderLoader($qb);
$loader->getEntitiesByIds('id', array(1, '', 2, 3, 'foo'));
}
public function testEmbeddedIdentifierName()
{
if (Version::compare('2.5.0') > 0) {
$this->markTestSkipped('Applicable only for Doctrine >= 2.5.0');
return;
}
$em = DoctrineTestHelper::createTestEntityManager();
$query = $this->getMockBuilder('QueryMock')
->setMethods(array('setParameter', 'getResult', 'getSql', '_doExecute'))
->getMock();
$query->expects($this->once())
->method('setParameter')
->with('ORMQueryBuilderLoader_getEntitiesByIds_id_value', array(1, 2, 3), Connection::PARAM_INT_ARRAY)
->willReturn($query);
$qb = $this->getMockBuilder('Doctrine\ORM\QueryBuilder')
->setConstructorArgs(array($em))
->setMethods(array('getQuery'))
->getMock();
$qb->expects($this->once())
->method('getQuery')
->willReturn($query);
$qb->select('e')
->from('Symfony\Bridge\Doctrine\Tests\Fixtures\EmbeddedIdentifierEntity', 'e');
$loader = new ORMQueryBuilderLoader($qb);
$loader->getEntitiesByIds('id.value', array(1, '', 2, 3, 'foo'));
}
}

View File

@ -18,7 +18,7 @@ use Symfony\Component\HttpKernel\DependencyInjection\Extension;
class FirewallEntryPointExtension extends Extension
{
public function load(array $config, ContainerBuilder $container)
public function load(array $configs, ContainerBuilder $container)
{
$loader = new XmlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
$loader->load('services.xml');

View File

@ -624,4 +624,24 @@ class ClientTest extends \PHPUnit_Framework_TestCase
$this->assertArrayHasKey('HTTPS', $server);
$this->assertFalse($server['HTTPS']);
}
public function testInternalRequest()
{
$client = new TestClient();
$client->request('GET', 'https://www.example.com/https/www.example.com', array(), array(), array(
'HTTP_HOST' => 'testhost',
'HTTP_USER_AGENT' => 'testua',
'HTTPS' => false,
'NEW_SERVER_KEY' => 'new-server-key-value',
));
$this->assertInstanceOf('Symfony\Component\BrowserKit\Request', $client->getInternalRequest());
}
public function testInternalRequestNull()
{
$client = new TestClient();
$this->assertNull($client->getInternalRequest());
}
}

View File

@ -174,6 +174,16 @@ class CookieJarTest extends \PHPUnit_Framework_TestCase
$this->assertEquals(array(), array_keys($cookieJar->allValues('http://example.com/')));
}
public function testCookieExpireWithDomain()
{
$cookieJar = new CookieJar();
$cookieJar->set($cookie1 = new Cookie('foo', 'bar1', null, '/foo', 'http://example2.com/'));
$cookieJar->expire('foo', '/foo', 'http://example2.com/');
$this->assertNull($cookieJar->get('foo'), '->get() returns null if the cookie is expired');
$this->assertEquals(array(), array_keys($cookieJar->allValues('http://example2.com/')));
}
public function testCookieWithSameNameButDifferentPaths()
{
$cookieJar = new CookieJar();
@ -207,6 +217,14 @@ class CookieJarTest extends \PHPUnit_Framework_TestCase
$this->assertEquals($cookie2, $cookieJar->get('foo1', '/', 'test.example.com'));
}
public function testCookieGetWithWrongSubdomain()
{
$cookieJar = new CookieJar();
$cookieJar->set($cookie1 = new Cookie('foo1', 'bar', null, '/', 'test.example.com'));
$this->assertNull($cookieJar->get('foo1', '/', 'foo.example.com'));
}
public function testCookieGetWithSubdirectory()
{
$cookieJar = new CookieJar();

View File

@ -176,4 +176,13 @@ class CookieTest extends \PHPUnit_Framework_TestCase
$cookie = new Cookie('foo', 'bar', 0);
$this->assertFalse($cookie->isExpired());
}
/**
* @expectedException UnexpectedValueException
* @expectedExceptionMessage The cookie expiration time "string" is not valid.
*/
public function testConstructException()
{
$cookie = new Cookie('foo', 'bar', 'string');
}
}

View File

@ -55,14 +55,17 @@ class ArrayNode extends BaseNode implements PrototypeNodeInterface
return $value;
}
$normalized = array();
foreach ($value as $k => $v) {
if (false !== strpos($k, '-') && false === strpos($k, '_') && !array_key_exists($normalizedKey = str_replace('-', '_', $k), $value)) {
$value[$normalizedKey] = $v;
unset($value[$k]);
$normalized[$normalizedKey] = $v;
} else {
$normalized[$k] = $v;
}
}
return $value;
return $normalized;
}
/**

View File

@ -74,6 +74,10 @@ class ArrayNodeTest extends \PHPUnit_Framework_TestCase
array('foo-bar_moo' => 'foo'),
array('foo-bar_moo' => 'foo'),
),
array(
array('anything-with-dash-and-no-underscore' => 'first', 'no_dash' => 'second'),
array('anything_with_dash_and_no_underscore' => 'first', 'no_dash' => 'second'),
),
array(
array('foo-bar' => null, 'foo_bar' => 'foo'),
array('foo-bar' => null, 'foo_bar' => 'foo'),

View File

@ -94,8 +94,13 @@ class FlattenException extends LegacyFlattenException
$e->setClass(get_class($exception));
$e->setFile($exception->getFile());
$e->setLine($exception->getLine());
if ($exception->getPrevious()) {
$e->setPrevious(static::create($exception->getPrevious()));
$previous = $exception->getPrevious();
if ($previous instanceof \Exception) {
$e->setPrevious(static::create($previous));
} elseif ($previous instanceof \Throwable) {
$e->setPrevious(static::create(new FatalThrowableError($previous)));
}
return $e;

View File

@ -131,6 +131,20 @@ class FlattenExceptionTest extends \PHPUnit_Framework_TestCase
$this->assertSame(array($flattened2), $flattened->getAllPrevious());
}
/**
* @requires PHP 7.0
*/
public function testPreviousError()
{
$exception = new \Exception('test', 123, new \ParseError('Oh noes!', 42));
$flattened = FlattenException::create($exception)->getPrevious();
$this->assertEquals($flattened->getMessage(), 'Parse error: Oh noes!', 'The message is copied from the original exception.');
$this->assertEquals($flattened->getCode(), 42, 'The code is copied from the original exception.');
$this->assertEquals($flattened->getClass(), 'Symfony\Component\Debug\Exception\FatalThrowableError', 'The class is set to the class of the original exception');
}
/**
* @dataProvider flattenDataProvider
*/

View File

@ -23,12 +23,12 @@ interface ExtensionInterface
/**
* Loads a specific configuration.
*
* @param array $config An array of configuration values
* @param array $configs An array of configuration values
* @param ContainerBuilder $container A ContainerBuilder instance
*
* @throws \InvalidArgumentException When provided tag is not defined in this extension
*/
public function load(array $config, ContainerBuilder $container);
public function load(array $configs, ContainerBuilder $container);
/**
* Returns the namespace to be used for this extension (XML namespace).

View File

@ -1,186 +1,318 @@
<?xml version="1.0"?>
<?xml version="1.0"?>
<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
<file source-language="en" datatype="plaintext" original="file.ext">
<body>
<trans-unit id="1">
<source>This value should be false.</source>
<target>Արժեքը պետք է լինի կեղծ.</target>
<target>Արժեքը պետք է լինի սխալ։</target>
</trans-unit>
<trans-unit id="2">
<source>This value should be true.</source>
<target>Արժեքը պետք է լինի ճշմարիտ.</target>
<target>Արժեքը պետք է լինի ճիշտ։</target>
</trans-unit>
<trans-unit id="3">
<source>This value should be of type {{ type }}.</source>
<target>Արժեքը պետք է լինի {{ type }} տեսակի.</target>
<target>Արժեքը պետք է լինի {{ type }} տեսակի։</target>
</trans-unit>
<trans-unit id="4">
<source>This value should be blank.</source>
<target>Արժեքը պետք է լինի դատարկ.</target>
<target>Արժեքը պետք է լինի դատարկ։</target>
</trans-unit>
<trans-unit id="5">
<source>The value you selected is not a valid choice.</source>
<target>Ձեր ընտրած արժեքը անթույլատրելի է.</target>
<target>Ձեր ընտրած արժեքը անվավեր ընտրություն է։</target>
</trans-unit>
<trans-unit id="6">
<source>You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices.</source>
<target>Դուք պետք է ընտրեք ամենաքիչը {{ limit }} տարբերակներ.</target>
<target>Դուք պետք է ընտրեք ամենաքիչը {{ limit }} տարբերակներ։</target>
</trans-unit>
<trans-unit id="7">
<source>You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices.</source>
<target>Դուք պետք է ընտրեք ոչ ավելի քան {{ limit }} տարբերակներ.</target>
<target>Դուք պետք է ընտրեք ոչ ավելի քան {{ limit }} տարբերակներ։</target>
</trans-unit>
<trans-unit id="8">
<source>One or more of the given values is invalid.</source>
<target>Մեկ կամ ավելի տրված արժեքները անթույլատրելի են.</target>
<target>Մեկ կամ ավելի տրված արժեքները անվավեր են։</target>
</trans-unit>
<trans-unit id="9">
<source>This field was not expected.</source>
<target>Այս դաշտը չի սպասվում.</target>
<target>Այս դաշտը չի սպասվում։</target>
</trans-unit>
<trans-unit id="10">
<source>This field is missing.</source>
<target>Այս դաշտը բացակայում է.</target>
<target>Այս դաշտը բացակայում է։</target>
</trans-unit>
<trans-unit id="11">
<source>This value is not a valid date.</source>
<target>Արժեքը սխալ ամսաթիվ է.</target>
<target>Արժեքը սխալ ամսաթիվ է։</target>
</trans-unit>
<trans-unit id="12">
<source>This value is not a valid datetime.</source>
<target>Ամսաթվի և ժամանակի արժեքը անթույլատրելի է.</target>
<target>Ամսաթվի և ժամանակի արժեքը անվավեր է։</target>
</trans-unit>
<trans-unit id="13">
<source>This value is not a valid email address.</source>
<target>Էլ-փոստի արժեքը անթույլատրելի է.</target>
<target>Անվավեր էլ֊փոստի արժեք։</target>
</trans-unit>
<trans-unit id="14">
<source>The file could not be found.</source>
<target>Ֆայլը չի գտնվել.</target>
<target>Նիշքը չի գտնվել։</target>
</trans-unit>
<trans-unit id="15">
<source>The file is not readable.</source>
<target>Ֆայլը անընթեռնելի է.</target>
<target>Նիշքը անընթեռնելի է։</target>
</trans-unit>
<trans-unit id="16">
<source>The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}.</source>
<target>Ֆայլը չափազանց մեծ է ({{ size }} {{ suffix }}): Մաքսիմալ թույլատրելի չափսը՝ {{ limit }} {{ suffix }}.</target>
<target>Նիշքը չափազանց մեծ է ({{ size }} {{ suffix }}): Մաքսիմալ թույլատրելի չափսը՝ {{ limit }} {{ suffix }}։</target>
</trans-unit>
<trans-unit id="17">
<source>The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}.</source>
<target>MIME-տեսակը անթույլատրելի է({{ type }}): Ֆայլերի թույլատրելի MIME-տեսակներն են: {{ types }}.</target>
<target>MIME-տեսակը անվավեր է է({{ type }}): Նիշքերի թույլատրելի MIME-տեսակներն են: {{ types }}։</target>
</trans-unit>
<trans-unit id="18">
<source>This value should be {{ limit }} or less.</source>
<target>Արժեքը պետք է լինի {{ limit }} կամ փոքր.</target>
<target>Արժեքը պետք է լինի {{ limit }} կամ փոքր։</target>
</trans-unit>
<trans-unit id="19">
<source>This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less.</source>
<target>Արժեքը չափազանց երկար է: Պետք է լինի {{ limit }} կամ ավել սիմվոլներ.</target>
<target>Արժեքը չափազանց երկար է: Պետք է լինի {{ limit }} կամ ավել սիմվոլներ։</target>
</trans-unit>
<trans-unit id="20">
<source>This value should be {{ limit }} or more.</source>
<target>Արժեքը պետ է լինի {{ limit }} կամ շատ.</target>
<target>Արժեքը պետ է լինի {{ limit }} կամ շատ։</target>
</trans-unit>
<trans-unit id="21">
<source>This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more.</source>
<target>Արժեքը չափազանց կարճ է: Պետք է լինի {{ limit }} կամ ավելի սիմվոլներ.</target>
<target>Արժեքը չափազանց կարճ է: Պետք է լինի {{ limit }} կամ ավելի սիմվոլներ։</target>
</trans-unit>
<trans-unit id="22">
<source>This value should not be blank.</source>
<target>Արժեքը չպետք է դատարկ լինի.</target>
<target>Արժեքը չպետք է դատարկ լինի։</target>
</trans-unit>
<trans-unit id="23">
<source>This value should not be null.</source>
<target>Արժեքը չպետք է լինի null.</target>
<target>Արժեքը չպետք է լինի null։</target>
</trans-unit>
<trans-unit id="24">
<source>This value should be null.</source>
<target>Արժեքը պետք է լինի null.</target>
<target>Արժեքը պետք է լինի null։</target>
</trans-unit>
<trans-unit id="25">
<source>This value is not valid.</source>
<target>Անթույլատրելի արժեք.</target>
<target>Անվավեր արժեք։</target>
</trans-unit>
<trans-unit id="26">
<source>This value is not a valid time.</source>
<target>Ժամանակի արժեքը անթույլատրելի է.</target>
<target>Ժամանակի արժեքը անվավեր է։</target>
</trans-unit>
<trans-unit id="27">
<source>This value is not a valid URL.</source>
<target>Արժեքը URL չէ.</target>
<target>Արժեքը URL չէ։</target>
</trans-unit>
<trans-unit id="31">
<source>The two values should be equal.</source>
<target>Երկու արժեքները պետք է նույնը լինեն.</target>
<target>Երկու արժեքները պետք է նույնը լինեն։</target>
</trans-unit>
<trans-unit id="32">
<source>The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}.</source>
<target>Ֆայլը չափազանց մեծ է: Մաքսիմալ թույլատրելի չափսը {{ limit }} {{ suffix }} է.</target>
<target>Նիշքը չափազանց մեծ է: Մաքսիմալ թույլատրելի չափսը {{ limit }} {{ suffix }} է։</target>
</trans-unit>
<trans-unit id="33">
<source>The file is too large.</source>
<target>Ֆայլը չափազանց մեծ է.</target>
<target>Նիշքը չափազանց մեծ է։</target>
</trans-unit>
<trans-unit id="34">
<source>The file could not be uploaded.</source>
<target>Ֆայլը չի կարող բեռնվել.</target>
<target>Նիշքը չի կարող բեռնվել։</target>
</trans-unit>
<trans-unit id="35">
<source>This value should be a valid number.</source>
<target>Արժեքը պետք է լինի թիվ.</target>
<target>Արժեքը պետք է լինի թիվ։</target>
</trans-unit>
<trans-unit id="36">
<source>This value is not a valid country.</source>
<target>Արժեքը պետք է լինի երկիր.</target>
<target>Արժեքը պետք է լինի երկիր։</target>
</trans-unit>
<trans-unit id="37">
<source>This file is not a valid image.</source>
<target>Ֆայլը նկարի թույլատրելի ֆորմատ չէ.</target>
<target>Նիշքը նկարի վավեր ֆորմատ չէ։</target>
</trans-unit>
<trans-unit id="38">
<source>This is not a valid IP address.</source>
<target>Արժեքը թույլատրելի IP հասցե չէ.</target>
<target>Արժեքը վավեր IP հասցե չէ։</target>
</trans-unit>
<trans-unit id="39">
<source>This value is not a valid language.</source>
<target>Արժեքը թույլատրելի լեզու չէ.</target>
<target>Արժեքը վավեր լեզու չէ։</target>
</trans-unit>
<trans-unit id="40">
<source>This value is not a valid locale.</source>
<target>Արժեքը չի հանդիսանում թույլատրելի տեղայնացում.</target>
<target>Արժեքը չի հանդիսանում վավեր տեղայնացում։</target>
</trans-unit>
<trans-unit id="41">
<source>This value is already used.</source>
<target>Այդ արժեքը արդեն օգտագործվում է.</target>
<target>Այդ արժեքն արդեն օգտագործվում է։</target>
</trans-unit>
<trans-unit id="42">
<source>The size of the image could not be detected.</source>
<target>Նկարի չափսերը չստացվեց որոշել.</target>
<target>Նկարի չափսերը չստացվեց որոշել։</target>
</trans-unit>
<trans-unit id="43">
<source>The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px.</source>
<target>Նկարի լայնությունը չափազանց մեծ է({{ width }}px). Մաքսիմալ չափն է {{ max_width }}px.</target>
<target>Նկարի լայնությունը չափազանց մեծ է({{ width }}px). Մաքսիմալ չափն է {{ max_width }}px։</target>
</trans-unit>
<trans-unit id="44">
<source>The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px.</source>
<target>Նկարի լայնությունը չափազանց փոքր է ({{ width }}px). Մինիմալ չափն է {{ min_ width }}px.</target>
<target>Նկարի լայնությունը չափազանց փոքր է ({{ width }}px). Մինիմալ չափն է {{ min_ width }}px։</target>
</trans-unit>
<trans-unit id="45">
<source>The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px.</source>
<target>Նկարի բարձրությունը չափազանց մեծ է ({{ height }}px). Մաքսիմալ չափն է {{ max_height }}px.</target>
<target>Նկարի բարձրությունը չափազանց մեծ է ({{ height }}px). Մաքսիմալ չափն է {{ max_height }}px։</target>
</trans-unit>
<trans-unit id="46">
<source>The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px.</source>
<target>Նկարի բարձրությունը չափազանց փոքր է ({{ height }}px). Մինիմալ չափն է {{ min_height }}px.</target>
<target>Նկարի բարձրությունը չափազանց փոքր է ({{ height }}px). Մինիմալ չափն է {{ min_height }}px։</target>
</trans-unit>
<trans-unit id="47">
<source>This value should be the user's current password.</source>
<target>Այս արժեքը պետք է լինի օգտագործողի ներկա ծածկագիրը.</target>
<target>Այս արժեքը պետք է լինի օգտագործողի ներկա ծածկագիրը։</target>
</trans-unit>
<trans-unit id="48">
<source>This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters.</source>
<target>Այս արժեքը պետք է ունենա ճիշտ {{ limit }} սիմվոլներ.</target>
<target>Այս արժեքը պետք է ունենա ճիշտ {{ limit }} սիմվոլներ։</target>
</trans-unit>
<trans-unit id="49">
<source>The file was only partially uploaded.</source>
<target>Նիշքի մասնակի բեռնման սխալ։</target>
</trans-unit>
<trans-unit id="50">
<source>No file was uploaded.</source>
<target>Նիշքը չի բեռնվել։</target>
</trans-unit>
<trans-unit id="51">
<source>No temporary folder was configured in php.ini.</source>
<target>php.ini նիշքում ժամանակավոր պանակ նշված չէ։</target>
</trans-unit>
<trans-unit id="52">
<source>Cannot write temporary file to disk.</source>
<target>Ժամանակավոր նիշքը հնարավոր չէ գրել սկավառակի վրա։</target>
</trans-unit>
<trans-unit id="53">
<source>A PHP extension caused the upload to fail.</source>
<target>PHP ֆորմատը դարձել է բեռնման չհաջողման պատճառ։</target>
</trans-unit>
<trans-unit id="54">
<source>This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more.</source>
<target>Այս հավաքածուն պետք է պաուրակի {{ limit }} կամ ավելի տարրեր։|Այս հավելվածը պետք է պարունակի limit }} տարր կամ ավելին։|Այս հավաքածուն պետք է պարունակի {{ limit }} տարրերին կամ ավելի։</target>
</trans-unit>
<trans-unit id="55">
<source>This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less.</source>
<target>Այս հավաքածուն պետք է պաուրակի {{ limit }} տարրեր կամ քիչ։|Այս հավաքածուն պետք է պաուրակի {{ limit }} տարր կամ քիչ։|Այս հավաքածուն պետք է պաուրակի {{ limit }} տարրեր կամ քիչ։</target>
</trans-unit>
<trans-unit id="56">
<source>This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements.</source>
<target>Այս հավաքածուն պետք է պաուրակի ուղիղ {{ limit }} տարր։|Այս հավաքածուն պետք է պաուրակի ուղիղ {{ limit }} տարրեր։|Այս հավաքածուն պետք է պաուրակի {{ limit }} տարրեր։</target>
</trans-unit>
<trans-unit id="57">
<source>Invalid card number.</source>
<target>Քարտի սխալ համար:</target>
</trans-unit>
<trans-unit id="58">
<source>Unsupported card type or invalid card number.</source>
<target>Չսպասարկվող կամ սխալ քարտի համար:</target>
</trans-unit>
<trans-unit id="59">
<source>This is not a valid International Bank Account Number (IBAN).</source>
<target>Արժեքը վավեր միջազային բանկային հաշվի համար չէ (IBAN)։</target>
</trans-unit>
<trans-unit id="60">
<source>This value is not a valid ISBN-10.</source>
<target>Արժեքը ունի անվավեր ISBN-10 ձևաչափ։</target>
</trans-unit>
<trans-unit id="61">
<source>This value is not a valid ISBN-13.</source>
<target>Արժեքը ունի անվավեր ISBN-13 ձևաչափ։</target>
</trans-unit>
<trans-unit id="62">
<source>This value is neither a valid ISBN-10 nor a valid ISBN-13.</source>
<target>Արժեքը չի համապատասխանում ISBN-10 և ISBN-13 ձևաչափերին։</target>
</trans-unit>
<trans-unit id="63">
<source>This value is not a valid ISSN.</source>
<target>Արժեքը չի համապաստասխանում ISSN ձևաչափին։</target>
</trans-unit>
<trans-unit id="64">
<source>This value is not a valid currency.</source>
<target>Արժեքը վավեր տարադրամ չէ։</target>
</trans-unit>
<trans-unit id="65">
<source>This value should be equal to {{ compared_value }}.</source>
<target>Արժեքը պետք է լինի {{ compared_value }}։</target>
</trans-unit>
<trans-unit id="66">
<source>This value should be greater than {{ compared_value }}.</source>
<target>Արժեքը պետք է մեծ լինի, քան {{ compared_value }}։</target>
</trans-unit>
<trans-unit id="67">
<source>This value should be greater than or equal to {{ compared_value }}.</source>
<target>Արժեքը պետք է լինի հավասար կամ մեծ քան {{ compared_value }}։</target>
</trans-unit>
<trans-unit id="68">
<source>This value should be identical to {{ compared_value_type }} {{ compared_value }}.</source>
<target>Արժեքը պետք է լինի ինչպես {{ compared_value_type }} {{ compared_value }}։</target>
</trans-unit>
<trans-unit id="69">
<source>This value should be less than {{ compared_value }}.</source>
<target>Արժեքը պետք է լինի փոքր քան {{ compared_value }}։</target>
</trans-unit>
<trans-unit id="70">
<source>This value should be less than or equal to {{ compared_value }}.</source>
<target>Արժեքը պետք է լինի փոքր կամ հավասար {{ compared_value }}։</target>
</trans-unit>
<trans-unit id="71">
<source>This value should not be equal to {{ compared_value }}.</source>
<target>Արժեքը պետք է լինի հավասար {{ compared_value }}։</target>
</trans-unit>
<trans-unit id="72">
<source>This value should not be identical to {{ compared_value_type }} {{ compared_value }}.</source>
<target>Արժեքը պետք է լինի նունը {{ compared_value_type }} {{ compared_value }}:</target>
</trans-unit>
<trans-unit id="73">
<source>The image ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}.</source>
<target>Պատկերի կողմերի հարաբերակցությունը խիստ մեծ է ({{ ratio }}). Մաքսիմալ հարաբերակցությունը՝ {{ max_ratio }}։</target>
</trans-unit>
<trans-unit id="74">
<source>The image ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}.</source>
<target>Պատկերի կողմերի հարաբերակցությունը խիստ փոքր է ({{ ratio }}). Մինիմալ հարաբերակցությունը՝ {{ min_ratio }}։</target>
</trans-unit>
<trans-unit id="75">
<source>The image is square ({{ width }}x{{ height }}px). Square images are not allowed.</source>
<target>Պատկերը քառակուսի է({{ width }}x{{ height }}px)։ Քառակուսի նկարներ չեն թույլատրվում։</target>
</trans-unit>
<trans-unit id="76">
<source>The image is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented images are not allowed.</source>
<target>Պատկերը ալբոմային ուղղվածության է({{ width }}x{{ height }}px) դա չի թույլատրվում։</target>
</trans-unit>
<trans-unit id="77">
<source>The image is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented images are not allowed.</source>
<target>Պատկերը պորտրետային ուղղվածության է ({{ width }}x{{ height }}px) դա չի թույլատրվում։</target>
</trans-unit>
<trans-unit id="78">
<source>An empty file is not allowed.</source>
<target>Դատարկ նիշք չի թույլատրվում։</target>
</trans-unit>
<trans-unit id="79">
<source>The host could not be resolved.</source>
<target>Հոսթի անունը հնարավոր չի պարզել:</target>
</trans-unit>
<trans-unit id="80">
<source>This value does not match the expected {{ charset }} charset.</source>
<target>Արժեքը չի համընկնում {{ charset }} կոդավորման հետ:</target>
</trans-unit>
<trans-unit id="81">
<source>This is not a valid Business Identifier Code (BIC).</source>
<target>Սա վավեր Business Identifier Code (BIC) չէ։</target>
</trans-unit>
</body>
</file>

View File

@ -509,13 +509,13 @@ class Parser
}
$isCurrentLineBlank = $this->isCurrentLineBlank();
$text = '';
$blockLines = array();
// leading blank lines are consumed before determining indentation
while ($notEOF && $isCurrentLineBlank) {
// newline only if not EOF
if ($notEOF = $this->moveToNextLine()) {
$text .= "\n";
$blockLines[] = '';
$isCurrentLineBlank = $this->isCurrentLineBlank();
}
}
@ -536,37 +536,59 @@ class Parser
preg_match($pattern, $this->currentLine, $matches)
)
) {
if ($isCurrentLineBlank) {
$text .= substr($this->currentLine, $indentation);
if ($isCurrentLineBlank && strlen($this->currentLine) > $indentation) {
$blockLines[] = substr($this->currentLine, $indentation);
} elseif ($isCurrentLineBlank) {
$blockLines[] = '';
} else {
$text .= $matches[1];
$blockLines[] = $matches[1];
}
// newline only if not EOF
if ($notEOF = $this->moveToNextLine()) {
$text .= "\n";
$isCurrentLineBlank = $this->isCurrentLineBlank();
}
}
} elseif ($notEOF) {
$text .= "\n";
$blockLines[] = '';
}
if ($notEOF) {
$blockLines[] = '';
$this->moveToPreviousLine();
}
// folded style
if ('>' === $style) {
// folded lines
// replace all non-leading/non-trailing single newlines with spaces
preg_match('/(\n*)$/', $text, $matches);
$text = preg_replace('/(?<!\n|^)\n(?!\n)/', ' ', rtrim($text, "\n"));
$text .= $matches[1];
$text = '';
$previousLineIndented = false;
$previousLineBlank = false;
// empty separation lines
// remove one newline from each group of non-leading/non-trailing newlines
$text = preg_replace('/[^\n]\n+\K\n(?=[^\n])/', '', $text);
for ($i = 0; $i < count($blockLines); $i++) {
if ('' === $blockLines[$i]) {
$text .= "\n";
$previousLineIndented = false;
$previousLineBlank = true;
} elseif (' ' === $blockLines[$i][0]) {
$text .= "\n".$blockLines[$i];
$previousLineIndented = true;
$previousLineBlank = false;
} elseif ($previousLineIndented) {
$text .= "\n".$blockLines[$i];
$previousLineIndented = false;
$previousLineBlank = false;
} elseif ($previousLineBlank || 0 === $i) {
$text .= $blockLines[$i];
$previousLineIndented = false;
$previousLineBlank = false;
} else {
$text .= ' '.$blockLines[$i];
$previousLineIndented = false;
$previousLineBlank = false;
}
}
} else {
$text = implode("\n", $blockLines);
}
// deal with trailing newlines

View File

@ -899,6 +899,57 @@ EOT
array($yaml2, $expected2),
);
}
public function testBlankLinesAreParsedAsNewLinesInFoldedBlocks()
{
$yaml = <<<EOT
test: >
<h2>A heading</h2>
<ul>
<li>a list</li>
<li>may be a good example</li>
</ul>
EOT;
$this->assertSame(
array(
'test' => <<<EOT
<h2>A heading</h2>
<ul> <li>a list</li> <li>may be a good example</li> </ul>
EOT
,
),
$this->parser->parse($yaml)
);
}
public function testAdditionallyIndentedLinesAreParsedAsNewLinesInFoldedBlocks()
{
$yaml = <<<EOT
test: >
<h2>A heading</h2>
<ul>
<li>a list</li>
<li>may be a good example</li>
</ul>
EOT;
$this->assertSame(
array(
'test' => <<<EOT
<h2>A heading</h2>
<ul>
<li>a list</li>
<li>may be a good example</li>
</ul>
EOT
,
),
$this->parser->parse($yaml)
);
}
}
class B