Merge branch '2.3' into 2.4

* 2.3: (31 commits)
  Fix parent serialization of user object
  [DependencyInjection] fixed typo
  add memcache, memcached, and mongodb extensions to run skipped tests
  [DependencyInjection] Fixed support for backslashes in service ids.
  fix #9356 [Security] Logger should manipulate the user reloaded from provider
  [BrowserKit] fixes #8311 CookieJar is totally ignorant of RFC 6265 edge cases
  [HttpFoundation] fixed constants that do exist in 2.3 (only in 2.4)
  fix 5528 let ArrayNode::normalizeValue respect order of value array provided
  fix #7243 allow 0 as arraynode name
  Fixed issue in BaseDateTimeTransformer when invalid timezone cause Transformation filed exception (closes #9403).
  BinaryFileResponse should also return 416 or 200 on some range-requets
  Do normalization on tag options
  bumped Symfony version to 2.3.9
  updated VERSION for 2.3.8
  update CONTRIBUTORS for 2.3.8
  updated CHANGELOG for 2.3.8
  [Filesystem] Changed the mode for a target file in copy() to be write only.
  [Console] fixed CS
  fixed TableHelper when cell value has new line
  Improved and fixed grammar mistakes. Added pluralized messages
  ...

Conflicts:
	src/Symfony/Component/BrowserKit/Cookie.php
	src/Symfony/Component/HttpKernel/Kernel.php
	src/Symfony/Component/Routing/Matcher/UrlMatcher.php
This commit is contained in:
Fabien Potencier 2013-12-26 08:59:03 +01:00
commit ef3ae9cf45
49 changed files with 885 additions and 137 deletions

View File

@ -6,10 +6,15 @@ php:
- 5.4
- 5.5
services: mongodb
before_script:
- sudo apt-get install parallel
- echo '' > ~/.phpenv/versions/$(phpenv version-name)/etc/conf.d/xdebug.ini
- echo "extension = mongo.so" >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini
- sh -c 'if [ $(php -r "echo PHP_MINOR_VERSION;") -le 4 ]; then echo "extension = apc.so" >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini; fi;'
- echo "extension = memcached.so" >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini
- echo "extension = memcache.so" >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini
- COMPOSER_ROOT_VERSION=dev-master composer --prefer-source --dev install
script:

View File

@ -7,6 +7,39 @@ in 2.3 minor versions.
To get the diff for a specific change, go to https://github.com/symfony/symfony/commit/XXX where XXX is the change hash
To get the diff between two versions, go to https://github.com/symfony/symfony/compare/v2.3.0...v2.3.1
* 2.3.8 (2013-12-16)
* bug #9758 [Console] fixed TableHelper when cell value has new line (k-przybyszewski)
* bug #9760 [Routing] Fix router matching pattern against multiple hosts (karolsojko)
* bug #9674 [Form] rename validators.ua.xlf to validators.uk.xlf (craue)
* bug #9722 [Validator]Fixed getting wrong msg when value is an object in Exception (aitboudad)
* bug #9750 allow TraceableEventDispatcher to reuse event instance in nested events (evillemez)
* bug #9718 [validator] throw an exception if isn't an instance of ConstraintValidatorInterface. (aitboudad)
* bug #9716 Reset the box model to content-box in the web debug toolbar (stof)
* bug #9711 [FrameworkBundle] Allowed "0" as a checkbox value in php templates (jakzal)
* bug #9665 [Bridge/Doctrine] ORMQueryBuilderLoader - handled the scenario when no entity manager is passed with closure query builder (jakzal)
* bug #9656 [DoctrineBridge] normalized class names in the ORM type guesser (fabpot)
* bug #9647 use the correct class name to retrieve mapped class' metadata and reposi... (xabbuh)
* bug #9648 [Debug] ensured that a fatal PHP error is actually fatal after being handled by our error handler (fabpot)
* bug #9643 [WebProfilerBundle] Fixed js escaping in time.html.twig (hason)
* bug #9641 [Debug] Avoid notice from being "eaten" by fatal error. (fabpot)
* bug #9639 Modified guessDefaultEscapingStrategy to not escape txt templates (fabpot)
* bug #9314 [Form] Fix DateType for 32bits computers. (WedgeSama)
* bug #9443 [FrameworkBundle] Fixed the registration of validation.xml file when the form is disabled (hason)
* bug #9625 [HttpFoundation] Do not return an empty session id if the session was closed (Taluu)
* bug #9637 [Validator] Replaced inexistent interface (jakzal)
* bug #9605 Adjusting CacheClear Warmup method to namespaced kernels (rdohms)
* bug #9610 Container::camelize also takes backslashes into consideration (ondrejmirtes)
* bug #9447 [BrowserKit] fixed protocol-relative url redirection (jong99)
* bug #9535 No Entity Manager defined exception (armetiz)
* bug #9485 [Acl] Fix for issue #9433 (guilro)
* bug #9516 [AclProvider] Fix incorrect behavior when partial results returned from cache (superdav42)
* bug #9352 [Intl] make currency bundle merge fallback locales when accessing data, ... (shieldo)
* bug #9537 [FrameworkBundle] Fix mistake in translation's service definition. (phpmike)
* bug #9367 [Process] Check if the pipe array is empty before calling stream_select() (jfposton)
* bug #9211 [Form] Fixed memory leak in FormValidator (bschussek)
* bug #9469 [Propel1] re-factor Propel1 ModelChoiceList (havvg)
* 2.3.7 (2013-11-14)
* bug #9499 Request::overrideGlobals() may call invalid ini value (denkiryokuhatsuden)

View File

@ -58,8 +58,8 @@ Symfony2 is the result of the work of many people who made the code better
- Bart van den Burg (burgov)
- Antoine Hérault (herzult)
- Toni Uebernickel (havvg)
- Michel Weimerskirch (mweimerskirch)
- Christian Raue
- Michel Weimerskirch (mweimerskirch)
- Arnaud Le Blanc (arnaud-lb)
- marc.weistroff
- Brice BERNARD (brikou)
@ -68,10 +68,10 @@ Symfony2 is the result of the work of many people who made the code better
- Włodzimierz Gajda (gajdaw)
- Colin Frei
- excelwebzone
- Wouter De Jong (wouterj)
- Kevin Bond (kbond)
- Fabien Pennequin (fabienpennequin)
- Jacob Dreesen (jdreesen)
- Wouter De Jong (wouterj)
- Adrien Brault (adrienbrault)
- Michal Piotrowski (eventhorizon)
- Robert Schönthal (digitalkaoz)
@ -94,6 +94,7 @@ Symfony2 is the result of the work of many people who made the code better
- Amal Raghav (kertz)
- Jonathan Ingram (jonathaningram)
- Artur Kotyrba
- Ait Boudad Abdellatif (aitboudad)
- Pablo Godel (pgodel)
- Sebastiaan Stok (sstok)
- Dmitrii Chekaliuk (lazyhammer)
@ -113,7 +114,6 @@ Symfony2 is the result of the work of many people who made the code better
- Guilherme Blanco (guilhermeblanco)
- Martin Schuhfuß (usefulthink)
- Thomas Rabaix (rande)
- Ait Boudad Abdellatif (aitboudad)
- Matthieu Bontemps (mbontemps)
- Pierre Minnieur (pminnieur)
- fivestar
@ -141,6 +141,7 @@ Symfony2 is the result of the work of many people who made the code better
- Alif Rachmawadi
- Joseph Rouff (rouffj)
- Félix Labrecque (woodspire)
- Christian Flothmann (xabbuh)
- GordonsLondon
- Jan Sorgalla (jsor)
- Ray
@ -160,8 +161,8 @@ Symfony2 is the result of the work of many people who made the code better
- Florian Klein (docteurklein)
- Matthias Pigulla (mpdude)
- Manuel Kiessling (manuelkiessling)
- Christian Flothmann (xabbuh)
- Bertrand Zuchuat (garfield-fr)
- Gabor Toth (tgabi333)
- Thomas Tourlourat (armetiz)
- Andrey Esaulov (andremaha)
- Grégoire Passault (gregwar)
@ -169,6 +170,7 @@ Symfony2 is the result of the work of many people who made the code better
- Aurelijus Valeiša (aurelijus)
- Gustavo Piltcher
- Stepan Tanasiychuk (stfalcon)
- Luis Cordova (cordoval)
- Bob den Otter (bopp)
- Adrian Rudnik (kreischweide)
- Francesc Rosàs (frosas)
@ -182,6 +184,7 @@ Symfony2 is the result of the work of many people who made the code better
- Vitaliy Zakharov (zakharovvi)
- Gyula Sallai (salla)
- Michele Orselli (orso)
- Christian Gärtner (dagardner)
- Tom Van Looy (tvlooy)
- Peter Kruithof (pkruithof)
- Felix Labrecque
@ -196,7 +199,6 @@ Symfony2 is the result of the work of many people who made the code better
- Atsuhiro KUBO (iteman)
- sun (sun)
- Lars Strojny
- Gabor Toth (tgabi333)
- Costin Bereveanu (schniper)
- realmfoo
- Tamas Szijarto
@ -209,7 +211,6 @@ Symfony2 is the result of the work of many people who made the code better
- Kai
- Xavier HAUSHERR
- Albert Jessurum (ajessu)
- Luis Cordova (cordoval)
- Laszlo Korte
- Tiago Ribeiro (fixe)
- Alessandro Desantis
@ -235,7 +236,6 @@ Symfony2 is the result of the work of many people who made the code better
- Olivier Dolbeau (odolbeau)
- alquerci
- vagrant
- Christian Gärtner (dagardner)
- Asier Illarramendi (doup)
- Christoph Mewes (xrstf)
- Vitaliy Tverdokhlib (vitaliytv)
@ -276,6 +276,7 @@ Symfony2 is the result of the work of many people who made the code better
- sasezaki
- Denis Gorbachev (starfall)
- Steven Surowiec
- giulio de donato (liuggio)
- Marek Kalnik (marekkalnik)
- Chris Smith
- Anthon Pang
@ -406,7 +407,6 @@ Symfony2 is the result of the work of many people who made the code better
- Timothée Barray (tyx)
- Christian Morgan
- Alexander Miehe (engerim)
- giulio de donato (liuggio)
- Titouan Galopin (tgalopin)
- Don Pinkster
- Maksim Muruev
@ -419,6 +419,7 @@ Symfony2 is the result of the work of many people who made the code better
- Arno Geurts
- Adán Lobato (adanlobato)
- Maks
- Gábor Tóth
- Daniel Cestari
- Magnus Nordlander (magnusnordlander)
- Mikhail Yurasov (mym)
@ -575,6 +576,7 @@ Symfony2 is the result of the work of many people who made the code better
- Rick Prent
- Martin Eckhardt
- Michael Dowling (mtdowling)
- Nicolas Grekas (nicolas-grekas)
- BilgeXA
- Robert Queck
- mlively
@ -746,6 +748,7 @@ Symfony2 is the result of the work of many people who made the code better
- Yorkie Chadwick (yorkie76)
- Yanick Witschi
- Ondrej Mirtes
- Youpie
- srsbiz
- Nicolas A. Bérard-Nault
- Gladhon
@ -791,7 +794,6 @@ Symfony2 is the result of the work of many people who made the code better
- Kaipi Yann
- Sam Williams
- James Michael DuPont
- Gábor Tóth
- Tammy D
- Ondrej Slinták
- vlechemin
@ -800,8 +802,10 @@ Symfony2 is the result of the work of many people who made the code better
- mieszko4
- datibbaw
- Norbert Orzechowicz
- Markus Staab
- Pierre-Louis LAUNAY
- djama
- Eduardo Conceição
- Jon Cave
- Sébastien HOUZE
- Abdulkadir N. A.

View File

@ -38,7 +38,7 @@ class RedirectableUrlMatcherTest extends \PHPUnit_Framework_TestCase
);
}
public function testSchemeRedirect()
public function testSchemeRedirectBC()
{
$coll = new RouteCollection();
$coll->add('foo', new Route('/foo', array(), array('_scheme' => 'https')));
@ -57,4 +57,24 @@ class RedirectableUrlMatcherTest extends \PHPUnit_Framework_TestCase
$matcher->match('/foo')
);
}
public function testSchemeRedirect()
{
$coll = new RouteCollection();
$coll->add('foo', new Route('/foo', array(), array(), array(), '', array('https')));
$matcher = new RedirectableUrlMatcher($coll, $context = new RequestContext());
$this->assertEquals(array(
'_controller' => 'Symfony\Bundle\FrameworkBundle\Controller\RedirectController::urlRedirectAction',
'path' => '/foo',
'permanent' => true,
'scheme' => 'https',
'httpPort' => $context->getHttpPort(),
'httpsPort' => $context->getHttpsPort(),
'_route' => 'foo',
),
$matcher->match('/foo')
);
}
}

View File

@ -127,7 +127,7 @@ class Cookie
$parts = explode(';', $cookie);
if (false === strpos($parts[0], '=')) {
throw new \InvalidArgumentException(sprintf('The cookie string "%s" is not valid.', $cookie));
throw new \InvalidArgumentException(sprintf('The cookie string "%s" is not valid.', $parts[0]));
}
list($name, $value) = explode('=', array_shift($parts), 2);

View File

@ -55,7 +55,25 @@ class CookieJar
$this->flushExpiredCookies();
if (!empty($domain)) {
return isset($this->cookieJar[$domain][$path][$name]) ? $this->cookieJar[$domain][$path][$name] : null;
foreach ($this->cookieJar as $cookieDomain => $pathCookies) {
if ($cookieDomain) {
$cookieDomain = '.'.ltrim($cookieDomain, '.');
if ($cookieDomain != substr('.'.$domain, -strlen($cookieDomain))) {
continue;
}
}
foreach ($pathCookies as $cookiePath => $namedCookies) {
if ($cookiePath != substr($path, 0, strlen($cookiePath))) {
continue;
}
if (isset($namedCookies[$name])) {
return $namedCookies[$name];
}
}
}
return null;
}
// avoid relying on this behavior that is mainly here for BC reasons

View File

@ -196,6 +196,30 @@ class CookieJarTest extends \PHPUnit_Framework_TestCase
$this->assertEquals(array('foo' => 'bar2'), $cookieJar->allValues('http://bar.example.com/'));
}
public function testCookieGetWithSubdomain()
{
$cookieJar = new CookieJar();
$cookieJar->set($cookie1 = new Cookie('foo', 'bar', null, '/', '.example.com'));
$cookieJar->set($cookie2 = new Cookie('foo1', 'bar', null, '/', 'test.example.com'));
$this->assertEquals($cookie1, $cookieJar->get('foo','/','foo.example.com'));
$this->assertEquals($cookie1, $cookieJar->get('foo','/','example.com'));
$this->assertEquals($cookie2, $cookieJar->get('foo1','/','test.example.com'));
}
public function testCookieGetWithSubdirectory()
{
$cookieJar = new CookieJar();
$cookieJar->set($cookie1 = new Cookie('foo', 'bar', null, '/test', '.example.com'));
$cookieJar->set($cookie2 = new Cookie('foo1', 'bar1', null, '/', '.example.com'));
$this->assertNull($cookieJar->get('foo','/','.example.com'));
$this->assertNull($cookieJar->get('foo','/bar','.example.com'));
$this->assertEquals($cookie1, $cookieJar->get('foo','/test','example.com'));
$this->assertEquals($cookie2, $cookieJar->get('foo1','/','example.com'));
$this->assertEquals($cookie2, $cookieJar->get('foo1','/bar','example.com'));
}
public function testCookieWithWildcardDomain()
{
$cookieJar = new CookieJar();

View File

@ -200,7 +200,7 @@ class ArrayNode extends BaseNode implements PrototypeNodeInterface
public function addChild(NodeInterface $node)
{
$name = $node->getName();
if (empty($name)) {
if (!strlen($name)) {
throw new \InvalidArgumentException('Child nodes must be named.');
}
if (isset($this->children[$name])) {
@ -293,9 +293,9 @@ class ArrayNode extends BaseNode implements PrototypeNodeInterface
$value = $this->remapXml($value);
$normalized = array();
foreach ($this->children as $name => $child) {
if (array_key_exists($name, $value)) {
$normalized[$name] = $child->normalize($value[$name]);
foreach ($value as $name => $val) {
if (isset($this->children[$name])) {
$normalized[$name] = $this->children[$name]->normalize($val);
unset($value[$name]);
}
}

View File

@ -12,6 +12,8 @@
namespace Symfony\Component\Config\Tests\Definition;
use Symfony\Component\Config\Definition\ArrayNode;
use Symfony\Component\Config\Definition\ScalarNode;
use Symfony\Component\Serializer\Tests\Fixtures\ScalarDummy;
class ArrayNodeTest extends \PHPUnit_Framework_TestCase
{
@ -79,4 +81,81 @@ class ArrayNodeTest extends \PHPUnit_Framework_TestCase
)
);
}
/**
* @dataProvider getZeroNamedNodeExamplesData
*/
public function testNodeNameCanBeZero($denormalized, $normalized)
{
$zeroNode = new ArrayNode(0);
$zeroNode->addChild(new ScalarNode('name'));
$fiveNode = new ArrayNode(5);
$fiveNode->addChild(new ScalarNode(0));
$fiveNode->addChild(new ScalarNode('new_key'));
$rootNode = new ArrayNode('root');
$rootNode->addChild($zeroNode);
$rootNode->addChild($fiveNode);
$rootNode->addChild(new ScalarNode('string_key'));
$r = new \ReflectionMethod($rootNode, 'normalizeValue');
$r->setAccessible(true);
$this->assertSame($normalized, $r->invoke($rootNode, $denormalized));
}
public function getZeroNamedNodeExamplesData()
{
return array(
array(
array(
0 => array(
'name' => 'something',
),
5 => array(
0 => 'this won\'t work too',
'new_key' => 'some other value',
),
'string_key' => 'just value',
),
array(
0 => array (
'name' => 'something',
),
5 => array (
0 => 'this won\'t work too',
'new_key' => 'some other value',
),
'string_key' => 'just value',
),
),
);
}
/**
* @dataProvider getPreNormalizedNormalizedOrderedData
*/
public function testChildrenOrderIsMaintainedOnNormalizeValue($prenormalized, $normalized)
{
$scalar1 = new ScalarNode('1');
$scalar2 = new ScalarNode('2');
$scalar3 = new ScalarNode('3');
$node = new ArrayNode('foo');
$node->addChild($scalar1);
$node->addChild($scalar3);
$node->addChild($scalar2);
$r = new \ReflectionMethod($node, 'normalizeValue');
$r->setAccessible(true);
$this->assertSame($normalized, $r->invoke($node, $prenormalized));
}
public function getPreNormalizedNormalizedOrderedData()
{
return array(
array(
array('2' => 'two', '1' => 'one', '3' => 'three'),
array('2' => 'two', '1' => 'one', '3' => 'three'),
),
);
}
}

View File

@ -161,6 +161,29 @@ class TableHelper extends Helper
{
$this->rows[] = array_values($row);
$keys = array_keys($this->rows);
$rowKey = array_pop($keys);
foreach ($row as $key => $cellValue) {
if (!strstr($cellValue, "\n")) {
continue;
}
$lines = explode("\n", $cellValue);
$this->rows[$rowKey][$key] = $lines[0];
unset($lines[0]);
foreach ($lines as $lineKey => $line) {
$nextRowKey = $rowKey + $lineKey + 1;
if (isset($this->rows[$nextRowKey])) {
$this->rows[$nextRowKey][$key] = $line;
} else {
$this->rows[$nextRowKey] = array($key => $line);
}
}
}
return $this;
}

View File

@ -172,6 +172,31 @@ TABLE
| 80-902734-1-6 | And Then There Were None | Agatha Christie |
+---------------+--------------------------+------------------+
TABLE
),
array(
array('ISBN', 'Title', 'Author'),
array(
array("99921-58-10-7", "Divine\nComedy", "Dante Alighieri"),
array("9971-5-0210-2", "Harry Potter\nand the Chamber of Secrets", "Rowling\nJoanne K."),
array("9971-5-0210-2", "Harry Potter\nand the Chamber of Secrets", "Rowling\nJoanne K."),
array("960-425-059-0", "The Lord of the Rings", "J. R. R.\nTolkien"),
),
TableHelper::LAYOUT_DEFAULT,
<<<TABLE
+---------------+----------------------------+-----------------+
| ISBN | Title | Author |
+---------------+----------------------------+-----------------+
| 99921-58-10-7 | Divine | Dante Alighieri |
| | Comedy | |
| 9971-5-0210-2 | Harry Potter | Rowling |
| | and the Chamber of Secrets | Joanne K. |
| 9971-5-0210-2 | Harry Potter | Rowling |
| | and the Chamber of Secrets | Joanne K. |
| 960-425-059-0 | The Lord of the Rings | J. R. R. |
| | | Tolkien |
+---------------+----------------------------+-----------------+
TABLE
),
array(

View File

@ -207,7 +207,7 @@ class Container implements IntrospectableContainerInterface
$this->services[$id] = $service;
if (method_exists($this, $method = 'synchronize'.strtr($id, array('_' => '', '.' => '_')).'Service')) {
if (method_exists($this, $method = 'synchronize'.strtr($id, array('_' => '', '.' => '_', '\\' => '_')).'Service')) {
$this->$method();
}
@ -236,7 +236,7 @@ class Container implements IntrospectableContainerInterface
return isset($this->services[$id])
|| array_key_exists($id, $this->services)
|| isset($this->aliases[$id])
|| method_exists($this, 'get'.strtr($id, array('_' => '', '.' => '_')).'Service')
|| method_exists($this, 'get'.strtr($id, array('_' => '', '.' => '_', '\\' => '_')).'Service')
;
}
@ -264,7 +264,7 @@ class Container implements IntrospectableContainerInterface
// Attempt to retrieve the service by checking first aliases then
// available services. Service IDs are case insensitive, however since
// this method can be called thousands of times during a request, avoid
// calling strotolower() unless necessary.
// calling strtolower() unless necessary.
foreach (array(false, true) as $strtolower) {
if ($strtolower) {
$id = strtolower($id);
@ -284,7 +284,7 @@ class Container implements IntrospectableContainerInterface
if (isset($this->methodMap[$id])) {
$method = $this->methodMap[$id];
} elseif (method_exists($this, $method = 'get'.strtr($id, array('_' => '', '.' => '_')).'Service')) {
} elseif (method_exists($this, $method = 'get'.strtr($id, array('_' => '', '.' => '_', '\\' => '_')).'Service')) {
// $method is set to the right value, proceed
} else {
if (self::EXCEPTION_ON_INVALID_REFERENCE === $invalidBehavior) {

View File

@ -187,6 +187,10 @@ class XmlFileLoader extends FileLoader
continue;
}
if (false !== strpos($name, '-') && false === strpos($name, '_') && !array_key_exists($normalizedName = str_replace('-', '_', $name), $parameters)) {
$parameters[$normalizedName] = SimpleXMLElement::phpize($value);
}
// keep not normalized key for BC too
$parameters[$name] = SimpleXMLElement::phpize($value);
}

View File

@ -188,6 +188,7 @@ class ContainerTest extends \PHPUnit_Framework_TestCase
$this->assertEquals($sc->__bar, $sc->get('bar'), '->get() returns the service for the given id');
$this->assertEquals($sc->__foo_bar, $sc->get('foo_bar'), '->get() returns the service if a get*Method() is defined');
$this->assertEquals($sc->__foo_baz, $sc->get('foo.baz'), '->get() returns the service if a get*Method() is defined');
$this->assertEquals($sc->__foo_baz, $sc->get('foo\\baz'), '->get() returns the service if a get*Method() is defined');
$sc->set('bar', $bar = new \stdClass());
$this->assertEquals($bar, $sc->get('bar'), '->get() prefers to return a service defined with set() than one defined with a getXXXMethod()');
@ -259,6 +260,7 @@ class ContainerTest extends \PHPUnit_Framework_TestCase
$this->assertTrue($sc->has('bar'), '->has() returns true if a get*Method() is defined');
$this->assertTrue($sc->has('foo_bar'), '->has() returns true if a get*Method() is defined');
$this->assertTrue($sc->has('foo.baz'), '->has() returns true if a get*Method() is defined');
$this->assertTrue($sc->has('foo\\baz'), '->has() returns true if a get*Method() is defined');
}
/**

View File

@ -0,0 +1,16 @@
<?xml version="1.0" ?>
<container xmlns="http://symfony.com/schema/dic/services"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
<services>
<service id="foo" class="BarClass">
<tag name="foo_tag"
some-option="cat"
some_option="ciz"
other-option="lorem"
an_other-option="ipsum"
/>
</service>
</services>
</container>

View File

@ -231,6 +231,29 @@ class XmlFileLoaderTest extends \PHPUnit_Framework_TestCase
$this->assertFalse($aliases['another_alias_for_foo']->isPublic());
}
public function testParsesTags()
{
$container = new ContainerBuilder();
$loader = new XmlFileLoader($container, new FileLocator(self::$fixturesPath.'/xml'));
$loader->load('services10.xml');
$services = $container->findTaggedServiceIds('foo_tag');
$this->assertCount(1, $services);
foreach ($services as $id => $tagAttributes) {
foreach ($tagAttributes as $attributes) {
$this->assertArrayHasKey('other_option', $attributes);
$this->assertEquals('lorem', $attributes['other_option']);
$this->assertArrayHasKey('other-option', $attributes, 'unnormalized tag attributes should not be removed');
$this->assertEquals('ciz', $attributes['some_option'], 'no overriding should be done when normalizing');
$this->assertEquals('cat', $attributes['some-option']);
$this->assertArrayNotHasKey('an_other_option', $attributes, 'normalization should not be done when an underscore is already found');
}
}
}
public function testConvertDomElementToArray()
{
$doc = new \DOMDocument("1.0");

View File

@ -0,0 +1,9 @@
<?xml version="1.0" ?>
<container xmlns="http://symfony.com/schema/dic/services"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
<services>
<service id="foo" class="BarClass" />
</services>
</container>

View File

@ -52,7 +52,7 @@ class Filesystem
if ($doCopy) {
// https://bugs.php.net/bug.php?id=64634
$source = fopen($originFile, 'r');
$target = fopen($targetFile, 'w+');
$target = fopen($targetFile, 'w');
stream_copy_to_stream($source, $target);
fclose($source);
fclose($target);

View File

@ -12,6 +12,7 @@
namespace Symfony\Component\Form\Extension\Core\DataTransformer;
use Symfony\Component\Form\DataTransformerInterface;
use Symfony\Component\Form\Exception\InvalidArgumentException;
use Symfony\Component\Form\Exception\UnexpectedTypeException;
abstract class BaseDateTimeTransformer implements DataTransformerInterface
@ -35,6 +36,7 @@ abstract class BaseDateTimeTransformer implements DataTransformerInterface
* @param string $outputTimezone The name of the output timezone
*
* @throws UnexpectedTypeException if a timezone is not a string
* @throws InvalidArgumentException if a timezone is not valid
*/
public function __construct($inputTimezone = null, $outputTimezone = null)
{
@ -48,5 +50,18 @@ abstract class BaseDateTimeTransformer implements DataTransformerInterface
$this->inputTimezone = $inputTimezone ?: date_default_timezone_get();
$this->outputTimezone = $outputTimezone ?: date_default_timezone_get();
// Check if input and output timezones are valid
try {
new \DateTimeZone($this->inputTimezone);
} catch (\Exception $e) {
throw new InvalidArgumentException(sprintf('Input timezone is invalid: %s.', $this->inputTimezone), $e->getCode(), $e);
}
try {
new \DateTimeZone($this->outputTimezone);
} catch (\Exception $e) {
throw new InvalidArgumentException(sprintf('Output timezone is invalid: %s.', $this->outputTimezone), $e->getCode(), $e);
}
}
}

View File

@ -145,14 +145,10 @@ class ValidatorTypeGuesser implements FormTypeGuesserInterface
case 'Symfony\Component\Validator\Constraints\Ip':
return new TypeGuess('text', array(), Guess::MEDIUM_CONFIDENCE);
case 'Symfony\Component\Validator\Constraints\MaxLength':
case 'Symfony\Component\Validator\Constraints\MinLength':
case 'Symfony\Component\Validator\Constraints\Length':
case 'Symfony\Component\Validator\Constraints\Regex':
return new TypeGuess('text', array(), Guess::LOW_CONFIDENCE);
case 'Symfony\Component\Validator\Constraints\Min':
case 'Symfony\Component\Validator\Constraints\Max':
case 'Symfony\Component\Validator\Constraints\Range':
return new TypeGuess('number', array(), Guess::LOW_CONFIDENCE);
@ -196,9 +192,6 @@ class ValidatorTypeGuesser implements FormTypeGuesserInterface
public function guessMaxLengthForConstraint(Constraint $constraint)
{
switch (get_class($constraint)) {
case 'Symfony\Component\Validator\Constraints\MaxLength':
return new ValueGuess($constraint->limit, Guess::HIGH_CONFIDENCE);
case 'Symfony\Component\Validator\Constraints\Length':
if (is_numeric($constraint->max)) {
return new ValueGuess($constraint->max, Guess::HIGH_CONFIDENCE);
@ -211,9 +204,6 @@ class ValidatorTypeGuesser implements FormTypeGuesserInterface
}
break;
case 'Symfony\Component\Validator\Constraints\Max':
return new ValueGuess(strlen((string) $constraint->limit), Guess::LOW_CONFIDENCE);
case 'Symfony\Component\Validator\Constraints\Range':
if (is_numeric($constraint->max)) {
return new ValueGuess(strlen((string) $constraint->max), Guess::LOW_CONFIDENCE);
@ -234,9 +224,6 @@ class ValidatorTypeGuesser implements FormTypeGuesserInterface
public function guessPatternForConstraint(Constraint $constraint)
{
switch (get_class($constraint)) {
case 'Symfony\Component\Validator\Constraints\MinLength':
return new ValueGuess(sprintf('.{%s,}', (string) $constraint->limit), Guess::LOW_CONFIDENCE);
case 'Symfony\Component\Validator\Constraints\Length':
if (is_numeric($constraint->min)) {
return new ValueGuess(sprintf('.{%s,}', (string) $constraint->min), Guess::LOW_CONFIDENCE);
@ -251,9 +238,6 @@ class ValidatorTypeGuesser implements FormTypeGuesserInterface
}
break;
case 'Symfony\Component\Validator\Constraints\Min':
return new ValueGuess(sprintf('.{%s,}', strlen((string) $constraint->limit)), Guess::LOW_CONFIDENCE);
case 'Symfony\Component\Validator\Constraints\Range':
if (is_numeric($constraint->min)) {
return new ValueGuess(sprintf('.{%s,}', strlen((string) $constraint->min)), Guess::LOW_CONFIDENCE);

View File

@ -0,0 +1,41 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien.potencier@symfony-project.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Form\Tests\Extension\Core\DataTransformer;
class BaseDateTimeTransformerTest extends \PHPUnit_Framework_TestCase
{
/**
* @expectedException \Symfony\Component\Form\Exception\InvalidArgumentException
* @expectedExceptionMessage this_timezone_does_not_exist
*/
public function testConstructFailsIfInputTimezoneIsInvalid()
{
$this->getMock(
'Symfony\Component\Form\Extension\Core\DataTransformer\BaseDateTimeTransformer',
array(),
array('this_timezone_does_not_exist')
);
}
/**
* @expectedException \Symfony\Component\Form\Exception\InvalidArgumentException
* @expectedExceptionMessage that_timezone_does_not_exist
*/
public function testConstructFailsIfOutputTimezoneIsInvalid()
{
$this->getMock(
'Symfony\Component\Form\Extension\Core\DataTransformer\BaseDateTimeTransformer',
array(),
array(null, 'that_timezone_does_not_exist')
);
}
}

View File

@ -216,15 +216,18 @@ class BinaryFileResponse extends Response
$start = (int) $start;
}
$start = max($start, 0);
$end = min($end, $fileSize - 1);
if ($start <= $end) {
if ($start < 0 || $end > $fileSize - 1) {
$this->setStatusCode(416);
} elseif ($start !== 0 || $end !== $fileSize - 1) {
$this->maxlen = $end < $fileSize ? $end - $start + 1 : -1;
$this->offset = $start;
$this->maxlen = $end < $fileSize ? $end - $start + 1 : -1;
$this->offset = $start;
$this->setStatusCode(206);
$this->headers->set('Content-Range', sprintf('bytes %s-%s/%s', $start, $end, $fileSize));
$this->headers->set('Content-Length', $end - $start + 1);
$this->setStatusCode(206);
$this->headers->set('Content-Range', sprintf('bytes %s-%s/%s', $start, $end, $fileSize));
$this->headers->set('Content-Length', $end - $start + 1);
}
}
}
}

View File

@ -84,12 +84,73 @@ class BinaryFileResponseTest extends ResponseTestCase
return array(
array('bytes=1-4', 1, 4, 'bytes 1-4/35'),
array('bytes=-5', 30, 5, 'bytes 30-34/35'),
array('bytes=-35', 0, 35, 'bytes 0-34/35'),
array('bytes=-40', 0, 35, 'bytes 0-34/35'),
array('bytes=30-', 30, 5, 'bytes 30-34/35'),
array('bytes=30-30', 30, 1, 'bytes 30-30/35'),
array('bytes=30-34', 30, 5, 'bytes 30-34/35'),
array('bytes=30-40', 30, 5, 'bytes 30-34/35')
);
}
/**
* @dataProvider provideFullFileRanges
*/
public function testFullFileRequests($requestRange)
{
$response = BinaryFileResponse::create(__DIR__.'/File/Fixtures/test.gif')->setAutoEtag();
// prepare a request for a range of the testing file
$request = Request::create('/');
$request->headers->set('Range', $requestRange);
$file = fopen(__DIR__.'/File/Fixtures/test.gif', 'r');
$data = fread($file, 35);
fclose($file);
$this->expectOutputString($data);
$response = clone $response;
$response->prepare($request);
$response->sendContent();
$this->assertEquals(200, $response->getStatusCode());
$this->assertEquals('binary', $response->headers->get('Content-Transfer-Encoding'));
}
public function provideFullFileRanges()
{
return array(
array('bytes=0-'),
array('bytes=0-34'),
array('bytes=-35'),
// Syntactical invalid range-request should also return the full resource
array('bytes=20-10'),
array('bytes=50-40'),
);
}
/**
* @dataProvider provideInvalidRanges
*/
public function testInvalidRequests($requestRange)
{
$response = BinaryFileResponse::create(__DIR__.'/File/Fixtures/test.gif')->setAutoEtag();
// prepare a request for a range of the testing file
$request = Request::create('/');
$request->headers->set('Range', $requestRange);
$response = clone $response;
$response->prepare($request);
$response->sendContent();
$this->assertEquals(416, $response->getStatusCode());
$this->assertEquals('binary', $response->headers->get('Content-Transfer-Encoding'));
#$this->assertEquals('', $response->headers->get('Content-Range'));
}
public function provideInvalidRanges()
{
return array(
array('bytes=-40'),
array('bytes=30-40')
);
}

View File

@ -36,6 +36,7 @@ class TraceableEventDispatcher implements EventDispatcherInterface, TraceableEve
private $wrappedListeners = array();
private $firstCalledEvent = array();
private $id;
private $lastEventId = 0;
/**
* Constructor.
@ -123,7 +124,7 @@ class TraceableEventDispatcher implements EventDispatcherInterface, TraceableEve
$event = new Event();
}
$this->id = spl_object_hash($event);
$this->id = $eventId = ++$this->lastEventId;
$this->preDispatch($eventName, $event);
@ -138,7 +139,7 @@ class TraceableEventDispatcher implements EventDispatcherInterface, TraceableEve
$this->dispatcher->dispatch($eventName, $event);
// reset the id as another event might have been dispatched during the dispatching of this event
$this->id = spl_object_hash($event);
$this->id = $eventId;
unset($this->firstCalledEvent[$eventName]);

View File

@ -148,6 +148,22 @@ class TraceableEventDispatcherTest extends \PHPUnit_Framework_TestCase
$dispatcher->dispatch('foo');
}
public function testDispatchReusedEventNested()
{
$nestedCall = false;
$dispatcher = new TraceableEventDispatcher(new EventDispatcher(), new Stopwatch());
$dispatcher->addListener('foo', function (Event $e) use ($dispatcher) {
$dispatcher->dispatch('bar', $e);
});
$dispatcher->addListener('bar', function (Event $e) use (&$nestedCall) {
$nestedCall = true;
});
$this->assertFalse($nestedCall);
$dispatcher->dispatch('foo');
$this->assertTrue($nestedCall);
}
public function testStopwatchSections()
{
$dispatcher = new TraceableEventDispatcher(new EventDispatcher(), $stopwatch = new Stopwatch());

View File

@ -137,5 +137,4 @@ class SvnRepository
return $this->svnInfo;
}
}

View File

@ -92,6 +92,7 @@ EOF;
$properties[] = $route->getRequirements();
$properties[] = $compiledRoute->getTokens();
$properties[] = $compiledRoute->getHostTokens();
$properties[] = $route->getSchemes();
$routes .= sprintf(" '%s' => %s,\n", $name, str_replace("\n", '', var_export($properties, true)));
}
@ -114,9 +115,9 @@ EOF;
throw new RouteNotFoundException(sprintf('Unable to generate a URL for the named route "%s" as such route does not exist.', \$name));
}
list(\$variables, \$defaults, \$requirements, \$tokens, \$hostTokens) = self::\$declaredRoutes[\$name];
list(\$variables, \$defaults, \$requirements, \$tokens, \$hostTokens, \$requiredSchemes) = self::\$declaredRoutes[\$name];
return \$this->doGenerate(\$variables, \$defaults, \$requirements, \$tokens, \$parameters, \$name, \$referenceType, \$hostTokens);
return \$this->doGenerate(\$variables, \$defaults, \$requirements, \$tokens, \$parameters, \$name, \$referenceType, \$hostTokens, \$requiredSchemes);
}
EOF;
}

View File

@ -137,7 +137,7 @@ class UrlGenerator implements UrlGeneratorInterface, ConfigurableRequirementsInt
// the Route has a cache of its own and is not recompiled as long as it does not get modified
$compiledRoute = $route->compile();
return $this->doGenerate($compiledRoute->getVariables(), $route->getDefaults(), $route->getRequirements(), $compiledRoute->getTokens(), $parameters, $name, $referenceType, $compiledRoute->getHostTokens());
return $this->doGenerate($compiledRoute->getVariables(), $route->getDefaults(), $route->getRequirements(), $compiledRoute->getTokens(), $parameters, $name, $referenceType, $compiledRoute->getHostTokens(), $route->getSchemes());
}
/**
@ -145,7 +145,7 @@ class UrlGenerator implements UrlGeneratorInterface, ConfigurableRequirementsInt
* @throws InvalidParameterException When a parameter value for a placeholder is not correct because
* it does not match the requirement
*/
protected function doGenerate($variables, $defaults, $requirements, $tokens, $parameters, $name, $referenceType, $hostTokens)
protected function doGenerate($variables, $defaults, $requirements, $tokens, $parameters, $name, $referenceType, $hostTokens, array $requiredSchemes = array())
{
$variables = array_flip($variables);
$mergedParams = array_replace($defaults, $this->context->getParameters(), $parameters);
@ -204,7 +204,24 @@ class UrlGenerator implements UrlGeneratorInterface, ConfigurableRequirementsInt
$schemeAuthority = '';
if ($host = $this->context->getHost()) {
$scheme = $this->context->getScheme();
if (isset($requirements['_scheme']) && ($req = strtolower($requirements['_scheme'])) && $scheme !== $req) {
if ($requiredSchemes) {
$schemeMatched = false;
foreach ($requiredSchemes as $requiredScheme) {
if ($scheme === $requiredScheme) {
$schemeMatched = true;
break;
}
}
if (!$schemeMatched) {
$referenceType = self::ABSOLUTE_URL;
$scheme = current($requiredSchemes);
}
} elseif (isset($requirements['_scheme']) && ($req = strtolower($requirements['_scheme'])) && $scheme !== $req) {
// We do this for BC; to be removed if _scheme is not supported anymore
$referenceType = self::ABSOLUTE_URL;
$scheme = $req;
}

View File

@ -288,14 +288,15 @@ EOF;
EOF;
}
if ($scheme = $route->getRequirement('_scheme')) {
if ($schemes = $route->getSchemes()) {
if (!$supportsRedirections) {
throw new \LogicException('The "_scheme" requirement is only supported for URL matchers that implement RedirectableUrlMatcherInterface.');
throw new \LogicException('The "schemes" requirement is only supported for URL matchers that implement RedirectableUrlMatcherInterface.');
}
$schemes = str_replace("\n", '', var_export(array_flip($schemes), true));
$code .= <<<EOF
if (\$this->context->getScheme() !== '$scheme') {
return \$this->redirect(\$pathinfo, '$name', '$scheme');
\$requiredSchemes = $schemes;
if (!isset(\$requiredSchemes[\$this->context->getScheme()])) {
return \$this->redirect(\$pathinfo, '$name', key(\$requiredSchemes));
}
@ -313,8 +314,11 @@ EOF;
}
$vars[] = "array('_route' => '$name')";
$code .= sprintf(" return \$this->mergeDefaults(array_replace(%s), %s);\n"
, implode(', ', $vars), str_replace("\n", '', var_export($route->getDefaults(), true)));
$code .= sprintf(
" return \$this->mergeDefaults(array_replace(%s), %s);\n",
implode(', ', $vars),
str_replace("\n", '', var_export($route->getDefaults(), true))
);
} elseif ($route->getDefaults()) {
$code .= sprintf(" return %s;\n", str_replace("\n", '', var_export(array_replace($route->getDefaults(), array('_route' => $name)), true)));

View File

@ -56,9 +56,10 @@ abstract class RedirectableUrlMatcher extends UrlMatcher implements Redirectable
}
// check HTTP scheme requirement
$scheme = $route->getRequirement('_scheme');
if ($scheme && $this->context->getScheme() !== $scheme) {
return array(self::ROUTE_MATCH, $this->redirect($pathinfo, $name, $scheme));
$scheme = $this->context->getScheme();
$schemes = $route->getSchemes();
if ($schemes && !$route->hasScheme($scheme)) {
return array(self::ROUTE_MATCH, $this->redirect($pathinfo, $name, current($schemes)));
}
return array(self::REQUIREMENT_MATCH, null);

View File

@ -75,7 +75,7 @@ class TraceableUrlMatcher extends UrlMatcher
if ($compiledRoute->getHostRegex() && !preg_match($compiledRoute->getHostRegex(), $this->context->getHost(), $hostMatches)) {
$this->addTrace(sprintf('Host "%s" does not match the requirement ("%s")', $this->context->getHost(), $route->getHost()), self::ROUTE_ALMOST_MATCHES, $name, $route);
return true;
continue;
}
// check HTTP method requirement
@ -104,9 +104,11 @@ class TraceableUrlMatcher extends UrlMatcher
}
// check HTTP scheme requirement
if ($scheme = $route->getRequirement('_scheme')) {
if ($this->context->getScheme() !== $scheme) {
$this->addTrace(sprintf('Scheme "%s" does not match the requirement ("%s"); the user will be redirected', $this->context->getScheme(), $scheme), self::ROUTE_ALMOST_MATCHES, $name, $route);
if ($requiredSchemes = $route->getSchemes()) {
$scheme = $this->context->getScheme();
if (!$route->hasScheme($scheme)) {
$this->addTrace(sprintf('Scheme "%s" does not match any of the required schemes ("%s"); the user will be redirected to first required scheme', $scheme, implode(', ', $requiredSchemes)), self::ROUTE_ALMOST_MATCHES, $name, $route);
return true;
}

View File

@ -205,12 +205,10 @@ class UrlMatcher implements UrlMatcherInterface, RequestMatcherInterface
}
// check HTTP scheme requirement
$scheme = $route->getRequirement('_scheme');
if ($scheme && $scheme !== $this->context->getScheme()) {
return array(self::REQUIREMENT_MISMATCH, null);
}
$scheme = $this->context->getScheme();
$status = $route->getSchemes() && !$route->hasScheme($scheme) ? self::REQUIREMENT_MISMATCH : self::REQUIREMENT_MATCH;
return array(self::REQUIREMENT_MATCH, null);
return array($status, null);
}
/**

View File

@ -247,6 +247,25 @@ class Route implements \Serializable
return $this;
}
/**
* Checks if a scheme requirement has been set.
*
* @param string $scheme
*
* @return Boolean true if the scheme requirement exists, otherwise false
*/
public function hasScheme($scheme)
{
$scheme = strtolower($scheme);
foreach ($this->schemes as $requiredScheme) {
if ($scheme === $requiredScheme) {
return true;
}
}
return false;
}
/**
* Returns the uppercased HTTP methods this route is restricted to.
* So an empty array means that any method is allowed.

View File

@ -321,8 +321,9 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Tests\Fixtures\Redirec
// secure
if ($pathinfo === '/secure') {
if ($this->context->getScheme() !== 'https') {
return $this->redirect($pathinfo, 'secure', 'https');
$requiredSchemes = array ( 'https' => 0,);
if (!isset($requiredSchemes[$this->context->getScheme()])) {
return $this->redirect($pathinfo, 'secure', key($requiredSchemes));
}
return array('_route' => 'secure');
@ -330,8 +331,9 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Tests\Fixtures\Redirec
// nonsecure
if ($pathinfo === '/nonsecure') {
if ($this->context->getScheme() !== 'http') {
return $this->redirect($pathinfo, 'nonsecure', 'http');
$requiredSchemes = array ( 'http' => 0,);
if (!isset($requiredSchemes[$this->context->getScheme()])) {
return $this->redirect($pathinfo, 'nonsecure', key($requiredSchemes));
}
return array('_route' => 'nonsecure');

View File

@ -114,4 +114,37 @@ class PhpGeneratorDumperTest extends \PHPUnit_Framework_TestCase
$this->assertEquals($url, '/testing');
}
public function testDumpWithSchemeRequirement()
{
$this->routeCollection->add('Test1', new Route('/testing', array(), array(), array(), '', array('ftp', 'https')));
$this->routeCollection->add('Test2', new Route('/testing_bc', array(), array('_scheme' => 'https'))); // BC
file_put_contents($this->testTmpFilepath, $this->generatorDumper->dump(array('class' => 'SchemeUrlGenerator')));
include ($this->testTmpFilepath);
$projectUrlGenerator = new \SchemeUrlGenerator(new RequestContext('/app.php'));
$absoluteUrl = $projectUrlGenerator->generate('Test1', array(), true);
$absoluteUrlBC = $projectUrlGenerator->generate('Test2', array(), true);
$relativeUrl = $projectUrlGenerator->generate('Test1', array(), false);
$relativeUrlBC = $projectUrlGenerator->generate('Test2', array(), false);
$this->assertEquals($absoluteUrl, 'ftp://localhost/app.php/testing');
$this->assertEquals($absoluteUrlBC, 'https://localhost/app.php/testing_bc');
$this->assertEquals($relativeUrl, 'ftp://localhost/app.php/testing');
$this->assertEquals($relativeUrlBC, 'https://localhost/app.php/testing_bc');
$projectUrlGenerator = new \SchemeUrlGenerator(new RequestContext('/app.php', 'GET', 'localhost', 'https'));
$absoluteUrl = $projectUrlGenerator->generate('Test1', array(), true);
$absoluteUrlBC = $projectUrlGenerator->generate('Test2', array(), true);
$relativeUrl = $projectUrlGenerator->generate('Test1', array(), false);
$relativeUrlBC = $projectUrlGenerator->generate('Test2', array(), false);
$this->assertEquals($absoluteUrl, 'https://localhost/app.php/testing');
$this->assertEquals($absoluteUrlBC, 'https://localhost/app.php/testing_bc');
$this->assertEquals($relativeUrl, '/app.php/testing');
$this->assertEquals($relativeUrlBC, '/app.php/testing_bc');
}
}

View File

@ -244,20 +244,38 @@ class UrlGeneratorTest extends \PHPUnit_Framework_TestCase
public function testSchemeRequirementDoesNothingIfSameCurrentScheme()
{
$routes = $this->getRoutes('test', new Route('/', array(), array('_scheme' => 'http')));
$routes = $this->getRoutes('test', new Route('/', array(), array('_scheme' => 'http'))); // BC
$this->assertEquals('/app.php/', $this->getGenerator($routes)->generate('test'));
$routes = $this->getRoutes('test', new Route('/', array(), array('_scheme' => 'https')));
$routes = $this->getRoutes('test', new Route('/', array(), array('_scheme' => 'https'))); // BC
$this->assertEquals('/app.php/', $this->getGenerator($routes, array('scheme' => 'https'))->generate('test'));
$routes = $this->getRoutes('test', new Route('/', array(), array(), array(), '', array('http')));
$this->assertEquals('/app.php/', $this->getGenerator($routes)->generate('test'));
$routes = $this->getRoutes('test', new Route('/', array(), array(), array(), '', array('https')));
$this->assertEquals('/app.php/', $this->getGenerator($routes, array('scheme' => 'https'))->generate('test'));
}
public function testSchemeRequirementForcesAbsoluteUrl()
{
$routes = $this->getRoutes('test', new Route('/', array(), array('_scheme' => 'https')));
$routes = $this->getRoutes('test', new Route('/', array(), array('_scheme' => 'https'))); // BC
$this->assertEquals('https://localhost/app.php/', $this->getGenerator($routes)->generate('test'));
$routes = $this->getRoutes('test', new Route('/', array(), array('_scheme' => 'http')));
$routes = $this->getRoutes('test', new Route('/', array(), array('_scheme' => 'http'))); // BC
$this->assertEquals('http://localhost/app.php/', $this->getGenerator($routes, array('scheme' => 'https'))->generate('test'));
$routes = $this->getRoutes('test', new Route('/', array(), array(), array(), '', array('https')));
$this->assertEquals('https://localhost/app.php/', $this->getGenerator($routes)->generate('test'));
$routes = $this->getRoutes('test', new Route('/', array(), array(), array(), '', array('http')));
$this->assertEquals('http://localhost/app.php/', $this->getGenerator($routes, array('scheme' => 'https'))->generate('test'));
}
public function testSchemeRequirementCreatesUrlForFirstRequiredScheme()
{
$routes = $this->getRoutes('test', new Route('/', array(), array(), array(), '', array('Ftp', 'https')));
$this->assertEquals('ftp://localhost/app.php/', $this->getGenerator($routes)->generate('test'));
}
public function testPathWithTwoStartingSlashes()
@ -443,7 +461,7 @@ class UrlGeneratorTest extends \PHPUnit_Framework_TestCase
$this->assertNull($generator->generate('test', array('foo' => 'baz'), false));
}
public function testGenerateNetworkPath()
public function testGenerateNetworkPathBC()
{
$routes = $this->getRoutes('test', new Route('/{name}', array(), array('_scheme' => 'http'), array(), '{locale}.example.com'));
@ -461,13 +479,32 @@ class UrlGeneratorTest extends \PHPUnit_Framework_TestCase
);
}
public function testGenerateNetworkPath()
{
$routes = $this->getRoutes('test', new Route('/{name}', array(), array(), array(), '{locale}.example.com', array('http')));
$this->assertSame('//fr.example.com/app.php/Fabien', $this->getGenerator($routes)->generate('test',
array('name' =>'Fabien', 'locale' => 'fr'), UrlGeneratorInterface::NETWORK_PATH), 'network path with different host'
);
$this->assertSame('//fr.example.com/app.php/Fabien?query=string', $this->getGenerator($routes, array('host' => 'fr.example.com'))->generate('test',
array('name' =>'Fabien', 'locale' => 'fr', 'query' => 'string'), UrlGeneratorInterface::NETWORK_PATH), 'network path although host same as context'
);
$this->assertSame('http://fr.example.com/app.php/Fabien', $this->getGenerator($routes, array('scheme' => 'https'))->generate('test',
array('name' =>'Fabien', 'locale' => 'fr'), UrlGeneratorInterface::NETWORK_PATH), 'absolute URL because scheme requirement does not match context'
);
$this->assertSame('http://fr.example.com/app.php/Fabien', $this->getGenerator($routes)->generate('test',
array('name' =>'Fabien', 'locale' => 'fr'), UrlGeneratorInterface::ABSOLUTE_URL), 'absolute URL with same scheme because it is requested'
);
}
public function testGenerateRelativePath()
{
$routes = new RouteCollection();
$routes->add('article', new Route('/{author}/{article}/'));
$routes->add('comments', new Route('/{author}/{article}/comments'));
$routes->add('host', new Route('/{article}', array(), array(), array(), '{author}.example.com'));
$routes->add('scheme', new Route('/{author}', array(), array('_scheme' => 'https')));
$routes->add('schemeBC', new Route('/{author}', array(), array('_scheme' => 'https'))); // BC
$routes->add('scheme', new Route('/{author}/blog', array(), array(), array(), '', array('https')));
$routes->add('unrelated', new Route('/about'));
$generator = $this->getGenerator($routes, array('host' => 'example.com', 'pathInfo' => '/fabien/symfony-is-great/'));
@ -487,9 +524,12 @@ class UrlGeneratorTest extends \PHPUnit_Framework_TestCase
$this->assertSame('//bernhard.example.com/app.php/forms-are-great', $generator->generate('host',
array('author' =>'bernhard', 'article' => 'forms-are-great'), UrlGeneratorInterface::RELATIVE_PATH)
);
$this->assertSame('https://example.com/app.php/bernhard', $generator->generate('scheme',
$this->assertSame('https://example.com/app.php/bernhard', $generator->generate('schemeBC',
array('author' =>'bernhard'), UrlGeneratorInterface::RELATIVE_PATH)
);
$this->assertSame('https://example.com/app.php/bernhard/blog', $generator->generate('scheme',
array('author' =>'bernhard'), UrlGeneratorInterface::RELATIVE_PATH)
);
$this->assertSame('../../about', $generator->generate('unrelated',
array(), UrlGeneratorInterface::RELATIVE_PATH)
);

View File

@ -41,7 +41,7 @@ class RedirectableUrlMatcherTest extends \PHPUnit_Framework_TestCase
$matcher->match('/foo');
}
public function testSchemeRedirect()
public function testSchemeRedirectBC()
{
$coll = new RouteCollection();
$coll->add('foo', new Route('/foo', array(), array('_scheme' => 'https')));
@ -55,4 +55,32 @@ class RedirectableUrlMatcherTest extends \PHPUnit_Framework_TestCase
;
$matcher->match('/foo');
}
public function testSchemeRedirectRedirectsToFirstScheme()
{
$coll = new RouteCollection();
$coll->add('foo', new Route('/foo', array(), array(), array(), '', array('FTP', 'HTTPS')));
$matcher = $this->getMockForAbstractClass('Symfony\Component\Routing\Matcher\RedirectableUrlMatcher', array($coll, new RequestContext()));
$matcher
->expects($this->once())
->method('redirect')
->with('/foo', 'foo', 'ftp')
->will($this->returnValue(array('_route' => 'foo')))
;
$matcher->match('/foo');
}
public function testNoSchemaRedirectIfOnOfMultipleSchemesMatches()
{
$coll = new RouteCollection();
$coll->add('foo', new Route('/foo', array(), array(), array(), '', array('https', 'http')));
$matcher = $this->getMockForAbstractClass('Symfony\Component\Routing\Matcher\RedirectableUrlMatcher', array($coll, new RequestContext()));
$matcher
->expects($this->never())
->method('redirect')
;
$matcher->match('/foo');
}
}

View File

@ -58,6 +58,37 @@ class TraceableUrlMatcherTest extends \PHPUnit_Framework_TestCase
$this->assertEquals(array(0, 0, 0, 0, 0, 1), $this->getLevels($traces));
}
public function testMatchRouteOnMultipleHosts()
{
$routes = new RouteCollection();
$routes->add('first', new Route(
'/mypath/',
array('_controller' => 'MainBundle:Info:first'),
array(),
array(),
'some.example.com'
));
$routes->add('second', new Route(
'/mypath/',
array('_controller' => 'MainBundle:Info:second'),
array(),
array(),
'another.example.com'
));
$context = new RequestContext();
$context->setHost('baz');
$matcher = new TraceableUrlMatcher($routes, $context);
$traces = $matcher->getTraces('/mypath/');
$this->assertEquals(
array(TraceableUrlMatcher::ROUTE_ALMOST_MATCHES, TraceableUrlMatcher::ROUTE_ALMOST_MATCHES),
$this->getLevels($traces)
);
}
public function getLevels($traces)
{
$levels = array();

View File

@ -313,13 +313,23 @@ class UrlMatcherTest extends \PHPUnit_Framework_TestCase
/**
* @expectedException \Symfony\Component\Routing\Exception\ResourceNotFoundException
*/
public function testSchemeRequirement()
public function testSchemeRequirementBC()
{
$coll = new RouteCollection();
$coll->add('foo', new Route('/foo', array(), array('_scheme' => 'https')));
$matcher = new UrlMatcher($coll, new RequestContext());
$matcher->match('/foo');
}
/**
* @expectedException \Symfony\Component\Routing\Exception\ResourceNotFoundException
*/
public function testSchemeRequirement()
{
$coll = new RouteCollection();
$coll->add('foo', new Route('/foo', array(), array(), array(), '', array('https')));
$matcher = new UrlMatcher($coll, new RequestContext());
$matcher->match('/foo');
}
/**
* @expectedException \Symfony\Component\Routing\Exception\ResourceNotFoundException

View File

@ -142,10 +142,15 @@ class RouteTest extends \PHPUnit_Framework_TestCase
{
$route = new Route('/');
$this->assertEquals(array(), $route->getSchemes(), 'schemes is initialized with array()');
$this->assertFalse($route->hasScheme('http'));
$route->setSchemes('hTTp');
$this->assertEquals(array('http'), $route->getSchemes(), '->setSchemes() accepts a single scheme string and lowercases it');
$this->assertTrue($route->hasScheme('htTp'));
$this->assertFalse($route->hasScheme('httpS'));
$route->setSchemes(array('HttpS', 'hTTp'));
$this->assertEquals(array('https', 'http'), $route->getSchemes(), '->setSchemes() accepts an array of schemes and lowercases them');
$this->assertTrue($route->hasScheme('htTp'));
$this->assertTrue($route->hasScheme('httpS'));
}
public function testSchemeIsBC()
@ -154,6 +159,9 @@ class RouteTest extends \PHPUnit_Framework_TestCase
$route->setRequirement('_scheme', 'http|https');
$this->assertEquals('http|https', $route->getRequirement('_scheme'));
$this->assertEquals(array('http', 'https'), $route->getSchemes());
$this->assertTrue($route->hasScheme('https'));
$this->assertTrue($route->hasScheme('http'));
$this->assertFalse($route->hasScheme('ftp'));
$route->setSchemes(array('hTTp'));
$this->assertEquals('http', $route->getRequirement('_scheme'));
$route->setSchemes(array());

View File

@ -142,7 +142,14 @@ abstract class AbstractToken implements TokenInterface
*/
public function serialize()
{
return serialize(array($this->user, $this->authenticated, $this->roles, $this->attributes));
return serialize(
array(
is_object($this->user) ? clone $this->user : $this->user,
$this->authenticated,
$this->roles,
$this->attributes
)
);
}
/**

View File

@ -11,7 +11,9 @@
namespace Symfony\Component\Security\Core\Tests\Authentication\Token;
use Symfony\Component\Security\Core\Authentication\Token\AbstractToken;
use Symfony\Component\Security\Core\Role\Role;
use Symfony\Component\Security\Core\Role\SwitchUserRole;
class TestUser
{
@ -28,6 +30,31 @@ class TestUser
}
}
class ConcreteToken extends AbstractToken
{
private $credentials = 'credentials_value';
public function __construct($user, array $roles = array())
{
parent::__construct($roles);
$this->setUser($user);
}
public function serialize()
{
return serialize(array($this->credentials, parent::serialize()));
}
public function unserialize($serialized)
{
list($this->credentials, $parentStr) = unserialize($serialized);
parent::unserialize($parentStr);
}
public function getCredentials() {}
}
class AbstractTokenTest extends \PHPUnit_Framework_TestCase
{
public function testGetUsername()
@ -71,6 +98,20 @@ class AbstractTokenTest extends \PHPUnit_Framework_TestCase
$this->assertEquals($token->getAttributes(), $uToken->getAttributes());
}
public function testSerializeParent()
{
$user = new TestUser('fabien');
$token = new ConcreteToken($user, array('ROLE_FOO'));
$parentToken = new ConcreteToken($user, array(new SwitchUserRole('ROLE_PREVIOUS', $token)));
$uToken = unserialize(serialize($parentToken));
$this->assertEquals(
current($parentToken->getRoles())->getSource()->getUser(),
current($uToken->getRoles())->getSource()->getUser()
);
}
/**
* @covers Symfony\Component\Security\Core\Authentication\Token\AbstractToken::__construct
*/

View File

@ -155,10 +155,11 @@ class ContextListener implements ListenerInterface
foreach ($this->userProviders as $provider) {
try {
$token->setUser($provider->refreshUser($user));
$refreshedUser = $provider->refreshUser($user);
$token->setUser($refreshedUser);
if (null !== $this->logger) {
$this->logger->debug(sprintf('Username "%s" was reloaded from user provider.', $user->getUsername()));
$this->logger->debug(sprintf('Username "%s" was reloaded from user provider.', $refreshedUser->getUsername()));
}
return $token;
@ -166,7 +167,7 @@ class ContextListener implements ListenerInterface
// let's try the next user provider
} catch (UsernameNotFoundException $notFound) {
if (null !== $this->logger) {
$this->logger->warning(sprintf('Username "%s" could not be found.', $user->getUsername()));
$this->logger->warning(sprintf('Username "%s" could not be found.', $notFound->getUsername()));
}
return null;

View File

@ -15,6 +15,6 @@ class UnexpectedTypeException extends ValidatorException
{
public function __construct($value, $expectedType)
{
parent::__construct(sprintf('Expected argument of type %s, %s given', $expectedType, gettype($value)));
parent::__construct(sprintf('Expected argument of type "%s", "%s" given', $expectedType, is_object($value) ? get_class($value) : gettype($value)));
}
}

View File

@ -92,11 +92,11 @@
</trans-unit>
<trans-unit id="23">
<source>This value should not be null.</source>
<target>Tato hodnota nesmí být null.</target>
<target>Tato hodnota nesmí být prázdná.</target>
</trans-unit>
<trans-unit id="24">
<source>This value should be null.</source>
<target>Tato hodnota musí být null.</target>
<target>Tato hodnota musí být prázdná.</target>
</trans-unit>
<trans-unit id="25">
<source>This value is not valid.</source>

View File

@ -242,6 +242,42 @@
<source>This value is not a valid ISSN.</source>
<target>Este valor no es un ISSN válido.</target>
</trans-unit>
<trans-unit id="64">
<source>This value is not a valid currency.</source>
<target>Este valor no es una divisa válida.</target>
</trans-unit>
<trans-unit id="65">
<source>This value should be equal to {{ compared_value }}.</source>
<target>Este valor debería ser igual que {{ compared_value }}.</target>
</trans-unit>
<trans-unit id="66">
<source>This value should be greater than {{ compared_value }}.</source>
<target>Este valor debería ser mayor que {{ compared_value }}.</target>
</trans-unit>
<trans-unit id="67">
<source>This value should be greater than or equal to {{ compared_value }}.</source>
<target>Este valor debería ser mayor o igual que {{ compared_value }}.</target>
</trans-unit>
<trans-unit id="68">
<source>This value should be identical to {{ compared_value_type }} {{ compared_value }}.</source>
<target>Este valor debería ser idéntico a {{ compared_value_type }} {{ compared_value }}.</target>
</trans-unit>
<trans-unit id="69">
<source>This value should be less than {{ compared_value }}.</source>
<target>Este valor debería ser menor que {{ compared_value }}.</target>
</trans-unit>
<trans-unit id="70">
<source>This value should be less than or equal to {{ compared_value }}.</source>
<target>Este valor debería ser menor o igual que {{ compared_value }}.</target>
</trans-unit>
<trans-unit id="71">
<source>This value should not be equal to {{ compared_value }}.</source>
<target>Este valor debería ser distinto de {{ compared_value }}.</target>
</trans-unit>
<trans-unit id="72">
<source>This value should not be identical to {{ compared_value_type }} {{ compared_value }}.</source>
<target>Este valor no debería ser idéntico a {{ compared_value_type }} {{ compared_value }}.</target>
</trans-unit>
</body>
</file>
</xliff>

View File

@ -4,19 +4,19 @@
<body>
<trans-unit id="1">
<source>This value should be false.</source>
<target>Balio honek faltsua izan beharko luke (false).</target>
<target>Balio hau faltsua izan beharko litzateke.</target>
</trans-unit>
<trans-unit id="2">
<source>This value should be true.</source>
<target>Balio honek egiazkoa izan beharko luke (true).</target>
<target>Balio hau egia izan beharko litzateke.</target>
</trans-unit>
<trans-unit id="3">
<source>This value should be of type {{ type }}.</source>
<target>Balio honek {{ type }} motakoa izan beharko luke.</target>
<target>Balio hau {{ type }} motakoa izan beharko litzateke.</target>
</trans-unit>
<trans-unit id="4">
<source>This value should be blank.</source>
<target>Balio honek hutsik egon beharko luke.</target>
<target>Balio hau hutsik egon beharko litzateke.</target>
</trans-unit>
<trans-unit id="5">
<source>The value you selected is not a valid choice.</source>
@ -24,15 +24,15 @@
</trans-unit>
<trans-unit id="6">
<source>You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices.</source>
<target>Gutxienez {{ limit }} aukera hautatu behar dituzu.</target>
<target>Gutxienez aukera {{ limit }} hautatu behar duzu.|Gutxienez {{ limit }} aukera hautatu behar dituzu.</target>
</trans-unit>
<trans-unit id="7">
<source>You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices.</source>
<target>Gehienez {{ limit }} aukera hautatu behar dituzu.</target>
<target>Gehienez aukera {{ limit }} hautatu behar duzu.|Gehienez {{ limit }} aukera hautatu behar dituzu.</target>
</trans-unit>
<trans-unit id="8">
<source>One or more of the given values is invalid.</source>
<target>Emandako balio bat edo gehiago ez dira egokiak.</target>
<target>Emandako balioetatik gutxienez bat ez da egokia.</target>
</trans-unit>
<trans-unit id="9">
<source>The fields {{ fields }} were not expected.</source>
@ -48,11 +48,11 @@
</trans-unit>
<trans-unit id="12">
<source>This value is not a valid datetime.</source>
<target>Balio hau ez da data eta ordu egoki bat.</target>
<target>Balio hau ez da data-ordu egoki bat.</target>
</trans-unit>
<trans-unit id="13">
<source>This value is not a valid email address.</source>
<target>Balio hau ez da helbide elektroniko egoki bat.</target>
<target>Balio hau ez da posta elektroniko egoki bat.</target>
</trans-unit>
<trans-unit id="14">
<source>The file could not be found.</source>
@ -60,11 +60,11 @@
</trans-unit>
<trans-unit id="15">
<source>The file is not readable.</source>
<target>Fitxategia ez dago irakurgai.</target>
<target>Fitxategia ez da irakurgarria.</target>
</trans-unit>
<trans-unit id="16">
<source>The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}.</source>
<target>Fitxategia handiegia da ({{ size }} {{ suffix }}). Baimendutako tamainu handiena {{ limit }} {{ suffix }} da.</target>
<target>Fitxategia handiegia da ({{ size }} {{ suffix }}). Baimendutako tamaina handiena {{ limit }} {{ suffix }} da.</target>
</trans-unit>
<trans-unit id="17">
<source>The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}.</source>
@ -72,31 +72,31 @@
</trans-unit>
<trans-unit id="18">
<source>This value should be {{ limit }} or less.</source>
<target>Balio honek {{ limit }} edo gutxiago izan beharko luke.</target>
<target>Balio hau gehienez {{ limit }} izan beharko litzateke.</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>Balio hau luzeegia da. {{ limit }} karaktere edo gutxiago eduki beharko lituzke.</target>
<target>Balio hau luzeegia da. Gehienez karaktere {{ limit }} eduki beharko luke.|Balio hau luzeegia da. Gehienez {{ limit }} karaktere eduki beharko lituzke.</target>
</trans-unit>
<trans-unit id="20">
<source>This value should be {{ limit }} or more.</source>
<target>Balio honek {{ limit }} edo handiago izan beharko luke.</target>
<target>Balio hau gutxienez {{ limit }} izan beharko litzateke.</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>Balio hau motzegia da. {{ limit }} karaktere edo gehiago eduki beharko lituzke.</target>
<target>Balio hau motzegia da. Karaktere {{ limit }} gutxienez eduki beharko luke.|Balio hau motzegia da. Gutxienez {{ limit }} karaktere eduki beharko lituzke.</target>
</trans-unit>
<trans-unit id="22">
<source>This value should not be blank.</source>
<target>Balio honek ez luke hutsik egon behar.</target>
<target>Balio hau ez litzateke hutsik egon behar.</target>
</trans-unit>
<trans-unit id="23">
<source>This value should not be null.</source>
<target>Balio honek ez luke nulua izan behar.</target>
<target>Balio hau ez litzateke nulua izan behar.</target>
</trans-unit>
<trans-unit id="24">
<source>This value should be null.</source>
<target>Balio honek nulua izan beharko luke.</target>
<target>Balio hau nulua izan beharko litzateke.</target>
</trans-unit>
<trans-unit id="25">
<source>This value is not valid.</source>
@ -108,7 +108,7 @@
</trans-unit>
<trans-unit id="27">
<source>This value is not a valid URL.</source>
<target>Balio hau ez da URL egoki bat.</target>
<target>Balio hau ez da baliabideen kokatzaile uniforme (URL) egoki bat.</target>
</trans-unit>
<trans-unit id="31">
<source>The two values should be equal.</source>
@ -116,7 +116,7 @@
</trans-unit>
<trans-unit id="32">
<source>The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}.</source>
<target>Fitxategia handiegia da. Baimendutako tamainu handiena {{ limit }} {{ suffix }} da.</target>
<target>Fitxategia handiegia da. Baimendutako tamaina handiena {{ limit }} {{ suffix }} da.</target>
</trans-unit>
<trans-unit id="33">
<source>The file is too large.</source>
@ -128,7 +128,7 @@
</trans-unit>
<trans-unit id="35">
<source>This value should be a valid number.</source>
<target>Balio honek zenbaki egoki bat izan beharko luke.</target>
<target>Balio hau zenbaki egoki bat izan beharko litzateke.</target>
</trans-unit>
<trans-unit id="36">
<source>This file is not a valid image.</source>
@ -144,7 +144,7 @@
</trans-unit>
<trans-unit id="39">
<source>This value is not a valid locale.</source>
<target>Balio hau ez da lokalizazio egoki bat.</target>
<target>Balio hau ez da kokapen egoki bat.</target>
</trans-unit>
<trans-unit id="40">
<source>This value is not a valid country.</source>
@ -160,7 +160,7 @@
</trans-unit>
<trans-unit id="43">
<source>The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px.</source>
<target>Irudiaren zabalera haundiegia da ({{ width }}px). Onartutako gehienezko zabalera {{ max_width }}px dira.</target>
<target>Irudiaren zabalera handiegia da ({{ width }}px). Onartutako gehienezko zabalera {{ max_width }}px dira.</target>
</trans-unit>
<trans-unit id="44">
<source>The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px.</source>
@ -168,7 +168,7 @@
</trans-unit>
<trans-unit id="45">
<source>The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px.</source>
<target>Irudiaren altuera haundiegia da ({{ height }}px). Onartutako gehienezko altuera {{ max_height }}px dira.</target>
<target>Irudiaren altuera handiegia da ({{ height }}px). Onartutako gehienezko altuera {{ max_height }}px dira.</target>
</trans-unit>
<trans-unit id="46">
<source>The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px.</source>
@ -176,15 +176,15 @@
</trans-unit>
<trans-unit id="47">
<source>This value should be the user current password.</source>
<target>Balio honek uneko erabiltzailearen pasahitza izan beharko luke.</target>
<target>Balio hau uneko erabiltzailearen pasahitza izan beharko litzateke.</target>
</trans-unit>
<trans-unit id="48">
<source>This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters.</source>
<target>Balio honek zehazki {{ limit }} karaktere izan beharko lituzke.</target>
<target>Balio honek zehazki karaktere {{ limit }} izan beharko luke.|Balio honek zehazki {{ limit }} karaktere izan beharko lituzke.</target>
</trans-unit>
<trans-unit id="49">
<source>The file was only partially uploaded.</source>
<target>Fitxategia partzialki bakarrik igo da.</target>
<target>Fitxategiaren zati bat bakarrik igo da.</target>
</trans-unit>
<trans-unit id="50">
<source>No file was uploaded.</source>
@ -204,27 +204,27 @@
</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>Bilduma honek {{ limit }} elementu edo gehiago eduki beharko lituzke.</target>
<target>Bilduma honek gutxienez elementu {{ limit }} eduki beharko luke.|Bilduma honek gutxienez {{ limit }} elementu eduki beharko lituzke.</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>Bilduma honek {{ limit }} elementu edo gutxiago eduki beharko lituzke.</target>
<target>Bilduma honek gehienez elementu {{ limit }} eduki beharko luke.|Bilduma honek gehienez {{ limit }} elementu eduki beharko lituzke.</target>
</trans-unit>
<trans-unit id="56">
<source>This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements.</source>
<target>Bilduma honek zehazki {{ limit }} elementu eduki beharko lituzke.</target>
<target>Bilduma honek zehazki elementu {{ limit }} eduki beharko luke.|Bilduma honek zehazki {{ limit }} elementu eduki beharko lituzke.</target>
</trans-unit>
<trans-unit id="57">
<source>Invalid card number.</source>
<target>Txartelaren zenbaki baliogabea.</target>
<target>Txartel zenbaki baliogabea.</target>
</trans-unit>
<trans-unit id="58">
<source>Unsupported card type or invalid card number.</source>
<target>Onartzen ez den txartel mota edo txartelaren zenbaki baliogabea.</target>
<target>Txartel mota onartezina edo txartel zenbaki baliogabea.</target>
</trans-unit>
<trans-unit id="59">
<source>This is not a valid International Bank Account Number (IBAN).</source>
<target>Hau ez da onartutako International Bank Account Number (IBAN) bat.</target>
<target>Hau ez da baliozko banku internazionaleko kontu zenbaki (IBAN) bat.</target>
</trans-unit>
<trans-unit id="60">
<source>This value is not a valid ISBN-10.</source>
@ -244,39 +244,39 @@
</trans-unit>
<trans-unit id="64">
<source>This value is not a valid currency.</source>
<target>Balio hau ez da baliozko moneta.</target>
<target>Balio hau ez da baliozko moneta bat.</target>
</trans-unit>
<trans-unit id="65">
<source>This value should be equal to {{ compared_value }}.</source>
<target>Balio honek {{ compared_value }}-(r)en berdina izan behar du.</target>
<target>Balio hau {{ compared_value }}-(r)en berbera izan beharko litzateke.</target>
</trans-unit>
<trans-unit id="66">
<source>This value should be greater than {{ compared_value }}.</source>
<target>Balio honek {{ compared_value }} baino handiagoa izan behar du.</target>
<target>Balio hau {{ compared_value }} baino handiagoa izan beharko litzateke.</target>
</trans-unit>
<trans-unit id="67">
<source>This value should be greater than or equal to {{ compared_value }}.</source>
<target>Balio honek {{ compared_value }}-(r)en berdina edo handiagoa izan beharko luke.</target>
<target>Balio hau {{ compared_value }}-(r)en berdina edota handiagoa izan beharko litzateke.</target>
</trans-unit>
<trans-unit id="68">
<source>This value should be identical to {{ compared_value_type }} {{ compared_value }}.</source>
<target>Balio honek berbera izan behar du {{ compared_value_type }} {{ compared_value }}.</target>
<target>Balio hau {{ compared_value_type }} {{ compared_value }}-(r)en berbera izan beharko litzateke.</target>
</trans-unit>
<trans-unit id="69">
<source>This value should be less than {{ compared_value }}.</source>
<target>Balio honek {{ compared_value }} baino txikiago izan behar du.</target>
<target>Balio hau {{ compared_value }} baino txikiagoa izan beharko litzateke.</target>
</trans-unit>
<trans-unit id="70">
<source>This value should be less than or equal to {{ compared_value }}.</source>
<target>Balio honek {{ compared_value }}-(r)en berdina edo txikiago izan behar du.</target>
<target>Balio hau {{ compared_value }}-(r)en berdina edota txikiagoa izan beharko litzateke.</target>
</trans-unit>
<trans-unit id="71">
<source>This value should not be equal to {{ compared_value }}.</source>
<target>Balio honek {{ compared_value }}-(r)en berdina izan behar du.</target>
<target>Balio hau ez litzateke {{ compared_value }}-(r)en berdina izan behar.</target>
</trans-unit>
<trans-unit id="72">
<source>This value should not be identical to {{ compared_value_type }} {{ compared_value }}.</source>
<target>Balio honek ez du berbera izan behar {{ compared_value_type }} {{ compared_value }}.</target>
<target>Balio hau ez litzateke {{ compared_value_type }} {{ compared_value }}-(r)en berbera izan behar.</target>
</trans-unit>
</body>
</file>

View File

@ -214,6 +214,70 @@
<source>This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements.</source>
<target>Sąraše turi būti lygiai {{ limit }} įrašas.|Sąraše turi būti lygiai {{ limit }} įrašai.|Sąraše turi būti lygiai {{ limit }} įrašų.</target>
</trans-unit>
<trans-unit id="57">
<source>Invalid card number.</source>
<target>Klaidingas kortelės numeris.</target>
</trans-unit>
<trans-unit id="58">
<source>Unsupported card type or invalid card number.</source>
<target>Kortelės tipas nepalaikomas arba klaidingas kortelės numeris.</target>
</trans-unit>
<trans-unit id="59">
<source>This is not a valid International Bank Account Number (IBAN).</source>
<target>Ši reišmė neatitinka tarptautinio banko sąskaitos numerio formato (IBAN).</target>
</trans-unit>
<trans-unit id="60">
<source>This value is not a valid ISBN-10.</source>
<target>Ši reikšmė neatitinka ISBN-10 formato.</target>
</trans-unit>
<trans-unit id="61">
<source>This value is not a valid ISBN-13.</source>
<target>Ši reikšmė neatitinka ISBN-13 formato.</target>
</trans-unit>
<trans-unit id="62">
<source>This value is neither a valid ISBN-10 nor a valid ISBN-13.</source>
<target>Ši reikšmė neatitinka nei ISBN-10, nei ISBN-13 formato.</target>
</trans-unit>
<trans-unit id="63">
<source>This value is not a valid ISSN.</source>
<target>Ši reišmė neatitinka ISSN formato.</target>
</trans-unit>
<trans-unit id="64">
<source>This value is not a valid currency.</source>
<target>Netinkamas valiutos formatas.</target>
</trans-unit>
<trans-unit id="65">
<source>This value should be equal to {{ compared_value }}.</source>
<target>Ši reikšmė turi būti lygi {{ compared_value }}.</target>
</trans-unit>
<trans-unit id="66">
<source>This value should be greater than {{ compared_value }}.</source>
<target>Ši reikšmė turi būti didesnė už {{ compared_value }}.</target>
</trans-unit>
<trans-unit id="67">
<source>This value should be greater than or equal to {{ compared_value }}.</source>
<target>Ši reikšmė turi būti didesnė už arba lygi {{ compared_value }}.</target>
</trans-unit>
<trans-unit id="68">
<source>This value should be identical to {{ compared_value_type }} {{ compared_value }}.</source>
<target>Ši reikšmė turi būti identiška {{ compared_value_type }} {{ compared_value }}.</target>
</trans-unit>
<trans-unit id="69">
<source>This value should be less than {{ compared_value }}.</source>
<target>Ši reikšmė turi būti mažesnė už {{ compared_value }}.</target>
</trans-unit>
<trans-unit id="70">
<source>This value should be less than or equal to {{ compared_value }}.</source>
<target>Ši reikšmė turi būti mažesnė už arba lygi {{ compared_value }}.</target>
</trans-unit>
<trans-unit id="71">
<source>This value should not be equal to {{ compared_value }}.</source>
<target>Ši reikšmė neturi būti lygi {{ compared_value }}.</target>
</trans-unit>
<trans-unit id="72">
<source>This value should not be identical to {{ compared_value_type }} {{ compared_value }}.</source>
<target>Ši reikšmė neturi būti identiška {{ compared_value_type }} {{ compared_value }}.</target>
</trans-unit>
</body>
</file>
</xliff>