Include copy of Symfony routing component, and don't use composer
This commit is contained in:
parent
8a3eda16f2
commit
c1c76539cc
|
@ -54,7 +54,3 @@ nbproject
|
|||
# WebFinger
|
||||
.well-known
|
||||
/.buildpath
|
||||
3rdparty/autoload.php
|
||||
3rdparty/composer/
|
||||
3rdparty/symfony/
|
||||
composer.lock
|
||||
|
|
Binary file not shown.
|
@ -0,0 +1,103 @@
|
|||
<?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\Component\Routing\Annotation;
|
||||
|
||||
/**
|
||||
* Annotation class for @Route().
|
||||
*
|
||||
* @Annotation
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
class Route
|
||||
{
|
||||
private $pattern;
|
||||
private $name;
|
||||
private $requirements;
|
||||
private $options;
|
||||
private $defaults;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param array $data An array of key/value parameters.
|
||||
*/
|
||||
public function __construct(array $data)
|
||||
{
|
||||
$this->requirements = array();
|
||||
$this->options = array();
|
||||
$this->defaults = array();
|
||||
|
||||
if (isset($data['value'])) {
|
||||
$data['pattern'] = $data['value'];
|
||||
unset($data['value']);
|
||||
}
|
||||
|
||||
foreach ($data as $key => $value) {
|
||||
$method = 'set'.$key;
|
||||
if (!method_exists($this, $method)) {
|
||||
throw new \BadMethodCallException(sprintf("Unknown property '%s' on annotation '%s'.", $key, get_class($this)));
|
||||
}
|
||||
$this->$method($value);
|
||||
}
|
||||
}
|
||||
|
||||
public function setPattern($pattern)
|
||||
{
|
||||
$this->pattern = $pattern;
|
||||
}
|
||||
|
||||
public function getPattern()
|
||||
{
|
||||
return $this->pattern;
|
||||
}
|
||||
|
||||
public function setName($name)
|
||||
{
|
||||
$this->name = $name;
|
||||
}
|
||||
|
||||
public function getName()
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
public function setRequirements($requirements)
|
||||
{
|
||||
$this->requirements = $requirements;
|
||||
}
|
||||
|
||||
public function getRequirements()
|
||||
{
|
||||
return $this->requirements;
|
||||
}
|
||||
|
||||
public function setOptions($options)
|
||||
{
|
||||
$this->options = $options;
|
||||
}
|
||||
|
||||
public function getOptions()
|
||||
{
|
||||
return $this->options;
|
||||
}
|
||||
|
||||
public function setDefaults($defaults)
|
||||
{
|
||||
$this->defaults = $defaults;
|
||||
}
|
||||
|
||||
public function getDefaults()
|
||||
{
|
||||
return $this->defaults;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,134 @@
|
|||
<?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\Component\Routing;
|
||||
|
||||
/**
|
||||
* CompiledRoutes are returned by the RouteCompiler class.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
class CompiledRoute
|
||||
{
|
||||
private $route;
|
||||
private $variables;
|
||||
private $tokens;
|
||||
private $staticPrefix;
|
||||
private $regex;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param Route $route A original Route instance
|
||||
* @param string $staticPrefix The static prefix of the compiled route
|
||||
* @param string $regex The regular expression to use to match this route
|
||||
* @param array $tokens An array of tokens to use to generate URL for this route
|
||||
* @param array $variables An array of variables
|
||||
*/
|
||||
public function __construct(Route $route, $staticPrefix, $regex, array $tokens, array $variables)
|
||||
{
|
||||
$this->route = $route;
|
||||
$this->staticPrefix = $staticPrefix;
|
||||
$this->regex = $regex;
|
||||
$this->tokens = $tokens;
|
||||
$this->variables = $variables;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the Route instance.
|
||||
*
|
||||
* @return Route A Route instance
|
||||
*/
|
||||
public function getRoute()
|
||||
{
|
||||
return $this->route;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the static prefix.
|
||||
*
|
||||
* @return string The static prefix
|
||||
*/
|
||||
public function getStaticPrefix()
|
||||
{
|
||||
return $this->staticPrefix;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the regex.
|
||||
*
|
||||
* @return string The regex
|
||||
*/
|
||||
public function getRegex()
|
||||
{
|
||||
return $this->regex;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the tokens.
|
||||
*
|
||||
* @return array The tokens
|
||||
*/
|
||||
public function getTokens()
|
||||
{
|
||||
return $this->tokens;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the variables.
|
||||
*
|
||||
* @return array The variables
|
||||
*/
|
||||
public function getVariables()
|
||||
{
|
||||
return $this->variables;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the pattern.
|
||||
*
|
||||
* @return string The pattern
|
||||
*/
|
||||
public function getPattern()
|
||||
{
|
||||
return $this->route->getPattern();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the options.
|
||||
*
|
||||
* @return array The options
|
||||
*/
|
||||
public function getOptions()
|
||||
{
|
||||
return $this->route->getOptions();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the defaults.
|
||||
*
|
||||
* @return array The defaults
|
||||
*/
|
||||
public function getDefaults()
|
||||
{
|
||||
return $this->route->getDefaults();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the requirements.
|
||||
*
|
||||
* @return array The requirements
|
||||
*/
|
||||
public function getRequirements()
|
||||
{
|
||||
return $this->route->getRequirements();
|
||||
}
|
||||
}
|
23
3rdparty/symfony/routing/Symfony/Component/Routing/Exception/ExceptionInterface.php
vendored
Normal file
23
3rdparty/symfony/routing/Symfony/Component/Routing/Exception/ExceptionInterface.php
vendored
Normal file
|
@ -0,0 +1,23 @@
|
|||
<?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\Component\Routing\Exception;
|
||||
|
||||
/**
|
||||
* ExceptionInterface
|
||||
*
|
||||
* @author Alexandre Salomé <alexandre.salome@gmail.com>
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
interface ExceptionInterface
|
||||
{
|
||||
}
|
23
3rdparty/symfony/routing/Symfony/Component/Routing/Exception/InvalidParameterException.php
vendored
Normal file
23
3rdparty/symfony/routing/Symfony/Component/Routing/Exception/InvalidParameterException.php
vendored
Normal file
|
@ -0,0 +1,23 @@
|
|||
<?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\Component\Routing\Exception;
|
||||
|
||||
/**
|
||||
* Exception thrown when a parameter is not valid
|
||||
*
|
||||
* @author Alexandre Salomé <alexandre.salome@gmail.com>
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
class InvalidParameterException extends \InvalidArgumentException implements ExceptionInterface
|
||||
{
|
||||
}
|
38
3rdparty/symfony/routing/Symfony/Component/Routing/Exception/MethodNotAllowedException.php
vendored
Normal file
38
3rdparty/symfony/routing/Symfony/Component/Routing/Exception/MethodNotAllowedException.php
vendored
Normal file
|
@ -0,0 +1,38 @@
|
|||
<?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\Component\Routing\Exception;
|
||||
|
||||
/**
|
||||
* The resource was found but the request method is not allowed.
|
||||
*
|
||||
* This exception should trigger an HTTP 405 response in your application code.
|
||||
*
|
||||
* @author Kris Wallsmith <kris@symfony.com>
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
class MethodNotAllowedException extends \RuntimeException implements ExceptionInterface
|
||||
{
|
||||
protected $allowedMethods;
|
||||
|
||||
public function __construct(array $allowedMethods, $message = null, $code = 0, \Exception $previous = null)
|
||||
{
|
||||
$this->allowedMethods = array_map('strtoupper', $allowedMethods);
|
||||
|
||||
parent::__construct($message, $code, $previous);
|
||||
}
|
||||
|
||||
public function getAllowedMethods()
|
||||
{
|
||||
return $this->allowedMethods;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
<?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\Component\Routing\Exception;
|
||||
|
||||
/**
|
||||
* Exception thrown when a route cannot be generated because of missing
|
||||
* mandatory parameters.
|
||||
*
|
||||
* @author Alexandre Salomé <alexandre.salome@gmail.com>
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
class MissingMandatoryParametersException extends \InvalidArgumentException implements ExceptionInterface
|
||||
{
|
||||
}
|
25
3rdparty/symfony/routing/Symfony/Component/Routing/Exception/ResourceNotFoundException.php
vendored
Normal file
25
3rdparty/symfony/routing/Symfony/Component/Routing/Exception/ResourceNotFoundException.php
vendored
Normal file
|
@ -0,0 +1,25 @@
|
|||
<?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\Component\Routing\Exception;
|
||||
|
||||
/**
|
||||
* The resource was not found.
|
||||
*
|
||||
* This exception should trigger an HTTP 404 response in your application code.
|
||||
*
|
||||
* @author Kris Wallsmith <kris@symfony.com>
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
class ResourceNotFoundException extends \RuntimeException implements ExceptionInterface
|
||||
{
|
||||
}
|
23
3rdparty/symfony/routing/Symfony/Component/Routing/Exception/RouteNotFoundException.php
vendored
Normal file
23
3rdparty/symfony/routing/Symfony/Component/Routing/Exception/RouteNotFoundException.php
vendored
Normal file
|
@ -0,0 +1,23 @@
|
|||
<?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\Component\Routing\Exception;
|
||||
|
||||
/**
|
||||
* Exception thrown when a route does not exists
|
||||
*
|
||||
* @author Alexandre Salomé <alexandre.salome@gmail.com>
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
class RouteNotFoundException extends \InvalidArgumentException implements ExceptionInterface
|
||||
{
|
||||
}
|
39
3rdparty/symfony/routing/Symfony/Component/Routing/Generator/Dumper/GeneratorDumper.php
vendored
Normal file
39
3rdparty/symfony/routing/Symfony/Component/Routing/Generator/Dumper/GeneratorDumper.php
vendored
Normal file
|
@ -0,0 +1,39 @@
|
|||
<?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\Component\Routing\Generator\Dumper;
|
||||
|
||||
use Symfony\Component\Routing\RouteCollection;
|
||||
|
||||
/**
|
||||
* GeneratorDumper is the base class for all built-in generator dumpers.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
abstract class GeneratorDumper implements GeneratorDumperInterface
|
||||
{
|
||||
private $routes;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param RouteCollection $routes The RouteCollection to dump
|
||||
*/
|
||||
public function __construct(RouteCollection $routes)
|
||||
{
|
||||
$this->routes = $routes;
|
||||
}
|
||||
|
||||
public function getRoutes()
|
||||
{
|
||||
return $this->routes;
|
||||
}
|
||||
}
|
45
3rdparty/symfony/routing/Symfony/Component/Routing/Generator/Dumper/GeneratorDumperInterface.php
vendored
Normal file
45
3rdparty/symfony/routing/Symfony/Component/Routing/Generator/Dumper/GeneratorDumperInterface.php
vendored
Normal file
|
@ -0,0 +1,45 @@
|
|||
<?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\Component\Routing\Generator\Dumper;
|
||||
|
||||
use Symfony\Component\Routing\RouteCollection;
|
||||
|
||||
/**
|
||||
* GeneratorDumperInterface is the interface that all generator dumper classes must implement.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
interface GeneratorDumperInterface
|
||||
{
|
||||
/**
|
||||
* Dumps a set of routes to a PHP class.
|
||||
*
|
||||
* Available options:
|
||||
*
|
||||
* * class: The class name
|
||||
* * base_class: The base class name
|
||||
*
|
||||
* @param array $options An array of options
|
||||
*
|
||||
* @return string A PHP class representing the generator class
|
||||
*/
|
||||
public function dump(array $options = array());
|
||||
|
||||
/**
|
||||
* Gets the routes to dump.
|
||||
*
|
||||
* @return RouteCollection A RouteCollection instance
|
||||
*/
|
||||
public function getRoutes();
|
||||
}
|
150
3rdparty/symfony/routing/Symfony/Component/Routing/Generator/Dumper/PhpGeneratorDumper.php
vendored
Normal file
150
3rdparty/symfony/routing/Symfony/Component/Routing/Generator/Dumper/PhpGeneratorDumper.php
vendored
Normal file
|
@ -0,0 +1,150 @@
|
|||
<?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\Component\Routing\Generator\Dumper;
|
||||
|
||||
use Symfony\Component\Routing\Route;
|
||||
|
||||
/**
|
||||
* PhpGeneratorDumper creates a PHP class able to generate URLs for a given set of routes.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
class PhpGeneratorDumper extends GeneratorDumper
|
||||
{
|
||||
/**
|
||||
* Dumps a set of routes to a PHP class.
|
||||
*
|
||||
* Available options:
|
||||
*
|
||||
* * class: The class name
|
||||
* * base_class: The base class name
|
||||
*
|
||||
* @param array $options An array of options
|
||||
*
|
||||
* @return string A PHP class representing the generator class
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function dump(array $options = array())
|
||||
{
|
||||
$options = array_merge(array(
|
||||
'class' => 'ProjectUrlGenerator',
|
||||
'base_class' => 'Symfony\\Component\\Routing\\Generator\\UrlGenerator',
|
||||
), $options);
|
||||
|
||||
return
|
||||
$this->startClass($options['class'], $options['base_class']).
|
||||
$this->addConstructor().
|
||||
$this->addGenerator().
|
||||
$this->endClass()
|
||||
;
|
||||
}
|
||||
|
||||
private function addGenerator()
|
||||
{
|
||||
$methods = array();
|
||||
foreach ($this->getRoutes()->all() as $name => $route) {
|
||||
$compiledRoute = $route->compile();
|
||||
|
||||
$variables = str_replace("\n", '', var_export($compiledRoute->getVariables(), true));
|
||||
$defaults = str_replace("\n", '', var_export($compiledRoute->getDefaults(), true));
|
||||
$requirements = str_replace("\n", '', var_export($compiledRoute->getRequirements(), true));
|
||||
$tokens = str_replace("\n", '', var_export($compiledRoute->getTokens(), true));
|
||||
|
||||
$escapedName = str_replace('.', '__', $name);
|
||||
|
||||
$methods[] = <<<EOF
|
||||
private function get{$escapedName}RouteInfo()
|
||||
{
|
||||
return array($variables, $defaults, $requirements, $tokens);
|
||||
}
|
||||
|
||||
EOF
|
||||
;
|
||||
}
|
||||
|
||||
$methods = implode("\n", $methods);
|
||||
|
||||
return <<<EOF
|
||||
|
||||
public function generate(\$name, \$parameters = array(), \$absolute = false)
|
||||
{
|
||||
if (!isset(self::\$declaredRouteNames[\$name])) {
|
||||
throw new RouteNotFoundException(sprintf('Route "%s" does not exist.', \$name));
|
||||
}
|
||||
|
||||
\$escapedName = str_replace('.', '__', \$name);
|
||||
|
||||
list(\$variables, \$defaults, \$requirements, \$tokens) = \$this->{'get'.\$escapedName.'RouteInfo'}();
|
||||
|
||||
return \$this->doGenerate(\$variables, \$defaults, \$requirements, \$tokens, \$parameters, \$name, \$absolute);
|
||||
}
|
||||
|
||||
$methods
|
||||
EOF;
|
||||
}
|
||||
|
||||
private function startClass($class, $baseClass)
|
||||
{
|
||||
$routes = array();
|
||||
foreach ($this->getRoutes()->all() as $name => $route) {
|
||||
$routes[] = " '$name' => true,";
|
||||
}
|
||||
$routes = implode("\n", $routes);
|
||||
|
||||
return <<<EOF
|
||||
<?php
|
||||
|
||||
use Symfony\Component\Routing\RequestContext;
|
||||
use Symfony\Component\Routing\Exception\RouteNotFoundException;
|
||||
|
||||
|
||||
/**
|
||||
* $class
|
||||
*
|
||||
* This class has been auto-generated
|
||||
* by the Symfony Routing Component.
|
||||
*/
|
||||
class $class extends $baseClass
|
||||
{
|
||||
static private \$declaredRouteNames = array(
|
||||
$routes
|
||||
);
|
||||
|
||||
|
||||
EOF;
|
||||
}
|
||||
|
||||
private function addConstructor()
|
||||
{
|
||||
return <<<EOF
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
public function __construct(RequestContext \$context)
|
||||
{
|
||||
\$this->context = \$context;
|
||||
}
|
||||
|
||||
EOF;
|
||||
}
|
||||
|
||||
private function endClass()
|
||||
{
|
||||
return <<<EOF
|
||||
}
|
||||
|
||||
EOF;
|
||||
}
|
||||
}
|
176
3rdparty/symfony/routing/Symfony/Component/Routing/Generator/UrlGenerator.php
vendored
Normal file
176
3rdparty/symfony/routing/Symfony/Component/Routing/Generator/UrlGenerator.php
vendored
Normal file
|
@ -0,0 +1,176 @@
|
|||
<?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\Component\Routing\Generator;
|
||||
|
||||
use Symfony\Component\Routing\Route;
|
||||
use Symfony\Component\Routing\RouteCollection;
|
||||
use Symfony\Component\Routing\RequestContext;
|
||||
use Symfony\Component\Routing\Exception\InvalidParameterException;
|
||||
use Symfony\Component\Routing\Exception\RouteNotFoundException;
|
||||
use Symfony\Component\Routing\Exception\MissingMandatoryParametersException;
|
||||
|
||||
/**
|
||||
* UrlGenerator generates URL based on a set of routes.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
class UrlGenerator implements UrlGeneratorInterface
|
||||
{
|
||||
protected $context;
|
||||
protected $decodedChars = array(
|
||||
// %2F is not valid in a URL, so we don't encode it (which is fine as the requirements explicitly allowed it)
|
||||
'%2F' => '/',
|
||||
);
|
||||
|
||||
protected $routes;
|
||||
protected $cache;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param RouteCollection $routes A RouteCollection instance
|
||||
* @param RequestContext $context The context
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function __construct(RouteCollection $routes, RequestContext $context)
|
||||
{
|
||||
$this->routes = $routes;
|
||||
$this->context = $context;
|
||||
$this->cache = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the request context.
|
||||
*
|
||||
* @param RequestContext $context The context
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function setContext(RequestContext $context)
|
||||
{
|
||||
$this->context = $context;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the request context.
|
||||
*
|
||||
* @return RequestContext The context
|
||||
*/
|
||||
public function getContext()
|
||||
{
|
||||
return $this->context;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a URL from the given parameters.
|
||||
*
|
||||
* @param string $name The name of the route
|
||||
* @param mixed $parameters An array of parameters
|
||||
* @param Boolean $absolute Whether to generate an absolute URL
|
||||
*
|
||||
* @return string The generated URL
|
||||
*
|
||||
* @throws Symfony\Component\Routing\Exception\RouteNotFoundException When route doesn't exist
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function generate($name, $parameters = array(), $absolute = false)
|
||||
{
|
||||
if (null === $route = $this->routes->get($name)) {
|
||||
throw new RouteNotFoundException(sprintf('Route "%s" does not exist.', $name));
|
||||
}
|
||||
|
||||
if (!isset($this->cache[$name])) {
|
||||
$this->cache[$name] = $route->compile();
|
||||
}
|
||||
|
||||
return $this->doGenerate($this->cache[$name]->getVariables(), $route->getDefaults(), $route->getRequirements(), $this->cache[$name]->getTokens(), $parameters, $name, $absolute);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Symfony\Component\Routing\Exception\MissingMandatoryParametersException When route has some missing mandatory parameters
|
||||
* @throws Symfony\Component\Routing\Exception\InvalidParameterException When a parameter value is not correct
|
||||
*/
|
||||
protected function doGenerate($variables, $defaults, $requirements, $tokens, $parameters, $name, $absolute)
|
||||
{
|
||||
$variables = array_flip($variables);
|
||||
|
||||
$originParameters = $parameters;
|
||||
$parameters = array_replace($this->context->getParameters(), $parameters);
|
||||
$tparams = array_replace($defaults, $parameters);
|
||||
|
||||
// all params must be given
|
||||
if ($diff = array_diff_key($variables, $tparams)) {
|
||||
throw new MissingMandatoryParametersException(sprintf('The "%s" route has some missing mandatory parameters ("%s").', $name, implode('", "', array_keys($diff))));
|
||||
}
|
||||
|
||||
$url = '';
|
||||
$optional = true;
|
||||
foreach ($tokens as $token) {
|
||||
if ('variable' === $token[0]) {
|
||||
if (false === $optional || !array_key_exists($token[3], $defaults) || (isset($parameters[$token[3]]) && (string) $parameters[$token[3]] != (string) $defaults[$token[3]])) {
|
||||
if (!$isEmpty = in_array($tparams[$token[3]], array(null, '', false), true)) {
|
||||
// check requirement
|
||||
if ($tparams[$token[3]] && !preg_match('#^'.$token[2].'$#', $tparams[$token[3]])) {
|
||||
throw new InvalidParameterException(sprintf('Parameter "%s" for route "%s" must match "%s" ("%s" given).', $token[3], $name, $token[2], $tparams[$token[3]]));
|
||||
}
|
||||
}
|
||||
|
||||
if (!$isEmpty || !$optional) {
|
||||
$url = $token[1].strtr(rawurlencode($tparams[$token[3]]), $this->decodedChars).$url;
|
||||
}
|
||||
|
||||
$optional = false;
|
||||
}
|
||||
} elseif ('text' === $token[0]) {
|
||||
$url = $token[1].$url;
|
||||
$optional = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$url) {
|
||||
$url = '/';
|
||||
}
|
||||
|
||||
// add a query string if needed
|
||||
$extra = array_diff_key($originParameters, $variables, $defaults);
|
||||
if ($extra && $query = http_build_query($extra, '', '&')) {
|
||||
$url .= '?'.$query;
|
||||
}
|
||||
|
||||
$url = $this->context->getBaseUrl().$url;
|
||||
|
||||
if ($this->context->getHost()) {
|
||||
$scheme = $this->context->getScheme();
|
||||
if (isset($requirements['_scheme']) && ($req = strtolower($requirements['_scheme'])) && $scheme != $req) {
|
||||
$absolute = true;
|
||||
$scheme = $req;
|
||||
}
|
||||
|
||||
if ($absolute) {
|
||||
$port = '';
|
||||
if ('http' === $scheme && 80 != $this->context->getHttpPort()) {
|
||||
$port = ':'.$this->context->getHttpPort();
|
||||
} elseif ('https' === $scheme && 443 != $this->context->getHttpsPort()) {
|
||||
$port = ':'.$this->context->getHttpsPort();
|
||||
}
|
||||
|
||||
$url = $scheme.'://'.$this->context->getHost().$port.$url;
|
||||
}
|
||||
}
|
||||
|
||||
return $url;
|
||||
}
|
||||
}
|
37
3rdparty/symfony/routing/Symfony/Component/Routing/Generator/UrlGeneratorInterface.php
vendored
Normal file
37
3rdparty/symfony/routing/Symfony/Component/Routing/Generator/UrlGeneratorInterface.php
vendored
Normal file
|
@ -0,0 +1,37 @@
|
|||
<?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\Component\Routing\Generator;
|
||||
|
||||
use Symfony\Component\Routing\RequestContextAwareInterface;
|
||||
|
||||
/**
|
||||
* UrlGeneratorInterface is the interface that all URL generator classes must implements.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
interface UrlGeneratorInterface extends RequestContextAwareInterface
|
||||
{
|
||||
/**
|
||||
* Generates a URL from the given parameters.
|
||||
*
|
||||
* @param string $name The name of the route
|
||||
* @param mixed $parameters An array of parameters
|
||||
* @param Boolean $absolute Whether to generate an absolute URL
|
||||
*
|
||||
* @return string The generated URL
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function generate($name, $parameters = array(), $absolute = false);
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
Copyright (c) 2004-2012 Fabien Potencier
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is furnished
|
||||
to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
213
3rdparty/symfony/routing/Symfony/Component/Routing/Loader/AnnotationClassLoader.php
vendored
Normal file
213
3rdparty/symfony/routing/Symfony/Component/Routing/Loader/AnnotationClassLoader.php
vendored
Normal file
|
@ -0,0 +1,213 @@
|
|||
<?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\Component\Routing\Loader;
|
||||
|
||||
use Doctrine\Common\Annotations\Reader;
|
||||
use Symfony\Component\Config\Resource\FileResource;
|
||||
use Symfony\Component\Routing\Route;
|
||||
use Symfony\Component\Routing\RouteCollection;
|
||||
use Symfony\Component\Config\Loader\LoaderInterface;
|
||||
use Symfony\Component\Config\Loader\LoaderResolver;
|
||||
|
||||
/**
|
||||
* AnnotationClassLoader loads routing information from a PHP class and its methods.
|
||||
*
|
||||
* You need to define an implementation for the getRouteDefaults() method. Most of the
|
||||
* time, this method should define some PHP callable to be called for the route
|
||||
* (a controller in MVC speak).
|
||||
*
|
||||
* The @Route annotation can be set on the class (for global parameters),
|
||||
* and on each method.
|
||||
*
|
||||
* The @Route annotation main value is the route pattern. The annotation also
|
||||
* recognizes three parameters: requirements, options, and name. The name parameter
|
||||
* is mandatory. Here is an example of how you should be able to use it:
|
||||
*
|
||||
* /**
|
||||
* * @Route("/Blog")
|
||||
* * /
|
||||
* class Blog
|
||||
* {
|
||||
* /**
|
||||
* * @Route("/", name="blog_index")
|
||||
* * /
|
||||
* public function index()
|
||||
* {
|
||||
* }
|
||||
*
|
||||
* /**
|
||||
* * @Route("/{id}", name="blog_post", requirements = {"id" = "\d+"})
|
||||
* * /
|
||||
* public function show()
|
||||
* {
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
abstract class AnnotationClassLoader implements LoaderInterface
|
||||
{
|
||||
protected $reader;
|
||||
protected $routeAnnotationClass = 'Symfony\\Component\\Routing\\Annotation\\Route';
|
||||
protected $defaultRouteIndex;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param Reader $reader
|
||||
*/
|
||||
public function __construct(Reader $reader)
|
||||
{
|
||||
$this->reader = $reader;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the annotation class to read route properties from.
|
||||
*
|
||||
* @param string $class A fully-qualified class name
|
||||
*/
|
||||
public function setRouteAnnotationClass($class)
|
||||
{
|
||||
$this->routeAnnotationClass = $class;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads from annotations from a class.
|
||||
*
|
||||
* @param string $class A class name
|
||||
* @param string $type The resource type
|
||||
*
|
||||
* @return RouteCollection A RouteCollection instance
|
||||
*
|
||||
* @throws \InvalidArgumentException When route can't be parsed
|
||||
*/
|
||||
public function load($class, $type = null)
|
||||
{
|
||||
if (!class_exists($class)) {
|
||||
throw new \InvalidArgumentException(sprintf('Class "%s" does not exist.', $class));
|
||||
}
|
||||
|
||||
$globals = array(
|
||||
'pattern' => '',
|
||||
'requirements' => array(),
|
||||
'options' => array(),
|
||||
'defaults' => array(),
|
||||
);
|
||||
|
||||
$class = new \ReflectionClass($class);
|
||||
if ($class->isAbstract()) {
|
||||
throw new \InvalidArgumentException(sprintf('Annotations from class "%s" cannot be read as it is abstract.', $class));
|
||||
}
|
||||
|
||||
if ($annot = $this->reader->getClassAnnotation($class, $this->routeAnnotationClass)) {
|
||||
if (null !== $annot->getPattern()) {
|
||||
$globals['pattern'] = $annot->getPattern();
|
||||
}
|
||||
|
||||
if (null !== $annot->getRequirements()) {
|
||||
$globals['requirements'] = $annot->getRequirements();
|
||||
}
|
||||
|
||||
if (null !== $annot->getOptions()) {
|
||||
$globals['options'] = $annot->getOptions();
|
||||
}
|
||||
|
||||
if (null !== $annot->getDefaults()) {
|
||||
$globals['defaults'] = $annot->getDefaults();
|
||||
}
|
||||
}
|
||||
|
||||
$collection = new RouteCollection();
|
||||
$collection->addResource(new FileResource($class->getFileName()));
|
||||
|
||||
foreach ($class->getMethods() as $method) {
|
||||
$this->defaultRouteIndex = 0;
|
||||
foreach ($this->reader->getMethodAnnotations($method) as $annot) {
|
||||
if ($annot instanceof $this->routeAnnotationClass) {
|
||||
$this->addRoute($collection, $annot, $globals, $class, $method);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $collection;
|
||||
}
|
||||
|
||||
protected function addRoute(RouteCollection $collection, $annot, $globals, \ReflectionClass $class, \ReflectionMethod $method)
|
||||
{
|
||||
$name = $annot->getName();
|
||||
if (null === $name) {
|
||||
$name = $this->getDefaultRouteName($class, $method);
|
||||
}
|
||||
|
||||
$defaults = array_merge($globals['defaults'], $annot->getDefaults());
|
||||
$requirements = array_merge($globals['requirements'], $annot->getRequirements());
|
||||
$options = array_merge($globals['options'], $annot->getOptions());
|
||||
|
||||
$route = new Route($globals['pattern'].$annot->getPattern(), $defaults, $requirements, $options);
|
||||
|
||||
$this->configureRoute($route, $class, $method, $annot);
|
||||
|
||||
$collection->add($name, $route);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this class supports the given resource.
|
||||
*
|
||||
* @param mixed $resource A resource
|
||||
* @param string $type The resource type
|
||||
*
|
||||
* @return Boolean True if this class supports the given resource, false otherwise
|
||||
*/
|
||||
public function supports($resource, $type = null)
|
||||
{
|
||||
return is_string($resource) && preg_match('/^(?:\\\\?[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)+$/', $resource) && (!$type || 'annotation' === $type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the loader resolver.
|
||||
*
|
||||
* @param LoaderResolver $resolver A LoaderResolver instance
|
||||
*/
|
||||
public function setResolver(LoaderResolver $resolver)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the loader resolver.
|
||||
*
|
||||
* @return LoaderResolver A LoaderResolver instance
|
||||
*/
|
||||
public function getResolver()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the default route name for a class method.
|
||||
*
|
||||
* @param \ReflectionClass $class
|
||||
* @param \ReflectionMethod $method
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getDefaultRouteName(\ReflectionClass $class, \ReflectionMethod $method)
|
||||
{
|
||||
$name = strtolower(str_replace('\\', '_', $class->name).'_'.$method->name);
|
||||
if ($this->defaultRouteIndex > 0) {
|
||||
$name .= '_'.$this->defaultRouteIndex;
|
||||
}
|
||||
$this->defaultRouteIndex++;
|
||||
|
||||
return $name;
|
||||
}
|
||||
|
||||
abstract protected function configureRoute(Route $route, \ReflectionClass $class, \ReflectionMethod $method, $annot);
|
||||
}
|
77
3rdparty/symfony/routing/Symfony/Component/Routing/Loader/AnnotationDirectoryLoader.php
vendored
Normal file
77
3rdparty/symfony/routing/Symfony/Component/Routing/Loader/AnnotationDirectoryLoader.php
vendored
Normal file
|
@ -0,0 +1,77 @@
|
|||
<?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\Component\Routing\Loader;
|
||||
|
||||
use Symfony\Component\Routing\RouteCollection;
|
||||
use Symfony\Component\Config\Resource\DirectoryResource;
|
||||
|
||||
/**
|
||||
* AnnotationDirectoryLoader loads routing information from annotations set
|
||||
* on PHP classes and methods.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
class AnnotationDirectoryLoader extends AnnotationFileLoader
|
||||
{
|
||||
/**
|
||||
* Loads from annotations from a directory.
|
||||
*
|
||||
* @param string $path A directory path
|
||||
* @param string $type The resource type
|
||||
*
|
||||
* @return RouteCollection A RouteCollection instance
|
||||
*
|
||||
* @throws \InvalidArgumentException When the directory does not exist or its routes cannot be parsed
|
||||
*/
|
||||
public function load($path, $type = null)
|
||||
{
|
||||
$dir = $this->locator->locate($path);
|
||||
|
||||
$collection = new RouteCollection();
|
||||
$collection->addResource(new DirectoryResource($dir, '/\.php$/'));
|
||||
foreach (new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($dir), \RecursiveIteratorIterator::LEAVES_ONLY) as $file) {
|
||||
if (!$file->isFile() || '.php' !== substr($file->getFilename(), -4)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($class = $this->findClass($file)) {
|
||||
$refl = new \ReflectionClass($class);
|
||||
if ($refl->isAbstract()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$collection->addCollection($this->loader->load($class, $type));
|
||||
}
|
||||
}
|
||||
|
||||
return $collection;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this class supports the given resource.
|
||||
*
|
||||
* @param mixed $resource A resource
|
||||
* @param string $type The resource type
|
||||
*
|
||||
* @return Boolean True if this class supports the given resource, false otherwise
|
||||
*/
|
||||
public function supports($resource, $type = null)
|
||||
{
|
||||
try {
|
||||
$path = $this->locator->locate($resource);
|
||||
} catch (\Exception $e) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return is_string($resource) && is_dir($path) && (!$type || 'annotation' === $type);
|
||||
}
|
||||
}
|
125
3rdparty/symfony/routing/Symfony/Component/Routing/Loader/AnnotationFileLoader.php
vendored
Normal file
125
3rdparty/symfony/routing/Symfony/Component/Routing/Loader/AnnotationFileLoader.php
vendored
Normal file
|
@ -0,0 +1,125 @@
|
|||
<?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\Component\Routing\Loader;
|
||||
|
||||
use Symfony\Component\Routing\RouteCollection;
|
||||
use Symfony\Component\Config\Resource\FileResource;
|
||||
use Symfony\Component\Config\Loader\FileLoader;
|
||||
use Symfony\Component\Config\FileLocator;
|
||||
|
||||
/**
|
||||
* AnnotationFileLoader loads routing information from annotations set
|
||||
* on a PHP class and its methods.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
class AnnotationFileLoader extends FileLoader
|
||||
{
|
||||
protected $loader;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param FileLocator $locator A FileLocator instance
|
||||
* @param AnnotationClassLoader $loader An AnnotationClassLoader instance
|
||||
* @param string|array $paths A path or an array of paths where to look for resources
|
||||
*/
|
||||
public function __construct(FileLocator $locator, AnnotationClassLoader $loader, $paths = array())
|
||||
{
|
||||
if (!function_exists('token_get_all')) {
|
||||
throw new \RuntimeException('The Tokenizer extension is required for the routing annotation loaders.');
|
||||
}
|
||||
|
||||
parent::__construct($locator, $paths);
|
||||
|
||||
$this->loader = $loader;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads from annotations from a file.
|
||||
*
|
||||
* @param string $file A PHP file path
|
||||
* @param string $type The resource type
|
||||
*
|
||||
* @return RouteCollection A RouteCollection instance
|
||||
*
|
||||
* @throws \InvalidArgumentException When the file does not exist or its routes cannot be parsed
|
||||
*/
|
||||
public function load($file, $type = null)
|
||||
{
|
||||
$path = $this->locator->locate($file);
|
||||
|
||||
$collection = new RouteCollection();
|
||||
if ($class = $this->findClass($path)) {
|
||||
$collection->addResource(new FileResource($path));
|
||||
$collection->addCollection($this->loader->load($class, $type));
|
||||
}
|
||||
|
||||
return $collection;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this class supports the given resource.
|
||||
*
|
||||
* @param mixed $resource A resource
|
||||
* @param string $type The resource type
|
||||
*
|
||||
* @return Boolean True if this class supports the given resource, false otherwise
|
||||
*/
|
||||
public function supports($resource, $type = null)
|
||||
{
|
||||
return is_string($resource) && 'php' === pathinfo($resource, PATHINFO_EXTENSION) && (!$type || 'annotation' === $type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the full class name for the first class in the file.
|
||||
*
|
||||
* @param string $file A PHP file path
|
||||
*
|
||||
* @return string|false Full class name if found, false otherwise
|
||||
*/
|
||||
protected function findClass($file)
|
||||
{
|
||||
$class = false;
|
||||
$namespace = false;
|
||||
$tokens = token_get_all(file_get_contents($file));
|
||||
for ($i = 0, $count = count($tokens); $i < $count; $i++) {
|
||||
$token = $tokens[$i];
|
||||
|
||||
if (!is_array($token)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (true === $class && T_STRING === $token[0]) {
|
||||
return $namespace.'\\'.$token[1];
|
||||
}
|
||||
|
||||
if (true === $namespace && T_STRING === $token[0]) {
|
||||
$namespace = '';
|
||||
do {
|
||||
$namespace .= $token[1];
|
||||
$token = $tokens[++$i];
|
||||
} while ($i < $count && is_array($token) && in_array($token[0], array(T_NS_SEPARATOR, T_STRING)));
|
||||
}
|
||||
|
||||
if (T_CLASS === $token[0]) {
|
||||
$class = true;
|
||||
}
|
||||
|
||||
if (T_NAMESPACE === $token[0]) {
|
||||
$namespace = true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -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\Component\Routing\Loader;
|
||||
|
||||
use Symfony\Component\Config\Loader\Loader;
|
||||
|
||||
/**
|
||||
* ClosureLoader loads routes from a PHP closure.
|
||||
*
|
||||
* The Closure must return a RouteCollection instance.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
class ClosureLoader extends Loader
|
||||
{
|
||||
/**
|
||||
* Loads a Closure.
|
||||
*
|
||||
* @param \Closure $closure A Closure
|
||||
* @param string $type The resource type
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function load($closure, $type = null)
|
||||
{
|
||||
return call_user_func($closure);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this class supports the given resource.
|
||||
*
|
||||
* @param mixed $resource A resource
|
||||
* @param string $type The resource type
|
||||
*
|
||||
* @return Boolean True if this class supports the given resource, false otherwise
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function supports($resource, $type = null)
|
||||
{
|
||||
return $resource instanceof \Closure && (!$type || 'closure' === $type);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,64 @@
|
|||
<?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\Component\Routing\Loader;
|
||||
|
||||
use Symfony\Component\Config\Resource\FileResource;
|
||||
use Symfony\Component\Config\Loader\FileLoader;
|
||||
|
||||
/**
|
||||
* PhpFileLoader loads routes from a PHP file.
|
||||
*
|
||||
* The file must return a RouteCollection instance.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
class PhpFileLoader extends FileLoader
|
||||
{
|
||||
/**
|
||||
* Loads a PHP file.
|
||||
*
|
||||
* @param mixed $file A PHP file path
|
||||
* @param string $type The resource type
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function load($file, $type = null)
|
||||
{
|
||||
// the loader variable is exposed to the included file below
|
||||
$loader = $this;
|
||||
|
||||
$path = $this->locator->locate($file);
|
||||
$this->setCurrentDir(dirname($path));
|
||||
|
||||
$collection = include $path;
|
||||
$collection->addResource(new FileResource($path));
|
||||
|
||||
return $collection;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this class supports the given resource.
|
||||
*
|
||||
* @param mixed $resource A resource
|
||||
* @param string $type The resource type
|
||||
*
|
||||
* @return Boolean True if this class supports the given resource, false otherwise
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function supports($resource, $type = null)
|
||||
{
|
||||
return is_string($resource) && 'php' === pathinfo($resource, PATHINFO_EXTENSION) && (!$type || 'php' === $type);
|
||||
}
|
||||
}
|
224
3rdparty/symfony/routing/Symfony/Component/Routing/Loader/XmlFileLoader.php
vendored
Normal file
224
3rdparty/symfony/routing/Symfony/Component/Routing/Loader/XmlFileLoader.php
vendored
Normal file
|
@ -0,0 +1,224 @@
|
|||
<?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\Component\Routing\Loader;
|
||||
|
||||
use Symfony\Component\Routing\RouteCollection;
|
||||
use Symfony\Component\Routing\Route;
|
||||
use Symfony\Component\Config\Resource\FileResource;
|
||||
use Symfony\Component\Config\Loader\FileLoader;
|
||||
|
||||
/**
|
||||
* XmlFileLoader loads XML routing files.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
class XmlFileLoader extends FileLoader
|
||||
{
|
||||
/**
|
||||
* Loads an XML file.
|
||||
*
|
||||
* @param string $file An XML file path
|
||||
* @param string $type The resource type
|
||||
*
|
||||
* @return RouteCollection A RouteCollection instance
|
||||
*
|
||||
* @throws \InvalidArgumentException When a tag can't be parsed
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function load($file, $type = null)
|
||||
{
|
||||
$path = $this->locator->locate($file);
|
||||
|
||||
$xml = $this->loadFile($path);
|
||||
|
||||
$collection = new RouteCollection();
|
||||
$collection->addResource(new FileResource($path));
|
||||
|
||||
// process routes and imports
|
||||
foreach ($xml->documentElement->childNodes as $node) {
|
||||
if (!$node instanceof \DOMElement) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$this->parseNode($collection, $node, $path, $file);
|
||||
}
|
||||
|
||||
return $collection;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a node from a loaded XML file.
|
||||
*
|
||||
* @param RouteCollection $collection the collection to associate with the node
|
||||
* @param DOMElement $node the node to parse
|
||||
* @param string $path the path of the XML file being processed
|
||||
* @param string $file
|
||||
*/
|
||||
protected function parseNode(RouteCollection $collection, \DOMElement $node, $path, $file)
|
||||
{
|
||||
switch ($node->tagName) {
|
||||
case 'route':
|
||||
$this->parseRoute($collection, $node, $path);
|
||||
break;
|
||||
case 'import':
|
||||
$resource = (string) $node->getAttribute('resource');
|
||||
$type = (string) $node->getAttribute('type');
|
||||
$prefix = (string) $node->getAttribute('prefix');
|
||||
$this->setCurrentDir(dirname($path));
|
||||
$collection->addCollection($this->import($resource, ('' !== $type ? $type : null), false, $file), $prefix);
|
||||
break;
|
||||
default:
|
||||
throw new \InvalidArgumentException(sprintf('Unable to parse tag "%s"', $node->tagName));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this class supports the given resource.
|
||||
*
|
||||
* @param mixed $resource A resource
|
||||
* @param string $type The resource type
|
||||
*
|
||||
* @return Boolean True if this class supports the given resource, false otherwise
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function supports($resource, $type = null)
|
||||
{
|
||||
return is_string($resource) && 'xml' === pathinfo($resource, PATHINFO_EXTENSION) && (!$type || 'xml' === $type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a route and adds it to the RouteCollection.
|
||||
*
|
||||
* @param RouteCollection $collection A RouteCollection instance
|
||||
* @param \DOMElement $definition Route definition
|
||||
* @param string $file An XML file path
|
||||
*
|
||||
* @throws \InvalidArgumentException When the definition cannot be parsed
|
||||
*/
|
||||
protected function parseRoute(RouteCollection $collection, \DOMElement $definition, $file)
|
||||
{
|
||||
$defaults = array();
|
||||
$requirements = array();
|
||||
$options = array();
|
||||
|
||||
foreach ($definition->childNodes as $node) {
|
||||
if (!$node instanceof \DOMElement) {
|
||||
continue;
|
||||
}
|
||||
|
||||
switch ($node->tagName) {
|
||||
case 'default':
|
||||
$defaults[(string) $node->getAttribute('key')] = trim((string) $node->nodeValue);
|
||||
break;
|
||||
case 'option':
|
||||
$options[(string) $node->getAttribute('key')] = trim((string) $node->nodeValue);
|
||||
break;
|
||||
case 'requirement':
|
||||
$requirements[(string) $node->getAttribute('key')] = trim((string) $node->nodeValue);
|
||||
break;
|
||||
default:
|
||||
throw new \InvalidArgumentException(sprintf('Unable to parse tag "%s"', $node->tagName));
|
||||
}
|
||||
}
|
||||
|
||||
$route = new Route((string) $definition->getAttribute('pattern'), $defaults, $requirements, $options);
|
||||
|
||||
$collection->add((string) $definition->getAttribute('id'), $route);
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads an XML file.
|
||||
*
|
||||
* @param string $file An XML file path
|
||||
*
|
||||
* @return \DOMDocument
|
||||
*
|
||||
* @throws \InvalidArgumentException When loading of XML file returns error
|
||||
*/
|
||||
protected function loadFile($file)
|
||||
{
|
||||
$internalErrors = libxml_use_internal_errors(true);
|
||||
$disableEntities = libxml_disable_entity_loader(true);
|
||||
libxml_clear_errors();
|
||||
|
||||
$dom = new \DOMDocument();
|
||||
$dom->validateOnParse = true;
|
||||
if (!$dom->loadXML(file_get_contents($file), LIBXML_NONET | (defined('LIBXML_COMPACT') ? LIBXML_COMPACT : 0))) {
|
||||
libxml_disable_entity_loader($disableEntities);
|
||||
|
||||
throw new \InvalidArgumentException(implode("\n", $this->getXmlErrors($internalErrors)));
|
||||
}
|
||||
$dom->normalizeDocument();
|
||||
|
||||
libxml_use_internal_errors($internalErrors);
|
||||
libxml_disable_entity_loader($disableEntities);
|
||||
|
||||
foreach ($dom->childNodes as $child) {
|
||||
if ($child->nodeType === XML_DOCUMENT_TYPE_NODE) {
|
||||
throw new \InvalidArgumentException('Document types are not allowed.');
|
||||
}
|
||||
}
|
||||
|
||||
$this->validate($dom);
|
||||
|
||||
return $dom;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates a loaded XML file.
|
||||
*
|
||||
* @param \DOMDocument $dom A loaded XML file
|
||||
*
|
||||
* @throws \InvalidArgumentException When XML doesn't validate its XSD schema
|
||||
*/
|
||||
protected function validate(\DOMDocument $dom)
|
||||
{
|
||||
$location = __DIR__.'/schema/routing/routing-1.0.xsd';
|
||||
|
||||
$current = libxml_use_internal_errors(true);
|
||||
libxml_clear_errors();
|
||||
|
||||
if (!$dom->schemaValidate($location)) {
|
||||
throw new \InvalidArgumentException(implode("\n", $this->getXmlErrors($current)));
|
||||
}
|
||||
libxml_use_internal_errors($current);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves libxml errors and clears them.
|
||||
*
|
||||
* @return array An array of libxml error strings
|
||||
*/
|
||||
private function getXmlErrors($internalErrors)
|
||||
{
|
||||
$errors = array();
|
||||
foreach (libxml_get_errors() as $error) {
|
||||
$errors[] = sprintf('[%s %s] %s (in %s - line %d, column %d)',
|
||||
LIBXML_ERR_WARNING == $error->level ? 'WARNING' : 'ERROR',
|
||||
$error->code,
|
||||
trim($error->message),
|
||||
$error->file ? $error->file : 'n/a',
|
||||
$error->line,
|
||||
$error->column
|
||||
);
|
||||
}
|
||||
|
||||
libxml_clear_errors();
|
||||
libxml_use_internal_errors($internalErrors);
|
||||
|
||||
return $errors;
|
||||
}
|
||||
}
|
142
3rdparty/symfony/routing/Symfony/Component/Routing/Loader/YamlFileLoader.php
vendored
Normal file
142
3rdparty/symfony/routing/Symfony/Component/Routing/Loader/YamlFileLoader.php
vendored
Normal file
|
@ -0,0 +1,142 @@
|
|||
<?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\Component\Routing\Loader;
|
||||
|
||||
use Symfony\Component\Routing\RouteCollection;
|
||||
use Symfony\Component\Routing\Route;
|
||||
use Symfony\Component\Config\Resource\FileResource;
|
||||
use Symfony\Component\Yaml\Yaml;
|
||||
use Symfony\Component\Config\Loader\FileLoader;
|
||||
|
||||
/**
|
||||
* YamlFileLoader loads Yaml routing files.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
class YamlFileLoader extends FileLoader
|
||||
{
|
||||
private static $availableKeys = array(
|
||||
'type', 'resource', 'prefix', 'pattern', 'options', 'defaults', 'requirements'
|
||||
);
|
||||
|
||||
/**
|
||||
* Loads a Yaml file.
|
||||
*
|
||||
* @param string $file A Yaml file path
|
||||
* @param string $type The resource type
|
||||
*
|
||||
* @return RouteCollection A RouteCollection instance
|
||||
*
|
||||
* @throws \InvalidArgumentException When route can't be parsed
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function load($file, $type = null)
|
||||
{
|
||||
$path = $this->locator->locate($file);
|
||||
|
||||
$config = Yaml::parse($path);
|
||||
|
||||
$collection = new RouteCollection();
|
||||
$collection->addResource(new FileResource($path));
|
||||
|
||||
// empty file
|
||||
if (null === $config) {
|
||||
$config = array();
|
||||
}
|
||||
|
||||
// not an array
|
||||
if (!is_array($config)) {
|
||||
throw new \InvalidArgumentException(sprintf('The file "%s" must contain a YAML array.', $file));
|
||||
}
|
||||
|
||||
foreach ($config as $name => $config) {
|
||||
$config = $this->normalizeRouteConfig($config);
|
||||
|
||||
if (isset($config['resource'])) {
|
||||
$type = isset($config['type']) ? $config['type'] : null;
|
||||
$prefix = isset($config['prefix']) ? $config['prefix'] : null;
|
||||
$this->setCurrentDir(dirname($path));
|
||||
$collection->addCollection($this->import($config['resource'], $type, false, $file), $prefix);
|
||||
} else {
|
||||
$this->parseRoute($collection, $name, $config, $path);
|
||||
}
|
||||
}
|
||||
|
||||
return $collection;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this class supports the given resource.
|
||||
*
|
||||
* @param mixed $resource A resource
|
||||
* @param string $type The resource type
|
||||
*
|
||||
* @return Boolean True if this class supports the given resource, false otherwise
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function supports($resource, $type = null)
|
||||
{
|
||||
return is_string($resource) && 'yml' === pathinfo($resource, PATHINFO_EXTENSION) && (!$type || 'yaml' === $type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a route and adds it to the RouteCollection.
|
||||
*
|
||||
* @param RouteCollection $collection A RouteCollection instance
|
||||
* @param string $name Route name
|
||||
* @param array $config Route definition
|
||||
* @param string $file A Yaml file path
|
||||
*
|
||||
* @throws \InvalidArgumentException When config pattern is not defined for the given route
|
||||
*/
|
||||
protected function parseRoute(RouteCollection $collection, $name, $config, $file)
|
||||
{
|
||||
$defaults = isset($config['defaults']) ? $config['defaults'] : array();
|
||||
$requirements = isset($config['requirements']) ? $config['requirements'] : array();
|
||||
$options = isset($config['options']) ? $config['options'] : array();
|
||||
|
||||
if (!isset($config['pattern'])) {
|
||||
throw new \InvalidArgumentException(sprintf('You must define a "pattern" for the "%s" route.', $name));
|
||||
}
|
||||
|
||||
$route = new Route($config['pattern'], $defaults, $requirements, $options);
|
||||
|
||||
$collection->add($name, $route);
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalize route configuration.
|
||||
*
|
||||
* @param array $config A resource config
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @throws InvalidArgumentException if one of the provided config keys is not supported
|
||||
*/
|
||||
private function normalizeRouteConfig(array $config)
|
||||
{
|
||||
foreach ($config as $key => $value) {
|
||||
if (!in_array($key, self::$availableKeys)) {
|
||||
throw new \InvalidArgumentException(sprintf(
|
||||
'Yaml routing loader does not support given key: "%s". Expected one of the (%s).',
|
||||
$key, implode(', ', self::$availableKeys)
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
return $config;
|
||||
}
|
||||
}
|
38
3rdparty/symfony/routing/Symfony/Component/Routing/Loader/schema/routing/routing-1.0.xsd
vendored
Normal file
38
3rdparty/symfony/routing/Symfony/Component/Routing/Loader/schema/routing/routing-1.0.xsd
vendored
Normal file
|
@ -0,0 +1,38 @@
|
|||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
|
||||
<xsd:schema xmlns="http://symfony.com/schema/routing"
|
||||
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
|
||||
targetNamespace="http://symfony.com/schema/routing"
|
||||
elementFormDefault="qualified">
|
||||
|
||||
<xsd:element name="routes" type="routes" />
|
||||
|
||||
<xsd:complexType name="routes">
|
||||
<xsd:choice maxOccurs="unbounded" minOccurs="0">
|
||||
<xsd:element name="import" type="import" />
|
||||
<xsd:element name="route" type="route" />
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="route">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="default" type="element" minOccurs="0" maxOccurs="unbounded" />
|
||||
<xsd:element name="requirement" type="element" minOccurs="0" maxOccurs="unbounded" />
|
||||
<xsd:element name="option" type="element" minOccurs="0" maxOccurs="unbounded" />
|
||||
</xsd:sequence>
|
||||
|
||||
<xsd:attribute name="id" type="xsd:string" />
|
||||
<xsd:attribute name="pattern" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="import">
|
||||
<xsd:attribute name="resource" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="prefix" type="xsd:string" />
|
||||
<xsd:attribute name="class" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="element" mixed="true">
|
||||
<xsd:attribute name="key" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:schema>
|
76
3rdparty/symfony/routing/Symfony/Component/Routing/Matcher/ApacheUrlMatcher.php
vendored
Normal file
76
3rdparty/symfony/routing/Symfony/Component/Routing/Matcher/ApacheUrlMatcher.php
vendored
Normal file
|
@ -0,0 +1,76 @@
|
|||
<?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\Component\Routing\Matcher;
|
||||
|
||||
use Symfony\Component\Routing\Exception\MethodNotAllowedException;
|
||||
|
||||
/**
|
||||
* ApacheUrlMatcher matches URL based on Apache mod_rewrite matching (see ApacheMatcherDumper).
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
class ApacheUrlMatcher extends UrlMatcher
|
||||
{
|
||||
/**
|
||||
* Tries to match a URL based on Apache mod_rewrite matching.
|
||||
*
|
||||
* Returns false if no route matches the URL.
|
||||
*
|
||||
* @param string $pathinfo The pathinfo to be parsed
|
||||
*
|
||||
* @return array An array of parameters
|
||||
*
|
||||
* @throws MethodNotAllowedException If the current method is not allowed
|
||||
*/
|
||||
public function match($pathinfo)
|
||||
{
|
||||
$parameters = array();
|
||||
$defaults = array();
|
||||
$allow = array();
|
||||
$match = false;
|
||||
|
||||
foreach ($_SERVER as $key => $value) {
|
||||
$name = $key;
|
||||
|
||||
if (0 === strpos($name, 'REDIRECT_')) {
|
||||
$name = substr($name, 9);
|
||||
}
|
||||
|
||||
if (0 === strpos($name, '_ROUTING_DEFAULTS_')) {
|
||||
$name = substr($name, 18);
|
||||
$defaults[$name] = $value;
|
||||
} elseif (0 === strpos($name, '_ROUTING_')) {
|
||||
$name = substr($name, 9);
|
||||
if ('_route' == $name) {
|
||||
$match = true;
|
||||
$parameters[$name] = $value;
|
||||
} elseif (0 === strpos($name, '_allow_')) {
|
||||
$allow[] = substr($name, 7);
|
||||
} else {
|
||||
$parameters[$name] = $value;
|
||||
}
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
|
||||
unset($_SERVER[$key]);
|
||||
}
|
||||
|
||||
if ($match) {
|
||||
return $this->mergeDefaults($parameters, $defaults);
|
||||
} elseif (0 < count($allow)) {
|
||||
throw new MethodNotAllowedException($allow);
|
||||
} else {
|
||||
return parent::match($pathinfo);
|
||||
}
|
||||
}
|
||||
}
|
155
3rdparty/symfony/routing/Symfony/Component/Routing/Matcher/Dumper/ApacheMatcherDumper.php
vendored
Normal file
155
3rdparty/symfony/routing/Symfony/Component/Routing/Matcher/Dumper/ApacheMatcherDumper.php
vendored
Normal file
|
@ -0,0 +1,155 @@
|
|||
<?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\Component\Routing\Matcher\Dumper;
|
||||
|
||||
/**
|
||||
* Dumps a set of Apache mod_rewrite rules.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
* @author Kris Wallsmith <kris@symfony.com>
|
||||
*/
|
||||
class ApacheMatcherDumper extends MatcherDumper
|
||||
{
|
||||
/**
|
||||
* Dumps a set of Apache mod_rewrite rules.
|
||||
*
|
||||
* Available options:
|
||||
*
|
||||
* * script_name: The script name (app.php by default)
|
||||
* * base_uri: The base URI ("" by default)
|
||||
*
|
||||
* @param array $options An array of options
|
||||
*
|
||||
* @return string A string to be used as Apache rewrite rules
|
||||
*
|
||||
* @throws \LogicException When the route regex is invalid
|
||||
*/
|
||||
public function dump(array $options = array())
|
||||
{
|
||||
$options = array_merge(array(
|
||||
'script_name' => 'app.php',
|
||||
'base_uri' => '',
|
||||
), $options);
|
||||
|
||||
$options['script_name'] = self::escape($options['script_name'], ' ', '\\');
|
||||
|
||||
$rules = array("# skip \"real\" requests\nRewriteCond %{REQUEST_FILENAME} -f\nRewriteRule .* - [QSA,L]");
|
||||
$methodVars = array();
|
||||
|
||||
foreach ($this->getRoutes()->all() as $name => $route) {
|
||||
$compiledRoute = $route->compile();
|
||||
|
||||
// prepare the apache regex
|
||||
$regex = $compiledRoute->getRegex();
|
||||
$delimiter = $regex[0];
|
||||
$regexPatternEnd = strrpos($regex, $delimiter);
|
||||
if (strlen($regex) < 2 || 0 === $regexPatternEnd) {
|
||||
throw new \LogicException('The "%s" route regex "%s" is invalid', $name, $regex);
|
||||
}
|
||||
$regex = preg_replace('/\?P<.+?>/', '', substr($regex, 1, $regexPatternEnd - 1));
|
||||
$regex = '^'.self::escape(preg_quote($options['base_uri']).substr($regex, 1), ' ', '\\');
|
||||
|
||||
$hasTrailingSlash = '/$' == substr($regex, -2) && '^/$' != $regex;
|
||||
|
||||
$variables = array('E=_ROUTING__route:'.$name);
|
||||
foreach ($compiledRoute->getVariables() as $i => $variable) {
|
||||
$variables[] = 'E=_ROUTING_'.$variable.':%'.($i + 1);
|
||||
}
|
||||
foreach ($route->getDefaults() as $key => $value) {
|
||||
$variables[] = 'E=_ROUTING_DEFAULTS_'.$key.':'.strtr($value, array(
|
||||
':' => '\\:',
|
||||
'=' => '\\=',
|
||||
'\\' => '\\\\',
|
||||
' ' => '\\ ',
|
||||
));
|
||||
}
|
||||
$variables = implode(',', $variables);
|
||||
|
||||
$rule = array("# $name");
|
||||
|
||||
// method mismatch
|
||||
if ($req = $route->getRequirement('_method')) {
|
||||
$methods = explode('|', strtoupper($req));
|
||||
// GET and HEAD are equivalent
|
||||
if (in_array('GET', $methods) && !in_array('HEAD', $methods)) {
|
||||
$methods[] = 'HEAD';
|
||||
}
|
||||
$allow = array();
|
||||
foreach ($methods as $method) {
|
||||
$methodVars[] = $method;
|
||||
$allow[] = 'E=_ROUTING__allow_'.$method.':1';
|
||||
}
|
||||
|
||||
$rule[] = "RewriteCond %{REQUEST_URI} $regex";
|
||||
$rule[] = sprintf("RewriteCond %%{REQUEST_METHOD} !^(%s)$ [NC]", implode('|', $methods));
|
||||
$rule[] = sprintf('RewriteRule .* - [S=%d,%s]', $hasTrailingSlash ? 2 : 1, implode(',', $allow));
|
||||
}
|
||||
|
||||
// redirect with trailing slash appended
|
||||
if ($hasTrailingSlash) {
|
||||
$rule[] = 'RewriteCond %{REQUEST_URI} '.substr($regex, 0, -2).'$';
|
||||
$rule[] = 'RewriteRule .* $0/ [QSA,L,R=301]';
|
||||
}
|
||||
|
||||
// the main rule
|
||||
$rule[] = "RewriteCond %{REQUEST_URI} $regex";
|
||||
$rule[] = "RewriteRule .* {$options['script_name']} [QSA,L,$variables]";
|
||||
|
||||
$rules[] = implode("\n", $rule);
|
||||
}
|
||||
|
||||
if (0 < count($methodVars)) {
|
||||
$rule = array('# 405 Method Not Allowed');
|
||||
$methodVars = array_values(array_unique($methodVars));
|
||||
foreach ($methodVars as $i => $methodVar) {
|
||||
$rule[] = sprintf('RewriteCond %%{_ROUTING__allow_%s} !-z%s', $methodVar, isset($methodVars[$i + 1]) ? ' [OR]' : '');
|
||||
}
|
||||
$rule[] = sprintf('RewriteRule .* %s [QSA,L]', $options['script_name']);
|
||||
|
||||
$rules[] = implode("\n", $rule);
|
||||
}
|
||||
|
||||
return implode("\n\n", $rules)."\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* Escapes a string.
|
||||
*
|
||||
* @param string $string The string to be escaped
|
||||
* @param string $char The character to be escaped
|
||||
* @param string $with The character to be used for escaping
|
||||
*
|
||||
* @return string The escaped string
|
||||
*/
|
||||
private static function escape($string, $char, $with)
|
||||
{
|
||||
$escaped = false;
|
||||
$output = '';
|
||||
foreach (str_split($string) as $symbol) {
|
||||
if ($escaped) {
|
||||
$output .= $symbol;
|
||||
$escaped = false;
|
||||
continue;
|
||||
}
|
||||
if ($symbol === $char) {
|
||||
$output .= $with.$char;
|
||||
continue;
|
||||
}
|
||||
if ($symbol === $with) {
|
||||
$escaped = true;
|
||||
}
|
||||
$output .= $symbol;
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
}
|
44
3rdparty/symfony/routing/Symfony/Component/Routing/Matcher/Dumper/MatcherDumper.php
vendored
Normal file
44
3rdparty/symfony/routing/Symfony/Component/Routing/Matcher/Dumper/MatcherDumper.php
vendored
Normal file
|
@ -0,0 +1,44 @@
|
|||
<?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\Component\Routing\Matcher\Dumper;
|
||||
|
||||
use Symfony\Component\Routing\RouteCollection;
|
||||
|
||||
/**
|
||||
* MatcherDumper is the abstract class for all built-in matcher dumpers.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
abstract class MatcherDumper implements MatcherDumperInterface
|
||||
{
|
||||
private $routes;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param RouteCollection $routes The RouteCollection to dump
|
||||
*/
|
||||
public function __construct(RouteCollection $routes)
|
||||
{
|
||||
$this->routes = $routes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the routes to dump.
|
||||
*
|
||||
* @return RouteCollection A RouteCollection instance
|
||||
*/
|
||||
public function getRoutes()
|
||||
{
|
||||
return $this->routes;
|
||||
}
|
||||
}
|
41
3rdparty/symfony/routing/Symfony/Component/Routing/Matcher/Dumper/MatcherDumperInterface.php
vendored
Normal file
41
3rdparty/symfony/routing/Symfony/Component/Routing/Matcher/Dumper/MatcherDumperInterface.php
vendored
Normal file
|
@ -0,0 +1,41 @@
|
|||
<?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\Component\Routing\Matcher\Dumper;
|
||||
|
||||
/**
|
||||
* MatcherDumperInterface is the interface that all matcher dumper classes must implement.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
interface MatcherDumperInterface
|
||||
{
|
||||
/**
|
||||
* Dumps a set of routes to a PHP class.
|
||||
*
|
||||
* Available options:
|
||||
*
|
||||
* * class: The class name
|
||||
* * base_class: The base class name
|
||||
*
|
||||
* @param array $options An array of options
|
||||
*
|
||||
* @return string A PHP class representing the matcher class
|
||||
*/
|
||||
public function dump(array $options = array());
|
||||
|
||||
/**
|
||||
* Gets the routes to match.
|
||||
*
|
||||
* @return RouteCollection A RouteCollection instance
|
||||
*/
|
||||
public function getRoutes();
|
||||
}
|
293
3rdparty/symfony/routing/Symfony/Component/Routing/Matcher/Dumper/PhpMatcherDumper.php
vendored
Normal file
293
3rdparty/symfony/routing/Symfony/Component/Routing/Matcher/Dumper/PhpMatcherDumper.php
vendored
Normal file
|
@ -0,0 +1,293 @@
|
|||
<?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\Component\Routing\Matcher\Dumper;
|
||||
|
||||
use Symfony\Component\Routing\Route;
|
||||
use Symfony\Component\Routing\RouteCollection;
|
||||
|
||||
/**
|
||||
* PhpMatcherDumper creates a PHP class able to match URLs for a given set of routes.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
class PhpMatcherDumper extends MatcherDumper
|
||||
{
|
||||
/**
|
||||
* Dumps a set of routes to a PHP class.
|
||||
*
|
||||
* Available options:
|
||||
*
|
||||
* * class: The class name
|
||||
* * base_class: The base class name
|
||||
*
|
||||
* @param array $options An array of options
|
||||
*
|
||||
* @return string A PHP class representing the matcher class
|
||||
*/
|
||||
public function dump(array $options = array())
|
||||
{
|
||||
$options = array_merge(array(
|
||||
'class' => 'ProjectUrlMatcher',
|
||||
'base_class' => 'Symfony\\Component\\Routing\\Matcher\\UrlMatcher',
|
||||
), $options);
|
||||
|
||||
// trailing slash support is only enabled if we know how to redirect the user
|
||||
$interfaces = class_implements($options['base_class']);
|
||||
$supportsRedirections = isset($interfaces['Symfony\Component\Routing\Matcher\RedirectableUrlMatcherInterface']);
|
||||
|
||||
return
|
||||
$this->startClass($options['class'], $options['base_class']).
|
||||
$this->addConstructor().
|
||||
$this->addMatcher($supportsRedirections).
|
||||
$this->endClass()
|
||||
;
|
||||
}
|
||||
|
||||
private function addMatcher($supportsRedirections)
|
||||
{
|
||||
// we need to deep clone the routes as we will modify the structure to optimize the dump
|
||||
$code = implode("\n", $this->compileRoutes(clone $this->getRoutes(), $supportsRedirections));
|
||||
|
||||
return <<<EOF
|
||||
|
||||
public function match(\$pathinfo)
|
||||
{
|
||||
\$allow = array();
|
||||
\$pathinfo = urldecode(\$pathinfo);
|
||||
|
||||
$code
|
||||
throw 0 < count(\$allow) ? new MethodNotAllowedException(array_unique(\$allow)) : new ResourceNotFoundException();
|
||||
}
|
||||
|
||||
EOF;
|
||||
}
|
||||
|
||||
private function compileRoutes(RouteCollection $routes, $supportsRedirections, $parentPrefix = null)
|
||||
{
|
||||
$code = array();
|
||||
|
||||
$routeIterator = $routes->getIterator();
|
||||
$keys = array_keys($routeIterator->getArrayCopy());
|
||||
$keysCount = count($keys);
|
||||
|
||||
$i = 0;
|
||||
foreach ($routeIterator as $name => $route) {
|
||||
$i++;
|
||||
|
||||
if ($route instanceof RouteCollection) {
|
||||
$prefix = $route->getPrefix();
|
||||
$optimizable = $prefix && count($route->all()) > 1 && false === strpos($route->getPrefix(), '{');
|
||||
$indent = '';
|
||||
if ($optimizable) {
|
||||
for ($j = $i; $j < $keysCount; $j++) {
|
||||
if ($keys[$j] === null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$testRoute = $routeIterator->offsetGet($keys[$j]);
|
||||
$isCollection = ($testRoute instanceof RouteCollection);
|
||||
|
||||
$testPrefix = $isCollection ? $testRoute->getPrefix() : $testRoute->getPattern();
|
||||
|
||||
if (0 === strpos($testPrefix, $prefix)) {
|
||||
$routeIterator->offsetUnset($keys[$j]);
|
||||
|
||||
if ($isCollection) {
|
||||
$route->addCollection($testRoute);
|
||||
} else {
|
||||
$route->add($keys[$j], $testRoute);
|
||||
}
|
||||
|
||||
$i++;
|
||||
$keys[$j] = null;
|
||||
}
|
||||
}
|
||||
|
||||
if ($prefix !== $parentPrefix) {
|
||||
$code[] = sprintf(" if (0 === strpos(\$pathinfo, %s)) {", var_export($prefix, true));
|
||||
$indent = ' ';
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($this->compileRoutes($route, $supportsRedirections, $prefix) as $line) {
|
||||
foreach (explode("\n", $line) as $l) {
|
||||
if ($l) {
|
||||
$code[] = $indent.$l;
|
||||
} else {
|
||||
$code[] = $l;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($optimizable && $prefix !== $parentPrefix) {
|
||||
$code[] = " }\n";
|
||||
}
|
||||
} else {
|
||||
foreach ($this->compileRoute($route, $name, $supportsRedirections, $parentPrefix) as $line) {
|
||||
$code[] = $line;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $code;
|
||||
}
|
||||
|
||||
private function compileRoute(Route $route, $name, $supportsRedirections, $parentPrefix = null)
|
||||
{
|
||||
$code = array();
|
||||
$compiledRoute = $route->compile();
|
||||
$conditions = array();
|
||||
$hasTrailingSlash = false;
|
||||
$matches = false;
|
||||
if (!count($compiledRoute->getVariables()) && false !== preg_match('#^(.)\^(?P<url>.*?)\$\1#', $compiledRoute->getRegex(), $m)) {
|
||||
if ($supportsRedirections && substr($m['url'], -1) === '/') {
|
||||
$conditions[] = sprintf("rtrim(\$pathinfo, '/') === %s", var_export(rtrim(str_replace('\\', '', $m['url']), '/'), true));
|
||||
$hasTrailingSlash = true;
|
||||
} else {
|
||||
$conditions[] = sprintf("\$pathinfo === %s", var_export(str_replace('\\', '', $m['url']), true));
|
||||
}
|
||||
} else {
|
||||
if ($compiledRoute->getStaticPrefix() && $compiledRoute->getStaticPrefix() != $parentPrefix) {
|
||||
$conditions[] = sprintf("0 === strpos(\$pathinfo, %s)", var_export($compiledRoute->getStaticPrefix(), true));
|
||||
}
|
||||
|
||||
$regex = $compiledRoute->getRegex();
|
||||
if ($supportsRedirections && $pos = strpos($regex, '/$')) {
|
||||
$regex = substr($regex, 0, $pos).'/?$'.substr($regex, $pos + 2);
|
||||
$hasTrailingSlash = true;
|
||||
}
|
||||
$conditions[] = sprintf("preg_match(%s, \$pathinfo, \$matches)", var_export($regex, true));
|
||||
|
||||
$matches = true;
|
||||
}
|
||||
|
||||
$conditions = implode(' && ', $conditions);
|
||||
|
||||
$gotoname = 'not_'.preg_replace('/[^A-Za-z0-9_]/', '', $name);
|
||||
|
||||
$code[] = <<<EOF
|
||||
// $name
|
||||
if ($conditions) {
|
||||
EOF;
|
||||
|
||||
if ($req = $route->getRequirement('_method')) {
|
||||
$methods = explode('|', strtoupper($req));
|
||||
// GET and HEAD are equivalent
|
||||
if (in_array('GET', $methods) && !in_array('HEAD', $methods)) {
|
||||
$methods[] = 'HEAD';
|
||||
}
|
||||
if (1 === count($methods)) {
|
||||
$code[] = <<<EOF
|
||||
if (\$this->context->getMethod() != '$methods[0]') {
|
||||
\$allow[] = '$methods[0]';
|
||||
goto $gotoname;
|
||||
}
|
||||
EOF;
|
||||
} else {
|
||||
$methods = implode('\', \'', $methods);
|
||||
$code[] = <<<EOF
|
||||
if (!in_array(\$this->context->getMethod(), array('$methods'))) {
|
||||
\$allow = array_merge(\$allow, array('$methods'));
|
||||
goto $gotoname;
|
||||
}
|
||||
EOF;
|
||||
}
|
||||
}
|
||||
|
||||
if ($hasTrailingSlash) {
|
||||
$code[] = sprintf(<<<EOF
|
||||
if (substr(\$pathinfo, -1) !== '/') {
|
||||
return \$this->redirect(\$pathinfo.'/', '%s');
|
||||
}
|
||||
EOF
|
||||
, $name);
|
||||
}
|
||||
|
||||
if ($scheme = $route->getRequirement('_scheme')) {
|
||||
if (!$supportsRedirections) {
|
||||
throw new \LogicException('The "_scheme" requirement is only supported for route dumper that implements RedirectableUrlMatcherInterface.');
|
||||
}
|
||||
|
||||
$code[] = sprintf(<<<EOF
|
||||
if (\$this->context->getScheme() !== '$scheme') {
|
||||
return \$this->redirect(\$pathinfo, '%s', '$scheme');
|
||||
}
|
||||
EOF
|
||||
, $name);
|
||||
}
|
||||
|
||||
// optimize parameters array
|
||||
if (true === $matches && $compiledRoute->getDefaults()) {
|
||||
$code[] = sprintf(" return array_merge(\$this->mergeDefaults(\$matches, %s), array('_route' => '%s'));"
|
||||
, str_replace("\n", '', var_export($compiledRoute->getDefaults(), true)), $name);
|
||||
} elseif (true === $matches) {
|
||||
$code[] = sprintf(" \$matches['_route'] = '%s';", $name);
|
||||
$code[] = sprintf(" return \$matches;", $name);
|
||||
} elseif ($compiledRoute->getDefaults()) {
|
||||
$code[] = sprintf(' return %s;', str_replace("\n", '', var_export(array_merge($compiledRoute->getDefaults(), array('_route' => $name)), true)));
|
||||
} else {
|
||||
$code[] = sprintf(" return array('_route' => '%s');", $name);
|
||||
}
|
||||
$code[] = " }";
|
||||
|
||||
if ($req) {
|
||||
$code[] = " $gotoname:";
|
||||
}
|
||||
|
||||
$code[] = '';
|
||||
|
||||
return $code;
|
||||
}
|
||||
|
||||
private function startClass($class, $baseClass)
|
||||
{
|
||||
return <<<EOF
|
||||
<?php
|
||||
|
||||
use Symfony\Component\Routing\Exception\MethodNotAllowedException;
|
||||
use Symfony\Component\Routing\Exception\ResourceNotFoundException;
|
||||
use Symfony\Component\Routing\RequestContext;
|
||||
|
||||
/**
|
||||
* $class
|
||||
*
|
||||
* This class has been auto-generated
|
||||
* by the Symfony Routing Component.
|
||||
*/
|
||||
class $class extends $baseClass
|
||||
{
|
||||
|
||||
EOF;
|
||||
}
|
||||
|
||||
private function addConstructor()
|
||||
{
|
||||
return <<<EOF
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
public function __construct(RequestContext \$context)
|
||||
{
|
||||
\$this->context = \$context;
|
||||
}
|
||||
|
||||
EOF;
|
||||
}
|
||||
|
||||
private function endClass()
|
||||
{
|
||||
return <<<EOF
|
||||
}
|
||||
|
||||
EOF;
|
||||
}
|
||||
}
|
53
3rdparty/symfony/routing/Symfony/Component/Routing/Matcher/RedirectableUrlMatcher.php
vendored
Normal file
53
3rdparty/symfony/routing/Symfony/Component/Routing/Matcher/RedirectableUrlMatcher.php
vendored
Normal file
|
@ -0,0 +1,53 @@
|
|||
<?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\Component\Routing\Matcher;
|
||||
|
||||
use Symfony\Component\Routing\Exception\ResourceNotFoundException;
|
||||
|
||||
/**
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
abstract class RedirectableUrlMatcher extends UrlMatcher implements RedirectableUrlMatcherInterface
|
||||
{
|
||||
private $trailingSlashTest = false;
|
||||
|
||||
/**
|
||||
* @see UrlMatcher::match()
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function match($pathinfo)
|
||||
{
|
||||
try {
|
||||
$parameters = parent::match($pathinfo);
|
||||
} catch (ResourceNotFoundException $e) {
|
||||
if ('/' === substr($pathinfo, -1)) {
|
||||
throw $e;
|
||||
}
|
||||
|
||||
// try with a / at the end
|
||||
$this->trailingSlashTest = true;
|
||||
|
||||
return $this->match($pathinfo.'/');
|
||||
}
|
||||
|
||||
if ($this->trailingSlashTest) {
|
||||
$this->trailingSlashTest = false;
|
||||
|
||||
return $this->redirect($pathinfo, null);
|
||||
}
|
||||
|
||||
return $parameters;
|
||||
}
|
||||
}
|
35
3rdparty/symfony/routing/Symfony/Component/Routing/Matcher/RedirectableUrlMatcherInterface.php
vendored
Normal file
35
3rdparty/symfony/routing/Symfony/Component/Routing/Matcher/RedirectableUrlMatcherInterface.php
vendored
Normal file
|
@ -0,0 +1,35 @@
|
|||
<?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\Component\Routing\Matcher;
|
||||
|
||||
/**
|
||||
* RedirectableUrlMatcherInterface knows how to redirect the user.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
interface RedirectableUrlMatcherInterface
|
||||
{
|
||||
/**
|
||||
* Redirects the user to another URL.
|
||||
*
|
||||
* @param string $path The path info to redirect to.
|
||||
* @param string $route The route that matched
|
||||
* @param string $scheme The URL scheme (null to keep the current one)
|
||||
*
|
||||
* @return array An array of parameters
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function redirect($path, $route, $scheme = null);
|
||||
}
|
|
@ -0,0 +1,151 @@
|
|||
<?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\Component\Routing\Matcher;
|
||||
|
||||
use Symfony\Component\Routing\Exception\MethodNotAllowedException;
|
||||
use Symfony\Component\Routing\Exception\ResourceNotFoundException;
|
||||
use Symfony\Component\Routing\RouteCollection;
|
||||
use Symfony\Component\Routing\RequestContext;
|
||||
|
||||
/**
|
||||
* UrlMatcher matches URL based on a set of routes.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
class UrlMatcher implements UrlMatcherInterface
|
||||
{
|
||||
protected $context;
|
||||
protected $allow;
|
||||
|
||||
private $routes;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param RouteCollection $routes A RouteCollection instance
|
||||
* @param RequestContext $context The context
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function __construct(RouteCollection $routes, RequestContext $context)
|
||||
{
|
||||
$this->routes = $routes;
|
||||
$this->context = $context;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the request context.
|
||||
*
|
||||
* @param RequestContext $context The context
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function setContext(RequestContext $context)
|
||||
{
|
||||
$this->context = $context;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the request context.
|
||||
*
|
||||
* @return RequestContext The context
|
||||
*/
|
||||
public function getContext()
|
||||
{
|
||||
return $this->context;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tries to match a URL with a set of routes.
|
||||
*
|
||||
* @param string $pathinfo The path info to be parsed
|
||||
*
|
||||
* @return array An array of parameters
|
||||
*
|
||||
* @throws ResourceNotFoundException If the resource could not be found
|
||||
* @throws MethodNotAllowedException If the resource was found but the request method is not allowed
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function match($pathinfo)
|
||||
{
|
||||
$this->allow = array();
|
||||
|
||||
if ($ret = $this->matchCollection($pathinfo, $this->routes)) {
|
||||
return $ret;
|
||||
}
|
||||
|
||||
throw 0 < count($this->allow)
|
||||
? new MethodNotAllowedException(array_unique(array_map('strtoupper', $this->allow)))
|
||||
: new ResourceNotFoundException();
|
||||
}
|
||||
|
||||
protected function matchCollection($pathinfo, RouteCollection $routes)
|
||||
{
|
||||
$pathinfo = urldecode($pathinfo);
|
||||
|
||||
foreach ($routes as $name => $route) {
|
||||
if ($route instanceof RouteCollection) {
|
||||
if (false === strpos($route->getPrefix(), '{') && $route->getPrefix() !== substr($pathinfo, 0, strlen($route->getPrefix()))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!$ret = $this->matchCollection($pathinfo, $route)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
$compiledRoute = $route->compile();
|
||||
|
||||
// check the static prefix of the URL first. Only use the more expensive preg_match when it matches
|
||||
if ('' !== $compiledRoute->getStaticPrefix() && 0 !== strpos($pathinfo, $compiledRoute->getStaticPrefix())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!preg_match($compiledRoute->getRegex(), $pathinfo, $matches)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// check HTTP method requirement
|
||||
if ($req = $route->getRequirement('_method')) {
|
||||
// HEAD and GET are equivalent as per RFC
|
||||
if ('HEAD' === $method = $this->context->getMethod()) {
|
||||
$method = 'GET';
|
||||
}
|
||||
|
||||
if (!in_array($method, $req = explode('|', strtoupper($req)))) {
|
||||
$this->allow = array_merge($this->allow, $req);
|
||||
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
return array_merge($this->mergeDefaults($matches, $route->getDefaults()), array('_route' => $name));
|
||||
}
|
||||
}
|
||||
|
||||
protected function mergeDefaults($params, $defaults)
|
||||
{
|
||||
$parameters = $defaults;
|
||||
foreach ($params as $key => $value) {
|
||||
if (!is_int($key)) {
|
||||
$parameters[$key] = rawurldecode($value);
|
||||
}
|
||||
}
|
||||
|
||||
return $parameters;
|
||||
}
|
||||
}
|
38
3rdparty/symfony/routing/Symfony/Component/Routing/Matcher/UrlMatcherInterface.php
vendored
Normal file
38
3rdparty/symfony/routing/Symfony/Component/Routing/Matcher/UrlMatcherInterface.php
vendored
Normal file
|
@ -0,0 +1,38 @@
|
|||
<?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\Component\Routing\Matcher;
|
||||
|
||||
use Symfony\Component\Routing\RequestContextAwareInterface;
|
||||
|
||||
/**
|
||||
* UrlMatcherInterface is the interface that all URL matcher classes must implement.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
interface UrlMatcherInterface extends RequestContextAwareInterface
|
||||
{
|
||||
/**
|
||||
* Tries to match a URL with a set of routes.
|
||||
*
|
||||
* @param string $pathinfo The path info to be parsed
|
||||
*
|
||||
* @return array An array of parameters
|
||||
*
|
||||
* @throws ResourceNotFoundException If the resource could not be found
|
||||
* @throws MethodNotAllowedException If the resource was found but the request method is not allowed
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function match($pathinfo);
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
Routing Component
|
||||
=================
|
||||
|
||||
Routing associates a request with the code that will convert it to a response.
|
||||
|
||||
The example below demonstrates how you can set up a fully working routing
|
||||
system:
|
||||
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\Routing\Matcher\UrlMatcher;
|
||||
use Symfony\Component\Routing\RequestContext;
|
||||
use Symfony\Component\Routing\RouteCollection;
|
||||
use Symfony\Component\Routing\Route;
|
||||
|
||||
$routes = new RouteCollection();
|
||||
$routes->add('hello', new Route('/hello', array('controller' => 'foo')));
|
||||
|
||||
$context = new RequestContext();
|
||||
|
||||
// this is optional and can be done without a Request instance
|
||||
$context->fromRequest(Request::createFromGlobals());
|
||||
|
||||
$matcher = new UrlMatcher($routes, $context);
|
||||
|
||||
$parameters = $matcher->match('/hello');
|
||||
|
||||
Resources
|
||||
---------
|
||||
|
||||
Unit tests:
|
||||
|
||||
https://github.com/symfony/symfony/tree/master/tests/Symfony/Tests/Component/Routing
|
|
@ -0,0 +1,250 @@
|
|||
<?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\Component\Routing;
|
||||
|
||||
/**
|
||||
* Holds information about the current request.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
class RequestContext
|
||||
{
|
||||
private $baseUrl;
|
||||
private $method;
|
||||
private $host;
|
||||
private $scheme;
|
||||
private $httpPort;
|
||||
private $httpsPort;
|
||||
private $parameters;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param string $baseUrl The base URL
|
||||
* @param string $method The HTTP method
|
||||
* @param string $host The HTTP host name
|
||||
* @param string $scheme The HTTP scheme
|
||||
* @param integer $httpPort The HTTP port
|
||||
* @param integer $httpsPort The HTTPS port
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function __construct($baseUrl = '', $method = 'GET', $host = 'localhost', $scheme = 'http', $httpPort = 80, $httpsPort = 443)
|
||||
{
|
||||
$this->baseUrl = $baseUrl;
|
||||
$this->method = strtoupper($method);
|
||||
$this->host = $host;
|
||||
$this->scheme = strtolower($scheme);
|
||||
$this->httpPort = $httpPort;
|
||||
$this->httpsPort = $httpsPort;
|
||||
$this->parameters = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the base URL.
|
||||
*
|
||||
* @return string The base URL
|
||||
*/
|
||||
public function getBaseUrl()
|
||||
{
|
||||
return $this->baseUrl;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the base URL.
|
||||
*
|
||||
* @param string $baseUrl The base URL
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function setBaseUrl($baseUrl)
|
||||
{
|
||||
$this->baseUrl = $baseUrl;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the HTTP method.
|
||||
*
|
||||
* The method is always an uppercased string.
|
||||
*
|
||||
* @return string The HTTP method
|
||||
*/
|
||||
public function getMethod()
|
||||
{
|
||||
return $this->method;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the HTTP method.
|
||||
*
|
||||
* @param string $method The HTTP method
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function setMethod($method)
|
||||
{
|
||||
$this->method = strtoupper($method);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the HTTP host.
|
||||
*
|
||||
* @return string The HTTP host
|
||||
*/
|
||||
public function getHost()
|
||||
{
|
||||
return $this->host;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the HTTP host.
|
||||
*
|
||||
* @param string $host The HTTP host
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function setHost($host)
|
||||
{
|
||||
$this->host = $host;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the HTTP scheme.
|
||||
*
|
||||
* @return string The HTTP scheme
|
||||
*/
|
||||
public function getScheme()
|
||||
{
|
||||
return $this->scheme;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the HTTP scheme.
|
||||
*
|
||||
* @param string $scheme The HTTP scheme
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function setScheme($scheme)
|
||||
{
|
||||
$this->scheme = strtolower($scheme);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the HTTP port.
|
||||
*
|
||||
* @return string The HTTP port
|
||||
*/
|
||||
public function getHttpPort()
|
||||
{
|
||||
return $this->httpPort;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the HTTP port.
|
||||
*
|
||||
* @param string $httpPort The HTTP port
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function setHttpPort($httpPort)
|
||||
{
|
||||
$this->httpPort = $httpPort;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the HTTPS port.
|
||||
*
|
||||
* @return string The HTTPS port
|
||||
*/
|
||||
public function getHttpsPort()
|
||||
{
|
||||
return $this->httpsPort;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the HTTPS port.
|
||||
*
|
||||
* @param string $httpsPort The HTTPS port
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function setHttpsPort($httpsPort)
|
||||
{
|
||||
$this->httpsPort = $httpsPort;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the parameters.
|
||||
*
|
||||
* @return array The parameters
|
||||
*/
|
||||
public function getParameters()
|
||||
{
|
||||
return $this->parameters;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the parameters.
|
||||
*
|
||||
* This method implements a fluent interface.
|
||||
*
|
||||
* @param array $parameters The parameters
|
||||
*
|
||||
* @return Route The current Route instance
|
||||
*/
|
||||
public function setParameters(array $parameters)
|
||||
{
|
||||
$this->parameters = $parameters;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a parameter value.
|
||||
*
|
||||
* @param string $name A parameter name
|
||||
*
|
||||
* @return mixed The parameter value
|
||||
*/
|
||||
public function getParameter($name)
|
||||
{
|
||||
return isset($this->parameters[$name]) ? $this->parameters[$name] : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a parameter value is set for the given parameter.
|
||||
*
|
||||
* @param string $name A parameter name
|
||||
*
|
||||
* @return Boolean true if the parameter value is set, false otherwise
|
||||
*/
|
||||
public function hasParameter($name)
|
||||
{
|
||||
return array_key_exists($name, $this->parameters);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a parameter value.
|
||||
*
|
||||
* @param string $name A parameter name
|
||||
* @param mixed $parameter The parameter value
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function setParameter($name, $parameter)
|
||||
{
|
||||
$this->parameters[$name] = $parameter;
|
||||
}
|
||||
}
|
27
3rdparty/symfony/routing/Symfony/Component/Routing/RequestContextAwareInterface.php
vendored
Normal file
27
3rdparty/symfony/routing/Symfony/Component/Routing/RequestContextAwareInterface.php
vendored
Normal file
|
@ -0,0 +1,27 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Routing;
|
||||
|
||||
/**
|
||||
* @api
|
||||
*/
|
||||
interface RequestContextAwareInterface
|
||||
{
|
||||
/**
|
||||
* Sets the request context.
|
||||
*
|
||||
* @param RequestContext $context The context
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function setContext(RequestContext $context);
|
||||
}
|
|
@ -0,0 +1,312 @@
|
|||
<?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\Component\Routing;
|
||||
|
||||
/**
|
||||
* A Route describes a route and its parameters.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
class Route
|
||||
{
|
||||
private $pattern;
|
||||
private $defaults;
|
||||
private $requirements;
|
||||
private $options;
|
||||
private $compiled;
|
||||
|
||||
private static $compilers = array();
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* Available options:
|
||||
*
|
||||
* * compiler_class: A class name able to compile this route instance (RouteCompiler by default)
|
||||
*
|
||||
* @param string $pattern The pattern to match
|
||||
* @param array $defaults An array of default parameter values
|
||||
* @param array $requirements An array of requirements for parameters (regexes)
|
||||
* @param array $options An array of options
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function __construct($pattern, array $defaults = array(), array $requirements = array(), array $options = array())
|
||||
{
|
||||
$this->setPattern($pattern);
|
||||
$this->setDefaults($defaults);
|
||||
$this->setRequirements($requirements);
|
||||
$this->setOptions($options);
|
||||
}
|
||||
|
||||
public function __clone()
|
||||
{
|
||||
$this->compiled = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the pattern.
|
||||
*
|
||||
* @return string The pattern
|
||||
*/
|
||||
public function getPattern()
|
||||
{
|
||||
return $this->pattern;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the pattern.
|
||||
*
|
||||
* This method implements a fluent interface.
|
||||
*
|
||||
* @param string $pattern The pattern
|
||||
*
|
||||
* @return Route The current Route instance
|
||||
*/
|
||||
public function setPattern($pattern)
|
||||
{
|
||||
$this->pattern = trim($pattern);
|
||||
|
||||
// a route must start with a slash
|
||||
if (empty($this->pattern) || '/' !== $this->pattern[0]) {
|
||||
$this->pattern = '/'.$this->pattern;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the options.
|
||||
*
|
||||
* @return array The options
|
||||
*/
|
||||
public function getOptions()
|
||||
{
|
||||
return $this->options;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the options.
|
||||
*
|
||||
* This method implements a fluent interface.
|
||||
*
|
||||
* @param array $options The options
|
||||
*
|
||||
* @return Route The current Route instance
|
||||
*/
|
||||
public function setOptions(array $options)
|
||||
{
|
||||
$this->options = array_merge(array(
|
||||
'compiler_class' => 'Symfony\\Component\\Routing\\RouteCompiler',
|
||||
), $options);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets an option value.
|
||||
*
|
||||
* This method implements a fluent interface.
|
||||
*
|
||||
* @param string $name An option name
|
||||
* @param mixed $value The option value
|
||||
*
|
||||
* @return Route The current Route instance
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function setOption($name, $value)
|
||||
{
|
||||
$this->options[$name] = $value;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an option value.
|
||||
*
|
||||
* @param string $name An option name
|
||||
*
|
||||
* @return mixed The option value
|
||||
*/
|
||||
public function getOption($name)
|
||||
{
|
||||
return isset($this->options[$name]) ? $this->options[$name] : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the defaults.
|
||||
*
|
||||
* @return array The defaults
|
||||
*/
|
||||
public function getDefaults()
|
||||
{
|
||||
return $this->defaults;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the defaults.
|
||||
*
|
||||
* This method implements a fluent interface.
|
||||
*
|
||||
* @param array $defaults The defaults
|
||||
*
|
||||
* @return Route The current Route instance
|
||||
*/
|
||||
public function setDefaults(array $defaults)
|
||||
{
|
||||
$this->defaults = array();
|
||||
foreach ($defaults as $name => $default) {
|
||||
$this->defaults[(string) $name] = $default;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a default value.
|
||||
*
|
||||
* @param string $name A variable name
|
||||
*
|
||||
* @return mixed The default value
|
||||
*/
|
||||
public function getDefault($name)
|
||||
{
|
||||
return isset($this->defaults[$name]) ? $this->defaults[$name] : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a default value is set for the given variable.
|
||||
*
|
||||
* @param string $name A variable name
|
||||
*
|
||||
* @return Boolean true if the default value is set, false otherwise
|
||||
*/
|
||||
public function hasDefault($name)
|
||||
{
|
||||
return array_key_exists($name, $this->defaults);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a default value.
|
||||
*
|
||||
* @param string $name A variable name
|
||||
* @param mixed $default The default value
|
||||
*
|
||||
* @return Route The current Route instance
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function setDefault($name, $default)
|
||||
{
|
||||
$this->defaults[(string) $name] = $default;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the requirements.
|
||||
*
|
||||
* @return array The requirements
|
||||
*/
|
||||
public function getRequirements()
|
||||
{
|
||||
return $this->requirements;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the requirements.
|
||||
*
|
||||
* This method implements a fluent interface.
|
||||
*
|
||||
* @param array $requirements The requirements
|
||||
*
|
||||
* @return Route The current Route instance
|
||||
*/
|
||||
public function setRequirements(array $requirements)
|
||||
{
|
||||
$this->requirements = array();
|
||||
foreach ($requirements as $key => $regex) {
|
||||
$this->requirements[$key] = $this->sanitizeRequirement($key, $regex);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the requirement for the given key.
|
||||
*
|
||||
* @param string $key The key
|
||||
*
|
||||
* @return string The regex
|
||||
*/
|
||||
public function getRequirement($key)
|
||||
{
|
||||
return isset($this->requirements[$key]) ? $this->requirements[$key] : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a requirement for the given key.
|
||||
*
|
||||
* @param string $key The key
|
||||
* @param string $regex The regex
|
||||
*
|
||||
* @return Route The current Route instance
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function setRequirement($key, $regex)
|
||||
{
|
||||
$this->requirements[$key] = $this->sanitizeRequirement($key, $regex);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compiles the route.
|
||||
*
|
||||
* @return CompiledRoute A CompiledRoute instance
|
||||
*/
|
||||
public function compile()
|
||||
{
|
||||
if (null !== $this->compiled) {
|
||||
return $this->compiled;
|
||||
}
|
||||
|
||||
$class = $this->getOption('compiler_class');
|
||||
|
||||
if (!isset(self::$compilers[$class])) {
|
||||
self::$compilers[$class] = new $class;
|
||||
}
|
||||
|
||||
return $this->compiled = self::$compilers[$class]->compile($this);
|
||||
}
|
||||
|
||||
private function sanitizeRequirement($key, $regex)
|
||||
{
|
||||
if (is_array($regex)) {
|
||||
throw new \InvalidArgumentException(sprintf('Routing requirements must be a string, array given for "%s"', $key));
|
||||
}
|
||||
|
||||
if ('^' == $regex[0]) {
|
||||
$regex = substr($regex, 1);
|
||||
}
|
||||
|
||||
if ('$' == substr($regex, -1)) {
|
||||
$regex = substr($regex, 0, -1);
|
||||
}
|
||||
|
||||
return $regex;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,259 @@
|
|||
<?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\Component\Routing;
|
||||
|
||||
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 the instance or its children and parents.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
class RouteCollection implements \IteratorAggregate
|
||||
{
|
||||
private $routes;
|
||||
private $resources;
|
||||
private $prefix;
|
||||
private $parent;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->routes = array();
|
||||
$this->resources = array();
|
||||
$this->prefix = '';
|
||||
}
|
||||
|
||||
public function __clone()
|
||||
{
|
||||
foreach ($this->routes as $name => $route) {
|
||||
$this->routes[$name] = clone $route;
|
||||
if ($route instanceof RouteCollection) {
|
||||
$this->routes[$name]->setParent($this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a route.
|
||||
*
|
||||
* @param string $name The route name
|
||||
* @param Route $route A Route instance
|
||||
*
|
||||
* @throws \InvalidArgumentException When route name contains non valid characters
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function add($name, Route $route)
|
||||
{
|
||||
if (!preg_match('/^[a-z0-9A-Z_.]+$/', $name)) {
|
||||
throw new \InvalidArgumentException(sprintf('The provided route name "%s" contains non valid characters. A route name must only contain digits (0-9), letters (a-z and A-Z), underscores (_) and dots (.).', $name));
|
||||
}
|
||||
|
||||
$parent = $this;
|
||||
while ($parent->getParent()) {
|
||||
$parent = $parent->getParent();
|
||||
}
|
||||
|
||||
if ($parent) {
|
||||
$parent->remove($name);
|
||||
}
|
||||
|
||||
$this->routes[$name] = $route;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the array of routes.
|
||||
*
|
||||
* @return array An array of routes
|
||||
*/
|
||||
public function all()
|
||||
{
|
||||
$routes = array();
|
||||
foreach ($this->routes as $name => $route) {
|
||||
if ($route instanceof RouteCollection) {
|
||||
$routes = array_merge($routes, $route->all());
|
||||
} else {
|
||||
$routes[$name] = $route;
|
||||
}
|
||||
}
|
||||
|
||||
return $routes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a route by name.
|
||||
*
|
||||
* @param string $name The route name
|
||||
*
|
||||
* @return Route $route A Route instance
|
||||
*/
|
||||
public function get($name)
|
||||
{
|
||||
// get the latest defined route
|
||||
foreach (array_reverse($this->routes) as $routes) {
|
||||
if (!$routes instanceof RouteCollection) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (null !== $route = $routes->get($name)) {
|
||||
return $route;
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($this->routes[$name])) {
|
||||
return $this->routes[$name];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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).
|
||||
*
|
||||
* @param RouteCollection $collection A RouteCollection instance
|
||||
* @param string $prefix An optional prefix to add before each pattern of the route collection
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a prefix to all routes in the current set.
|
||||
*
|
||||
* @param string $prefix An optional prefix to add before each pattern of the route collection
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function addPrefix($prefix)
|
||||
{
|
||||
// a prefix must not end with a slash
|
||||
$prefix = rtrim($prefix, '/');
|
||||
|
||||
if (!$prefix) {
|
||||
return;
|
||||
}
|
||||
|
||||
// a prefix must start with a slash
|
||||
if ('/' !== $prefix[0]) {
|
||||
$prefix = '/'.$prefix;
|
||||
}
|
||||
|
||||
$this->prefix = $prefix.$this->prefix;
|
||||
|
||||
foreach ($this->routes as $name => $route) {
|
||||
if ($route instanceof RouteCollection) {
|
||||
$route->addPrefix($prefix);
|
||||
} else {
|
||||
$route->setPattern($prefix.$route->getPattern());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function getPrefix()
|
||||
{
|
||||
return $this->prefix;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of resources loaded to build this collection.
|
||||
*
|
||||
* @return ResourceInterface[] An array of resources
|
||||
*/
|
||||
public function getResources()
|
||||
{
|
||||
$resources = $this->resources;
|
||||
foreach ($this as $routes) {
|
||||
if ($routes instanceof RouteCollection) {
|
||||
$resources = array_merge($resources, $routes->getResources());
|
||||
}
|
||||
}
|
||||
|
||||
return array_unique($resources);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a resource for this collection.
|
||||
*
|
||||
* @param ResourceInterface $resource A resource instance
|
||||
*/
|
||||
public function addResource(ResourceInterface $resource)
|
||||
{
|
||||
$this->resources[] = $resource;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,128 @@
|
|||
<?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\Component\Routing;
|
||||
|
||||
/**
|
||||
* RouteCompiler compiles Route instances to CompiledRoute instances.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
class RouteCompiler implements RouteCompilerInterface
|
||||
{
|
||||
/**
|
||||
* Compiles the current route instance.
|
||||
*
|
||||
* @param Route $route A Route instance
|
||||
*
|
||||
* @return CompiledRoute A CompiledRoute instance
|
||||
*/
|
||||
public function compile(Route $route)
|
||||
{
|
||||
$pattern = $route->getPattern();
|
||||
$len = strlen($pattern);
|
||||
$tokens = array();
|
||||
$variables = array();
|
||||
$pos = 0;
|
||||
preg_match_all('#.\{([\w\d_]+)\}#', $pattern, $matches, PREG_OFFSET_CAPTURE | PREG_SET_ORDER);
|
||||
foreach ($matches as $match) {
|
||||
if ($text = substr($pattern, $pos, $match[0][1] - $pos)) {
|
||||
$tokens[] = array('text', $text);
|
||||
}
|
||||
$seps = array($pattern[$pos]);
|
||||
$pos = $match[0][1] + strlen($match[0][0]);
|
||||
$var = $match[1][0];
|
||||
|
||||
if ($req = $route->getRequirement($var)) {
|
||||
$regexp = $req;
|
||||
} else {
|
||||
if ($pos !== $len) {
|
||||
$seps[] = $pattern[$pos];
|
||||
}
|
||||
$regexp = sprintf('[^%s]+?', preg_quote(implode('', array_unique($seps)), '#'));
|
||||
}
|
||||
|
||||
$tokens[] = array('variable', $match[0][0][0], $regexp, $var);
|
||||
|
||||
if (in_array($var, $variables)) {
|
||||
throw new \LogicException(sprintf('Route pattern "%s" cannot reference variable name "%s" more than once.', $route->getPattern(), $var));
|
||||
}
|
||||
|
||||
$variables[] = $var;
|
||||
}
|
||||
|
||||
if ($pos < $len) {
|
||||
$tokens[] = array('text', substr($pattern, $pos));
|
||||
}
|
||||
|
||||
// find the first optional token
|
||||
$firstOptional = INF;
|
||||
for ($i = count($tokens) - 1; $i >= 0; $i--) {
|
||||
$token = $tokens[$i];
|
||||
if ('variable' === $token[0] && $route->hasDefault($token[3])) {
|
||||
$firstOptional = $i;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// compute the matching regexp
|
||||
$regexp = '';
|
||||
for ($i = 0, $nbToken = count($tokens); $i < $nbToken; $i++) {
|
||||
$regexp .= $this->computeRegexp($tokens, $i, $firstOptional);
|
||||
}
|
||||
|
||||
return new CompiledRoute(
|
||||
$route,
|
||||
'text' === $tokens[0][0] ? $tokens[0][1] : '',
|
||||
sprintf("#^%s$#s", $regexp),
|
||||
array_reverse($tokens),
|
||||
$variables
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes the regexp used to match the token.
|
||||
*
|
||||
* @param array $tokens The route tokens
|
||||
* @param integer $index The index of the current token
|
||||
* @param integer $firstOptional The index of the first optional token
|
||||
*
|
||||
* @return string The regexp
|
||||
*/
|
||||
private function computeRegexp(array $tokens, $index, $firstOptional)
|
||||
{
|
||||
$token = $tokens[$index];
|
||||
if ('text' === $token[0]) {
|
||||
// Text tokens
|
||||
return preg_quote($token[1], '#');
|
||||
} else {
|
||||
// Variable tokens
|
||||
if (0 === $index && 0 === $firstOptional && 1 == count($tokens)) {
|
||||
// When the only token is an optional variable token, the separator is required
|
||||
return sprintf('%s(?P<%s>%s)?', preg_quote($token[1], '#'), $token[3], $token[2]);
|
||||
} else {
|
||||
$nbTokens = count($tokens);
|
||||
$regexp = sprintf('%s(?P<%s>%s)', preg_quote($token[1], '#'), $token[3], $token[2]);
|
||||
if ($index >= $firstOptional) {
|
||||
// Enclose each optional tokens in a subpattern to make it optional
|
||||
$regexp = "(?:$regexp";
|
||||
if ($nbTokens - 1 == $index) {
|
||||
// Close the optional subpatterns
|
||||
$regexp .= str_repeat(")?", $nbTokens - $firstOptional);
|
||||
}
|
||||
}
|
||||
|
||||
return $regexp;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
29
3rdparty/symfony/routing/Symfony/Component/Routing/RouteCompilerInterface.php
vendored
Normal file
29
3rdparty/symfony/routing/Symfony/Component/Routing/RouteCompilerInterface.php
vendored
Normal file
|
@ -0,0 +1,29 @@
|
|||
<?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\Component\Routing;
|
||||
|
||||
/**
|
||||
* RouteCompilerInterface is the interface that all RouteCompiler classes must implements.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
interface RouteCompilerInterface
|
||||
{
|
||||
/**
|
||||
* Compiles the current route instance.
|
||||
*
|
||||
* @param Route $route A Route instance
|
||||
*
|
||||
* @return CompiledRoute A CompiledRoute instance
|
||||
*/
|
||||
public function compile(Route $route);
|
||||
}
|
|
@ -0,0 +1,263 @@
|
|||
<?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\Component\Routing;
|
||||
|
||||
use Symfony\Component\Config\Loader\LoaderInterface;
|
||||
use Symfony\Component\Config\ConfigCache;
|
||||
|
||||
/**
|
||||
* The Router class is an example of the integration of all pieces of the
|
||||
* routing system for easier use.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
class Router implements RouterInterface
|
||||
{
|
||||
protected $matcher;
|
||||
protected $generator;
|
||||
protected $defaults;
|
||||
protected $context;
|
||||
protected $loader;
|
||||
protected $collection;
|
||||
protected $resource;
|
||||
protected $options;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param LoaderInterface $loader A LoaderInterface instance
|
||||
* @param mixed $resource The main resource to load
|
||||
* @param array $options An array of options
|
||||
* @param RequestContext $context The context
|
||||
* @param array $defaults The default values
|
||||
*/
|
||||
public function __construct(LoaderInterface $loader, $resource, array $options = array(), RequestContext $context = null, array $defaults = array())
|
||||
{
|
||||
$this->loader = $loader;
|
||||
$this->resource = $resource;
|
||||
$this->context = null === $context ? new RequestContext() : $context;
|
||||
$this->defaults = $defaults;
|
||||
$this->setOptions($options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets options.
|
||||
*
|
||||
* Available options:
|
||||
*
|
||||
* * cache_dir: The cache directory (or null to disable caching)
|
||||
* * debug: Whether to enable debugging or not (false by default)
|
||||
* * resource_type: Type hint for the main resource (optional)
|
||||
*
|
||||
* @param array $options An array of options
|
||||
*
|
||||
* @throws \InvalidArgumentException When unsupported option is provided
|
||||
*/
|
||||
public function setOptions(array $options)
|
||||
{
|
||||
$this->options = array(
|
||||
'cache_dir' => null,
|
||||
'debug' => false,
|
||||
'generator_class' => 'Symfony\\Component\\Routing\\Generator\\UrlGenerator',
|
||||
'generator_base_class' => 'Symfony\\Component\\Routing\\Generator\\UrlGenerator',
|
||||
'generator_dumper_class' => 'Symfony\\Component\\Routing\\Generator\\Dumper\\PhpGeneratorDumper',
|
||||
'generator_cache_class' => 'ProjectUrlGenerator',
|
||||
'matcher_class' => 'Symfony\\Component\\Routing\\Matcher\\UrlMatcher',
|
||||
'matcher_base_class' => 'Symfony\\Component\\Routing\\Matcher\\UrlMatcher',
|
||||
'matcher_dumper_class' => 'Symfony\\Component\\Routing\\Matcher\\Dumper\\PhpMatcherDumper',
|
||||
'matcher_cache_class' => 'ProjectUrlMatcher',
|
||||
'resource_type' => null,
|
||||
);
|
||||
|
||||
// check option names and live merge, if errors are encountered Exception will be thrown
|
||||
$invalid = array();
|
||||
$isInvalid = false;
|
||||
foreach ($options as $key => $value) {
|
||||
if (array_key_exists($key, $this->options)) {
|
||||
$this->options[$key] = $value;
|
||||
} else {
|
||||
$isInvalid = true;
|
||||
$invalid[] = $key;
|
||||
}
|
||||
}
|
||||
|
||||
if ($isInvalid) {
|
||||
throw new \InvalidArgumentException(sprintf('The Router does not support the following options: "%s".', implode('\', \'', $invalid)));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets an option.
|
||||
*
|
||||
* @param string $key The key
|
||||
* @param mixed $value The value
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function setOption($key, $value)
|
||||
{
|
||||
if (!array_key_exists($key, $this->options)) {
|
||||
throw new \InvalidArgumentException(sprintf('The Router does not support the "%s" option.', $key));
|
||||
}
|
||||
|
||||
$this->options[$key] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an option value.
|
||||
*
|
||||
* @param string $key The key
|
||||
*
|
||||
* @return mixed The value
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function getOption($key)
|
||||
{
|
||||
if (!array_key_exists($key, $this->options)) {
|
||||
throw new \InvalidArgumentException(sprintf('The Router does not support the "%s" option.', $key));
|
||||
}
|
||||
|
||||
return $this->options[$key];
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the RouteCollection instance associated with this Router.
|
||||
*
|
||||
* @return RouteCollection A RouteCollection instance
|
||||
*/
|
||||
public function getRouteCollection()
|
||||
{
|
||||
if (null === $this->collection) {
|
||||
$this->collection = $this->loader->load($this->resource, $this->options['resource_type']);
|
||||
}
|
||||
|
||||
return $this->collection;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the request context.
|
||||
*
|
||||
* @param RequestContext $context The context
|
||||
*/
|
||||
public function setContext(RequestContext $context)
|
||||
{
|
||||
$this->context = $context;
|
||||
|
||||
$this->getMatcher()->setContext($context);
|
||||
$this->getGenerator()->setContext($context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the request context.
|
||||
*
|
||||
* @return RequestContext The context
|
||||
*/
|
||||
public function getContext()
|
||||
{
|
||||
return $this->context;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a URL from the given parameters.
|
||||
*
|
||||
* @param string $name The name of the route
|
||||
* @param mixed $parameters An array of parameters
|
||||
* @param Boolean $absolute Whether to generate an absolute URL
|
||||
*
|
||||
* @return string The generated URL
|
||||
*/
|
||||
public function generate($name, $parameters = array(), $absolute = false)
|
||||
{
|
||||
return $this->getGenerator()->generate($name, $parameters, $absolute);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tries to match a URL with a set of routes.
|
||||
*
|
||||
* Returns false if no route matches the URL.
|
||||
*
|
||||
* @param string $url URL to be parsed
|
||||
*
|
||||
* @return array|false An array of parameters or false if no route matches
|
||||
*/
|
||||
public function match($url)
|
||||
{
|
||||
return $this->getMatcher()->match($url);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the UrlMatcher instance associated with this Router.
|
||||
*
|
||||
* @return UrlMatcherInterface A UrlMatcherInterface instance
|
||||
*/
|
||||
public function getMatcher()
|
||||
{
|
||||
if (null !== $this->matcher) {
|
||||
return $this->matcher;
|
||||
}
|
||||
|
||||
if (null === $this->options['cache_dir'] || null === $this->options['matcher_cache_class']) {
|
||||
return $this->matcher = new $this->options['matcher_class']($this->getRouteCollection(), $this->context, $this->defaults);
|
||||
}
|
||||
|
||||
$class = $this->options['matcher_cache_class'];
|
||||
$cache = new ConfigCache($this->options['cache_dir'].'/'.$class.'.php', $this->options['debug']);
|
||||
if (!$cache->isFresh($class)) {
|
||||
$dumper = new $this->options['matcher_dumper_class']($this->getRouteCollection());
|
||||
|
||||
$options = array(
|
||||
'class' => $class,
|
||||
'base_class' => $this->options['matcher_base_class'],
|
||||
);
|
||||
|
||||
$cache->write($dumper->dump($options), $this->getRouteCollection()->getResources());
|
||||
}
|
||||
|
||||
require_once $cache;
|
||||
|
||||
return $this->matcher = new $class($this->context, $this->defaults);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the UrlGenerator instance associated with this Router.
|
||||
*
|
||||
* @return UrlGeneratorInterface A UrlGeneratorInterface instance
|
||||
*/
|
||||
public function getGenerator()
|
||||
{
|
||||
if (null !== $this->generator) {
|
||||
return $this->generator;
|
||||
}
|
||||
|
||||
if (null === $this->options['cache_dir'] || null === $this->options['generator_cache_class']) {
|
||||
return $this->generator = new $this->options['generator_class']($this->getRouteCollection(), $this->context, $this->defaults);
|
||||
}
|
||||
|
||||
$class = $this->options['generator_cache_class'];
|
||||
$cache = new ConfigCache($this->options['cache_dir'].'/'.$class.'.php', $this->options['debug']);
|
||||
if (!$cache->isFresh($class)) {
|
||||
$dumper = new $this->options['generator_dumper_class']($this->getRouteCollection());
|
||||
|
||||
$options = array(
|
||||
'class' => $class,
|
||||
'base_class' => $this->options['generator_base_class'],
|
||||
);
|
||||
|
||||
$cache->write($dumper->dump($options), $this->getRouteCollection()->getResources());
|
||||
}
|
||||
|
||||
require_once $cache;
|
||||
|
||||
return $this->generator = new $class($this->context, $this->defaults);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
<?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\Component\Routing;
|
||||
|
||||
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
|
||||
use Symfony\Component\Routing\Matcher\UrlMatcherInterface;
|
||||
|
||||
/**
|
||||
* RouterInterface is the interface that all Router classes must implements.
|
||||
*
|
||||
* This interface is the concatenation of UrlMatcherInterface and UrlGeneratorInterface.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
interface RouterInterface extends UrlMatcherInterface, UrlGeneratorInterface
|
||||
{
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
{
|
||||
"name": "symfony/routing",
|
||||
"type": "library",
|
||||
"description": "Symfony Routing Component",
|
||||
"keywords": [],
|
||||
"homepage": "http://symfony.com",
|
||||
"license": "MIT",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Fabien Potencier",
|
||||
"email": "fabien@symfony.com"
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "http://symfony.com/contributors"
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": ">=5.3.2"
|
||||
},
|
||||
"suggest": {
|
||||
"symfony/config": "self.version",
|
||||
"symfony/yaml": "self.version"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-0": { "Symfony\\Component\\Routing": "" }
|
||||
},
|
||||
"target-dir": "Symfony/Component/Routing"
|
||||
}
|
|
@ -1,18 +0,0 @@
|
|||
{
|
||||
"description": "ownCloud gives you universal access to your files/contacts/calendar through a web interface or WebDAV.",
|
||||
"homepage": "http://owncloud.org",
|
||||
"license": "AGPL-3.0+",
|
||||
"support": {
|
||||
"email": "owncloud@kde.org",
|
||||
"irc": "irc://irc.freenode.org/owncloud",
|
||||
"forum": "http://forum.owncloud.org/",
|
||||
"issues": "https://github.com/owncloud/core/issues"
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.2",
|
||||
"symfony/routing": "2.0.*"
|
||||
},
|
||||
"config": {
|
||||
"vendor-dir": "3rdparty"
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue