merged 2.0

This commit is contained in:
Fabien Potencier 2011-10-04 09:32:13 +02:00
commit fbe9aa526e
15 changed files with 326 additions and 94 deletions

View File

@ -52,7 +52,7 @@ class ProxyCacheWarmer implements CacheWarmerInterface
// we need the directory no matter the proxy cache generation strategy
if (!is_dir($proxyCacheDir = $em->getConfiguration()->getProxyDir())) {
if (false === @mkdir($proxyCacheDir, 0777, true)) {
throw new \RuntimeException(sprintf('Unable to create the Doctrine Proxy directory "%s".', dirname($proxyCacheDir)));
throw new \RuntimeException(sprintf('Unable to create the Doctrine Proxy directory "%s".', $proxyCacheDir));
}
} elseif (!is_writable($proxyCacheDir)) {
throw new \RuntimeException(sprintf('The Doctrine Proxy directory "%s" is not writeable for the current system user.', $proxyCacheDir));

View File

@ -21,7 +21,7 @@ use Symfony\Component\HttpFoundation\Request;
*/
class WebProcessor extends BaseWebProcessor
{
public function __construct(RequestInterface $request)
public function __construct(Request $request)
{
parent::__construct($request->server->all());
}

View File

@ -42,14 +42,38 @@ class DoctrineBundle extends Bundle
if ($this->container->hasParameter('doctrine.orm.proxy_namespace')) {
$namespace = $this->container->getParameter('doctrine.orm.proxy_namespace');
$dir = $this->container->getParameter('doctrine.orm.proxy_dir');
$container = $this->container;
spl_autoload_register(function($class) use ($namespace, $dir) {
spl_autoload_register(function($class) use ($namespace, $dir, $container) {
if (0 === strpos($class, $namespace)) {
$className = substr($class, strlen($namespace) +1);
$file = $dir.DIRECTORY_SEPARATOR.$className.'.php';
if (!is_file($file)) {
throw new \RuntimeException(sprintf('The proxy file "%s" does not exist. If you still have objects serialized in the session, you need to clear the session manually.', $file));
if (!is_file($file) && $this->container->getParameter('kernel.debug')) {
$originalClassName = substr($className, 0, -5);
$registry = $container->get('doctrine');
// Tries to auto-generate the proxy file
foreach ($registry->getEntityManagers() as $em) {
if ($em->getConfiguration()->getAutoGenerateProxyClasses()) {
$classes = $em->getMetadataFactory()->getAllMetadata();
foreach ($classes as $class) {
$name = str_replace('\\', '', $class->name);
if ($name == $originalClassName) {
$em->getProxyFactory()->generateProxyClasses(array($class));
}
}
}
}
clearstatcache($file);
if (!is_file($file)) {
throw new \RuntimeException(sprintf('The proxy file "%s" does not exist. If you still have objects serialized in the session, you need to clear the session manually.', $file));
}
}
require $file;

View File

@ -17,6 +17,7 @@
}
],
"require": {
"php": ">=5.3.2"
"php": ">=5.3.2",
"swiftmailer/swiftmailer": ">=4.1.2"
}
}

View File

@ -55,7 +55,7 @@ class DebugUniversalClassLoader extends UniversalClassLoader
if ($file = $this->findFile($class)) {
require $file;
if (!class_exists($class, false) && !interface_exists($class, false) && (!function_exists('trait_exists') || !trait_exists($class))) {
if (!class_exists($class, false) && !interface_exists($class, false) && (!function_exists('trait_exists') || !trait_exists($class, false))) {
throw new \RuntimeException(sprintf('The autoloader expected class "%s" to be defined in file "%s". The file was found but the class was not in it, the class name or namespace probably has a typo.', $class, $file));
}
}

View File

@ -615,7 +615,7 @@ abstract class Kernel implements KernelInterface
foreach (array('cache' => $this->getCacheDir(), 'logs' => $this->getLogDir()) as $name => $dir) {
if (!is_dir($dir)) {
if (false === @mkdir($dir, 0777, true)) {
throw new \RuntimeException(sprintf("Unable to create the %s directory (%s)\n", $name, dirname($dir)));
throw new \RuntimeException(sprintf("Unable to create the %s directory (%s)\n", $name, $dir));
}
} elseif (!is_writable($dir)) {
throw new \RuntimeException(sprintf("Unable to write in the %s directory (%s)\n", $name, $dir));

View File

@ -91,7 +91,7 @@ EOF;
if ($optimizable) {
for ($j = $i; $j < $keysCount; $j++) {
if ($keys[$j] === null) {
continue;
continue;
}
$testRoute = $routeIterator->offsetGet($keys[$j]);

View File

@ -16,6 +16,9 @@ use Symfony\Component\Config\Resource\ResourceInterface;
/**
* A RouteCollection represents a set of Route instances.
*
* When adding a route, it overrides existing routes with the
* same name defined in theinstance or its children and parents.
*
* @author Fabien Potencier <fabien@symfony.com>
*
* @api
@ -25,6 +28,7 @@ class RouteCollection implements \IteratorAggregate
private $routes;
private $resources;
private $prefix;
private $parent;
/**
* Constructor.
@ -38,6 +42,31 @@ class RouteCollection implements \IteratorAggregate
$this->prefix = '';
}
/**
* Gets the parent RouteCollection.
*
* @return RouteCollection The parent RouteCollection
*/
public function getParent()
{
return $this->parent;
}
/**
* Sets the parent RouteCollection.
*
* @param RouteCollection $parent The parent RouteCollection
*/
public function setParent(RouteCollection $parent)
{
$this->parent = $parent;
}
/**
* Gets the current RouteCollection as an Iterator.
*
* @return \ArrayIterator An \ArrayIterator interface
*/
public function getIterator()
{
return new \ArrayIterator($this->routes);
@ -59,6 +88,15 @@ class RouteCollection implements \IteratorAggregate
throw new \InvalidArgumentException(sprintf('Name "%s" contains non valid characters for a route name.', $name));
}
$parent = $this;
while ($parent->getParent()) {
$parent = $parent->getParent();
}
if ($parent) {
$parent->remove($name);
}
$this->routes[$name] = $route;
}
@ -106,6 +144,24 @@ class RouteCollection implements \IteratorAggregate
}
}
/**
* Removes a route by name.
*
* @param string $name The route name
*/
public function remove($name)
{
if (isset($this->routes[$name])) {
unset($this->routes[$name]);
}
foreach ($this->routes as $routes) {
if ($routes instanceof RouteCollection) {
$routes->remove($name);
}
}
}
/**
* Adds a route collection to the current set of routes (at the end of the current set).
*
@ -116,8 +172,14 @@ class RouteCollection implements \IteratorAggregate
*/
public function addCollection(RouteCollection $collection, $prefix = '')
{
$collection->setParent($this);
$collection->addPrefix($prefix);
// remove all routes with the same name in all existing collections
foreach (array_keys($collection->all()) as $name) {
$this->remove($name);
}
$this->routes[] = $collection;
}

View File

@ -0,0 +1,54 @@
<?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\Tests\Bridge\Monolog\Processor;
use Monolog\Logger;
use Symfony\Bridge\Monolog\Processor\WebProcessor;
use Symfony\Component\HttpFoundation\Request;
class WebProcessorTest extends \PHPUnit_Framework_TestCase
{
public function testUsesRequestServerData()
{
$server = array(
'REQUEST_URI' => 'A',
'REMOTE_ADDR' => 'B',
'REQUEST_METHOD' => 'C',
);
$request = new Request();
$request->server->replace($server);
$processor = new WebProcessor($request);
$record = $processor($this->getRecord());
$this->assertEquals($server['REQUEST_URI'], $record['extra']['url']);
$this->assertEquals($server['REMOTE_ADDR'], $record['extra']['ip']);
$this->assertEquals($server['REQUEST_METHOD'], $record['extra']['http_method']);
}
/**
* @return array Record
*/
protected function getRecord($level = Logger::WARNING, $message = 'test')
{
return array(
'message' => $message,
'context' => array(),
'level' => $level,
'level_name' => Logger::getLevelName($level),
'channel' => 'test',
'datetime' => new \DateTime(),
'extra' => array(),
);
}
}

View File

@ -108,30 +108,35 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Matcher\UrlMatcher
if (0 === strpos($pathinfo, '/a')) {
if (0 === strpos($pathinfo, '/a/b\'b')) {
// foo
if (preg_match('#^/a/b\'b/(?P<foo>[^/]+?)$#xs', $pathinfo, $matches)) {
$matches['_route'] = 'foo';
return $matches;
}
// bar
if (preg_match('#^/a/b\'b/(?P<bar>[^/]+?)$#xs', $pathinfo, $matches)) {
$matches['_route'] = 'bar';
return $matches;
}
// foo1
if (preg_match('#^/a/b\'b/(?P<foo1>[^/]+?)$#xs', $pathinfo, $matches)) {
if (preg_match('#^/a/b\'b/(?P<foo>[^/]+?)$#xs', $pathinfo, $matches)) {
$matches['_route'] = 'foo1';
return $matches;
}
// bar1
if (preg_match('#^/a/b\'b/(?P<bar1>[^/]+?)$#xs', $pathinfo, $matches)) {
if (preg_match('#^/a/b\'b/(?P<bar>[^/]+?)$#xs', $pathinfo, $matches)) {
$matches['_route'] = 'bar1';
return $matches;
}
// foo2
if (preg_match('#^/a/b\'b/(?P<foo1>[^/]+?)$#xs', $pathinfo, $matches)) {
$matches['_route'] = 'foo2';
return $matches;
}
// bar2
if (preg_match('#^/a/b\'b/(?P<bar1>[^/]+?)$#xs', $pathinfo, $matches)) {
$matches['_route'] = 'bar2';
return $matches;
}
}
// overriden
if ($pathinfo === '/a/overriden2') {
return array('_route' => 'overriden');
}
// ababa
@ -139,23 +144,23 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Matcher\UrlMatcher
return array('_route' => 'ababa');
}
// foo
// foo4
if (preg_match('#^/aba/(?P<foo>[^/]+?)$#xs', $pathinfo, $matches)) {
$matches['_route'] = 'foo';
$matches['_route'] = 'foo4';
return $matches;
}
}
// foo
// foo3
if (preg_match('#^/(?P<_locale>[^/]+?)/b/(?P<foo>[^/]+?)$#xs', $pathinfo, $matches)) {
$matches['_route'] = 'foo';
$matches['_route'] = 'foo3';
return $matches;
}
// bar
// bar3
if (preg_match('#^/(?P<_locale>[^/]+?)/b/(?P<bar>[^/]+?)$#xs', $pathinfo, $matches)) {
$matches['_route'] = 'bar';
$matches['_route'] = 'bar3';
return $matches;
}

View File

@ -120,30 +120,35 @@ class ProjectUrlMatcher extends Symfony\Tests\Component\Routing\Fixtures\Redirec
if (0 === strpos($pathinfo, '/a')) {
if (0 === strpos($pathinfo, '/a/b\'b')) {
// foo
if (preg_match('#^/a/b\'b/(?P<foo>[^/]+?)$#xs', $pathinfo, $matches)) {
$matches['_route'] = 'foo';
return $matches;
}
// bar
if (preg_match('#^/a/b\'b/(?P<bar>[^/]+?)$#xs', $pathinfo, $matches)) {
$matches['_route'] = 'bar';
return $matches;
}
// foo1
if (preg_match('#^/a/b\'b/(?P<foo1>[^/]+?)$#xs', $pathinfo, $matches)) {
if (preg_match('#^/a/b\'b/(?P<foo>[^/]+?)$#xs', $pathinfo, $matches)) {
$matches['_route'] = 'foo1';
return $matches;
}
// bar1
if (preg_match('#^/a/b\'b/(?P<bar1>[^/]+?)$#xs', $pathinfo, $matches)) {
if (preg_match('#^/a/b\'b/(?P<bar>[^/]+?)$#xs', $pathinfo, $matches)) {
$matches['_route'] = 'bar1';
return $matches;
}
// foo2
if (preg_match('#^/a/b\'b/(?P<foo1>[^/]+?)$#xs', $pathinfo, $matches)) {
$matches['_route'] = 'foo2';
return $matches;
}
// bar2
if (preg_match('#^/a/b\'b/(?P<bar1>[^/]+?)$#xs', $pathinfo, $matches)) {
$matches['_route'] = 'bar2';
return $matches;
}
}
// overriden
if ($pathinfo === '/a/overriden2') {
return array('_route' => 'overriden');
}
// ababa
@ -151,23 +156,23 @@ class ProjectUrlMatcher extends Symfony\Tests\Component\Routing\Fixtures\Redirec
return array('_route' => 'ababa');
}
// foo
// foo4
if (preg_match('#^/aba/(?P<foo>[^/]+?)$#xs', $pathinfo, $matches)) {
$matches['_route'] = 'foo';
$matches['_route'] = 'foo4';
return $matches;
}
}
// foo
// foo3
if (preg_match('#^/(?P<_locale>[^/]+?)/b/(?P<foo>[^/]+?)$#xs', $pathinfo, $matches)) {
$matches['_route'] = 'foo';
$matches['_route'] = 'foo3';
return $matches;
}
// bar
// bar3
if (preg_match('#^/(?P<_locale>[^/]+?)/b/(?P<bar>[^/]+?)$#xs', $pathinfo, $matches)) {
$matches['_route'] = 'bar';
$matches['_route'] = 'bar3';
return $matches;
}

View File

@ -19,8 +19,52 @@ use Symfony\Component\Routing\RequestContext;
class PhpMatcherDumperTest extends \PHPUnit_Framework_TestCase
{
public function testDump()
{
$dumper = new PhpMatcherDumper($this->getRouteCollection(), new RequestContext());
$this->assertStringEqualsFile(__DIR__.'/../../Fixtures/dumper/url_matcher1.php', $dumper->dump(), '->dump() dumps basic routes to the correct PHP file.');
$collection = $this->getRouteCollection();
// force HTTPS redirection
$collection->add('secure', new Route(
'/secure',
array(),
array('_scheme' => 'https')
));
// force HTTP redirection
$collection->add('nonsecure', new Route(
'/nonsecure',
array(),
array('_scheme' => 'http')
));
$dumper = new PhpMatcherDumper($collection, new RequestContext());
$this->assertStringEqualsFile(__DIR__.'/../../Fixtures/dumper/url_matcher2.php', $dumper->dump(array('base_class' => 'Symfony\Tests\Component\Routing\Fixtures\RedirectableUrlMatcher')), '->dump() dumps basic routes to the correct PHP file.');
}
/**
* @expectedException \LogicException
*/
public function testDumpWhenSchemeIsUsedWithoutAProperDumper()
{
$collection = new RouteCollection();
$collection->add('secure', new Route(
'/secure',
array(),
array('_scheme' => 'https')
));
$dumper = new PhpMatcherDumper($collection, new RequestContext());
$dumper->dump();
}
protected function getRouteCollection()
{
$collection = new RouteCollection();
$collection->add('overriden', new Route('/overriden'));
// defaults and requirements
$collection->add('foo', new Route(
@ -82,20 +126,22 @@ class PhpMatcherDumperTest extends \PHPUnit_Framework_TestCase
// prefixes
$collection1 = new RouteCollection();
$collection1->add('foo', new Route('/{foo}'));
$collection1->add('bar', new Route('/{bar}'));
$collection1->add('overriden', new Route('/overriden1'));
$collection1->add('foo1', new Route('/{foo}'));
$collection1->add('bar1', new Route('/{bar}'));
$collection2 = new RouteCollection();
$collection2->addCollection($collection1, '/b\'b');
$collection2->add('overriden', new Route('/overriden2'));
$collection1 = new RouteCollection();
$collection1->add('foo1', new Route('/{foo1}'));
$collection1->add('bar1', new Route('/{bar1}'));
$collection1->add('foo2', new Route('/{foo1}'));
$collection1->add('bar2', new Route('/{bar1}'));
$collection2->addCollection($collection1, '/b\'b');
$collection->addCollection($collection2, '/a');
// "dynamic" prefix
$collection1 = new RouteCollection();
$collection1->add('foo', new Route('/{foo}'));
$collection1->add('bar', new Route('/{bar}'));
$collection1->add('foo3', new Route('/{foo}'));
$collection1->add('bar3', new Route('/{bar}'));
$collection2 = new RouteCollection();
$collection2->addCollection($collection1, '/b');
$collection->addCollection($collection2, '/{_locale}');
@ -104,42 +150,9 @@ class PhpMatcherDumperTest extends \PHPUnit_Framework_TestCase
// some more prefixes
$collection1 = new RouteCollection();
$collection1->add('foo', new Route('/{foo}'));
$collection1->add('foo4', new Route('/{foo}'));
$collection->addCollection($collection1, '/aba');
$dumper = new PhpMatcherDumper($collection, new RequestContext());
$this->assertStringEqualsFile(__DIR__.'/../../Fixtures/dumper/url_matcher1.php', $dumper->dump(), '->dump() dumps basic routes to the correct PHP file.');
// force HTTPS redirection
$collection->add('secure', new Route(
'/secure',
array(),
array('_scheme' => 'https')
));
// force HTTP redirection
$collection->add('nonsecure', new Route(
'/nonsecure',
array(),
array('_scheme' => 'http')
));
$this->assertStringEqualsFile(__DIR__.'/../../Fixtures/dumper/url_matcher2.php', $dumper->dump(array('base_class' => 'Symfony\Tests\Component\Routing\Fixtures\RedirectableUrlMatcher')), '->dump() dumps basic routes to the correct PHP file.');
}
/**
* @expectedException \LogicException
*/
public function testDumpWhenSchemeIsUsedWithoutAProperDumper()
{
$collection = new RouteCollection();
$collection->add('secure', new Route(
'/secure',
array(),
array('_scheme' => 'https')
));
$dumper = new PhpMatcherDumper($collection, new RequestContext());
$dumper->dump();
return $collection;
}
}

View File

@ -170,6 +170,23 @@ class UrlMatcherTest extends \PHPUnit_Framework_TestCase
$this->assertEquals(array('_route' => 'foo', 'foo' => "\n"), $matcher->match('/'.urlencode("\n").'/bar'), 'linefeed character is matched');
}
public function testMatchOverridenRoute()
{
$collection = new RouteCollection();
$collection->add('foo', new Route('/foo'));
$collection1 = new RouteCollection();
$collection1->add('foo', new Route('/foo1'));
$collection->addCollection($collection1);
$matcher = new UrlMatcher($collection, new RequestContext(), array());
$this->assertEquals(array('_route' => 'foo'), $matcher->match('/foo1'));
$this->setExpectedException('Symfony\Component\Routing\Exception\ResourceNotFoundException');
$this->assertEquals(array(), $matcher->match('/foo'));
}
public function testMatchRegression()
{
$coll = new RouteCollection();
@ -188,4 +205,4 @@ class UrlMatcherTest extends \PHPUnit_Framework_TestCase
} catch (ResourceNotFoundException $e) {
}
}
}
}

View File

@ -28,7 +28,6 @@ class RouteCollectionTest extends \PHPUnit_Framework_TestCase
}
/**
* @covers Symfony\Component\Routing\RouteCollection::add
* @expectedException InvalidArgumentException
*/
public function testAddInvalidRoute()
@ -38,6 +37,58 @@ class RouteCollectionTest extends \PHPUnit_Framework_TestCase
$collection->add('f o o', $route);
}
public function testOverridenRoute()
{
$collection = new RouteCollection();
$collection->add('foo', new Route('/foo'));
$collection->add('foo', new Route('/foo1'));
$this->assertEquals('/foo1', $collection->get('foo')->getPattern());
}
public function testDeepOverridenRoute()
{
$collection = new RouteCollection();
$collection->add('foo', new Route('/foo'));
$collection1 = new RouteCollection();
$collection1->add('foo', new Route('/foo1'));
$collection2 = new RouteCollection();
$collection2->add('foo', new Route('/foo2'));
$collection1->addCollection($collection2);
$collection->addCollection($collection1);
$this->assertEquals('/foo2', $collection1->get('foo')->getPattern());
$this->assertEquals('/foo2', $collection->get('foo')->getPattern());
}
public function testIteratorWithOverridenRoutes()
{
$collection = new RouteCollection();
$collection->add('foo', new Route('/foo'));
$collection1 = new RouteCollection();
$collection->addCollection($collection1);
$collection1->add('foo', new Route('/foo1'));
$this->assertEquals('/foo1', $this->getFirstNamedRoute($collection, 'foo')->getPattern());
}
protected function getFirstNamedRoute(RouteCollection $routeCollection, $name)
{
foreach ($routeCollection as $key => $route) {
if ($route instanceof RouteCollection) {
return $this->getFirstNamedRoute($route, $name);
}
if ($name === $key) {
return $route;
}
}
}
public function testAddCollection()
{
$collection = new RouteCollection();

View File

@ -28,7 +28,7 @@ class XliffFileLoaderTest extends \PHPUnit_Framework_TestCase
}
/**
* @expectedException Exception
* @expectedException \RuntimeException
*/
public function testLoadInvalidResource()
{
@ -37,7 +37,7 @@ class XliffFileLoaderTest extends \PHPUnit_Framework_TestCase
}
/**
* @expectedException Exception
* @expectedException \RuntimeException
*/
public function testLoadResourceDoesNotValidate()
{