aboutsummaryrefslogtreecommitdiffhomepage
path: root/assets/php/vendor/symfony/routing
diff options
context:
space:
mode:
authormarvin-borner@live.com2018-04-10 21:50:16 +0200
committermarvin-borner@live.com2018-04-10 21:54:48 +0200
commitfc9401f04a3aca5abb22f87ebc210de8afe11d32 (patch)
treeb0b310f3581764ec3955f4e496a05137a32951c3 /assets/php/vendor/symfony/routing
parent286d643180672f20526f3dc3bd19d7b751e2fa97 (diff)
Initial Commit
Diffstat (limited to 'assets/php/vendor/symfony/routing')
-rw-r--r--assets/php/vendor/symfony/routing/.gitignore3
-rw-r--r--assets/php/vendor/symfony/routing/Annotation/Route.php144
-rw-r--r--assets/php/vendor/symfony/routing/CHANGELOG.md228
-rw-r--r--assets/php/vendor/symfony/routing/CompiledRoute.php169
-rw-r--r--assets/php/vendor/symfony/routing/DependencyInjection/RoutingResolverPass.php49
-rw-r--r--assets/php/vendor/symfony/routing/Exception/ExceptionInterface.php21
-rw-r--r--assets/php/vendor/symfony/routing/Exception/InvalidParameterException.php21
-rw-r--r--assets/php/vendor/symfony/routing/Exception/MethodNotAllowedException.php41
-rw-r--r--assets/php/vendor/symfony/routing/Exception/MissingMandatoryParametersException.php22
-rw-r--r--assets/php/vendor/symfony/routing/Exception/NoConfigurationException.php21
-rw-r--r--assets/php/vendor/symfony/routing/Exception/ResourceNotFoundException.php23
-rw-r--r--assets/php/vendor/symfony/routing/Exception/RouteNotFoundException.php21
-rw-r--r--assets/php/vendor/symfony/routing/Generator/ConfigurableRequirementsInterface.php55
-rw-r--r--assets/php/vendor/symfony/routing/Generator/Dumper/GeneratorDumper.php37
-rw-r--r--assets/php/vendor/symfony/routing/Generator/Dumper/GeneratorDumperInterface.php39
-rw-r--r--assets/php/vendor/symfony/routing/Generator/Dumper/PhpGeneratorDumper.php118
-rw-r--r--assets/php/vendor/symfony/routing/Generator/UrlGenerator.php321
-rw-r--r--assets/php/vendor/symfony/routing/Generator/UrlGeneratorInterface.php86
-rw-r--r--assets/php/vendor/symfony/routing/LICENSE19
-rw-r--r--assets/php/vendor/symfony/routing/Loader/AnnotationClassLoader.php269
-rw-r--r--assets/php/vendor/symfony/routing/Loader/AnnotationDirectoryLoader.php93
-rw-r--r--assets/php/vendor/symfony/routing/Loader/AnnotationFileLoader.php142
-rw-r--r--assets/php/vendor/symfony/routing/Loader/ClosureLoader.php46
-rw-r--r--assets/php/vendor/symfony/routing/Loader/Configurator/CollectionConfigurator.php81
-rw-r--r--assets/php/vendor/symfony/routing/Loader/Configurator/ImportConfigurator.php49
-rw-r--r--assets/php/vendor/symfony/routing/Loader/Configurator/RouteConfigurator.php34
-rw-r--r--assets/php/vendor/symfony/routing/Loader/Configurator/RoutingConfigurator.php62
-rw-r--r--assets/php/vendor/symfony/routing/Loader/Configurator/Traits/AddTrait.php55
-rw-r--r--assets/php/vendor/symfony/routing/Loader/Configurator/Traits/RouteTrait.php131
-rw-r--r--assets/php/vendor/symfony/routing/Loader/DependencyInjection/ServiceRouterLoader.php40
-rw-r--r--assets/php/vendor/symfony/routing/Loader/DirectoryLoader.php58
-rw-r--r--assets/php/vendor/symfony/routing/Loader/GlobFileLoader.php47
-rw-r--r--assets/php/vendor/symfony/routing/Loader/ObjectRouteLoader.php95
-rw-r--r--assets/php/vendor/symfony/routing/Loader/PhpFileLoader.php75
-rw-r--r--assets/php/vendor/symfony/routing/Loader/XmlFileLoader.php359
-rw-r--r--assets/php/vendor/symfony/routing/Loader/YamlFileLoader.php233
-rw-r--r--assets/php/vendor/symfony/routing/Loader/schema/routing/routing-1.0.xsd148
-rw-r--r--assets/php/vendor/symfony/routing/Matcher/Dumper/DumperCollection.php159
-rw-r--r--assets/php/vendor/symfony/routing/Matcher/Dumper/DumperRoute.php57
-rw-r--r--assets/php/vendor/symfony/routing/Matcher/Dumper/MatcherDumper.php37
-rw-r--r--assets/php/vendor/symfony/routing/Matcher/Dumper/MatcherDumperInterface.php39
-rw-r--r--assets/php/vendor/symfony/routing/Matcher/Dumper/PhpMatcherDumper.php429
-rw-r--r--assets/php/vendor/symfony/routing/Matcher/Dumper/StaticPrefixCollection.php238
-rw-r--r--assets/php/vendor/symfony/routing/Matcher/RedirectableUrlMatcher.php65
-rw-r--r--assets/php/vendor/symfony/routing/Matcher/RedirectableUrlMatcherInterface.php31
-rw-r--r--assets/php/vendor/symfony/routing/Matcher/RequestMatcherInterface.php39
-rw-r--r--assets/php/vendor/symfony/routing/Matcher/TraceableUrlMatcher.php141
-rw-r--r--assets/php/vendor/symfony/routing/Matcher/UrlMatcher.php252
-rw-r--r--assets/php/vendor/symfony/routing/Matcher/UrlMatcherInterface.php41
-rw-r--r--assets/php/vendor/symfony/routing/README.md13
-rw-r--r--assets/php/vendor/symfony/routing/RequestContext.php336
-rw-r--r--assets/php/vendor/symfony/routing/RequestContextAwareInterface.php27
-rw-r--r--assets/php/vendor/symfony/routing/Route.php558
-rw-r--r--assets/php/vendor/symfony/routing/RouteCollection.php280
-rw-r--r--assets/php/vendor/symfony/routing/RouteCollectionBuilder.php380
-rw-r--r--assets/php/vendor/symfony/routing/RouteCompiler.php316
-rw-r--r--assets/php/vendor/symfony/routing/RouteCompilerInterface.php30
-rw-r--r--assets/php/vendor/symfony/routing/Router.php388
-rw-r--r--assets/php/vendor/symfony/routing/RouterInterface.php32
-rw-r--r--assets/php/vendor/symfony/routing/Tests/Annotation/RouteTest.php50
-rw-r--r--assets/php/vendor/symfony/routing/Tests/CompiledRouteTest.php27
-rw-r--r--assets/php/vendor/symfony/routing/Tests/DependencyInjection/RoutingResolverPassTest.php36
-rw-r--r--assets/php/vendor/symfony/routing/Tests/Fixtures/AnnotatedClasses/AbstractClass.php16
-rw-r--r--assets/php/vendor/symfony/routing/Tests/Fixtures/AnnotatedClasses/BarClass.php19
-rw-r--r--assets/php/vendor/symfony/routing/Tests/Fixtures/AnnotatedClasses/BazClass.php19
-rw-r--r--assets/php/vendor/symfony/routing/Tests/Fixtures/AnnotatedClasses/FooClass.php16
-rw-r--r--assets/php/vendor/symfony/routing/Tests/Fixtures/AnnotatedClasses/FooTrait.php13
-rw-r--r--assets/php/vendor/symfony/routing/Tests/Fixtures/CustomCompiledRoute.php18
-rw-r--r--assets/php/vendor/symfony/routing/Tests/Fixtures/CustomRouteCompiler.php26
-rw-r--r--assets/php/vendor/symfony/routing/Tests/Fixtures/CustomXmlFileLoader.php26
-rw-r--r--assets/php/vendor/symfony/routing/Tests/Fixtures/OtherAnnotatedClasses/AnonymousClassInTrait.php24
-rw-r--r--assets/php/vendor/symfony/routing/Tests/Fixtures/OtherAnnotatedClasses/NoStartTagClass.php3
-rw-r--r--assets/php/vendor/symfony/routing/Tests/Fixtures/OtherAnnotatedClasses/VariadicClass.php19
-rw-r--r--assets/php/vendor/symfony/routing/Tests/Fixtures/RedirectableUrlMatcher.php30
-rw-r--r--assets/php/vendor/symfony/routing/Tests/Fixtures/annotated.php0
-rw-r--r--assets/php/vendor/symfony/routing/Tests/Fixtures/bad_format.yml3
-rw-r--r--assets/php/vendor/symfony/routing/Tests/Fixtures/bar.xml0
-rw-r--r--assets/php/vendor/symfony/routing/Tests/Fixtures/controller/import__controller.xml10
-rw-r--r--assets/php/vendor/symfony/routing/Tests/Fixtures/controller/import__controller.yml4
-rw-r--r--assets/php/vendor/symfony/routing/Tests/Fixtures/controller/import_controller.xml8
-rw-r--r--assets/php/vendor/symfony/routing/Tests/Fixtures/controller/import_controller.yml3
-rw-r--r--assets/php/vendor/symfony/routing/Tests/Fixtures/controller/import_override_defaults.xml10
-rw-r--r--assets/php/vendor/symfony/routing/Tests/Fixtures/controller/import_override_defaults.yml5
-rw-r--r--assets/php/vendor/symfony/routing/Tests/Fixtures/controller/override_defaults.xml10
-rw-r--r--assets/php/vendor/symfony/routing/Tests/Fixtures/controller/override_defaults.yml5
-rw-r--r--assets/php/vendor/symfony/routing/Tests/Fixtures/controller/routing.xml14
-rw-r--r--assets/php/vendor/symfony/routing/Tests/Fixtures/controller/routing.yml11
-rw-r--r--assets/php/vendor/symfony/routing/Tests/Fixtures/directory/recurse/routes1.yml2
-rw-r--r--assets/php/vendor/symfony/routing/Tests/Fixtures/directory/recurse/routes2.yml2
-rw-r--r--assets/php/vendor/symfony/routing/Tests/Fixtures/directory/routes3.yml2
-rw-r--r--assets/php/vendor/symfony/routing/Tests/Fixtures/directory_import/import.yml3
-rw-r--r--assets/php/vendor/symfony/routing/Tests/Fixtures/dumper/url_matcher0.php37
-rw-r--r--assets/php/vendor/symfony/routing/Tests/Fixtures/dumper/url_matcher1.php318
-rw-r--r--assets/php/vendor/symfony/routing/Tests/Fixtures/dumper/url_matcher2.php380
-rw-r--r--assets/php/vendor/symfony/routing/Tests/Fixtures/dumper/url_matcher3.php55
-rw-r--r--assets/php/vendor/symfony/routing/Tests/Fixtures/dumper/url_matcher4.php112
-rw-r--r--assets/php/vendor/symfony/routing/Tests/Fixtures/dumper/url_matcher5.php209
-rw-r--r--assets/php/vendor/symfony/routing/Tests/Fixtures/dumper/url_matcher6.php213
-rw-r--r--assets/php/vendor/symfony/routing/Tests/Fixtures/dumper/url_matcher7.php249
-rw-r--r--assets/php/vendor/symfony/routing/Tests/Fixtures/empty.yml0
-rw-r--r--assets/php/vendor/symfony/routing/Tests/Fixtures/file_resource.yml0
-rw-r--r--assets/php/vendor/symfony/routing/Tests/Fixtures/foo.xml0
-rw-r--r--assets/php/vendor/symfony/routing/Tests/Fixtures/foo1.xml0
-rw-r--r--assets/php/vendor/symfony/routing/Tests/Fixtures/glob/bar.xml8
-rw-r--r--assets/php/vendor/symfony/routing/Tests/Fixtures/glob/bar.yml4
-rw-r--r--assets/php/vendor/symfony/routing/Tests/Fixtures/glob/baz.xml8
-rw-r--r--assets/php/vendor/symfony/routing/Tests/Fixtures/glob/baz.yml4
-rw-r--r--assets/php/vendor/symfony/routing/Tests/Fixtures/glob/import_multiple.xml8
-rw-r--r--assets/php/vendor/symfony/routing/Tests/Fixtures/glob/import_multiple.yml2
-rw-r--r--assets/php/vendor/symfony/routing/Tests/Fixtures/glob/import_single.xml8
-rw-r--r--assets/php/vendor/symfony/routing/Tests/Fixtures/glob/import_single.yml2
-rw-r--r--assets/php/vendor/symfony/routing/Tests/Fixtures/glob/php_dsl.php7
-rw-r--r--assets/php/vendor/symfony/routing/Tests/Fixtures/glob/php_dsl_bar.php12
-rw-r--r--assets/php/vendor/symfony/routing/Tests/Fixtures/glob/php_dsl_baz.php12
-rw-r--r--assets/php/vendor/symfony/routing/Tests/Fixtures/incomplete.yml2
-rw-r--r--assets/php/vendor/symfony/routing/Tests/Fixtures/list_defaults.xml20
-rw-r--r--assets/php/vendor/symfony/routing/Tests/Fixtures/list_in_list_defaults.xml22
-rw-r--r--assets/php/vendor/symfony/routing/Tests/Fixtures/list_in_map_defaults.xml22
-rw-r--r--assets/php/vendor/symfony/routing/Tests/Fixtures/list_null_values.xml22
-rw-r--r--assets/php/vendor/symfony/routing/Tests/Fixtures/map_defaults.xml20
-rw-r--r--assets/php/vendor/symfony/routing/Tests/Fixtures/map_in_list_defaults.xml22
-rw-r--r--assets/php/vendor/symfony/routing/Tests/Fixtures/map_in_map_defaults.xml22
-rw-r--r--assets/php/vendor/symfony/routing/Tests/Fixtures/map_null_values.xml22
-rw-r--r--assets/php/vendor/symfony/routing/Tests/Fixtures/missing_id.xml8
-rw-r--r--assets/php/vendor/symfony/routing/Tests/Fixtures/missing_path.xml8
-rw-r--r--assets/php/vendor/symfony/routing/Tests/Fixtures/namespaceprefix.xml16
-rw-r--r--assets/php/vendor/symfony/routing/Tests/Fixtures/nonesense_resource_plus_path.yml3
-rw-r--r--assets/php/vendor/symfony/routing/Tests/Fixtures/nonesense_type_without_resource.yml3
-rw-r--r--assets/php/vendor/symfony/routing/Tests/Fixtures/nonvalid.xml10
-rw-r--r--assets/php/vendor/symfony/routing/Tests/Fixtures/nonvalid.yml1
-rw-r--r--assets/php/vendor/symfony/routing/Tests/Fixtures/nonvalid2.yml1
-rw-r--r--assets/php/vendor/symfony/routing/Tests/Fixtures/nonvalidkeys.yml3
-rw-r--r--assets/php/vendor/symfony/routing/Tests/Fixtures/nonvalidnode.xml8
-rw-r--r--assets/php/vendor/symfony/routing/Tests/Fixtures/nonvalidroute.xml12
-rw-r--r--assets/php/vendor/symfony/routing/Tests/Fixtures/null_values.xml12
-rw-r--r--assets/php/vendor/symfony/routing/Tests/Fixtures/php_dsl.php22
-rw-r--r--assets/php/vendor/symfony/routing/Tests/Fixtures/php_dsl_sub.php14
-rw-r--r--assets/php/vendor/symfony/routing/Tests/Fixtures/scalar_defaults.xml33
-rw-r--r--assets/php/vendor/symfony/routing/Tests/Fixtures/special_route_name.yml2
-rw-r--r--assets/php/vendor/symfony/routing/Tests/Fixtures/validpattern.php18
-rw-r--r--assets/php/vendor/symfony/routing/Tests/Fixtures/validpattern.xml15
-rw-r--r--assets/php/vendor/symfony/routing/Tests/Fixtures/validpattern.yml13
-rw-r--r--assets/php/vendor/symfony/routing/Tests/Fixtures/validresource.php18
-rw-r--r--assets/php/vendor/symfony/routing/Tests/Fixtures/validresource.xml13
-rw-r--r--assets/php/vendor/symfony/routing/Tests/Fixtures/validresource.yml8
-rw-r--r--assets/php/vendor/symfony/routing/Tests/Fixtures/with_define_path_variable.php5
-rw-r--r--assets/php/vendor/symfony/routing/Tests/Fixtures/withdoctype.xml3
-rw-r--r--assets/php/vendor/symfony/routing/Tests/Generator/Dumper/PhpGeneratorDumperTest.php181
-rw-r--r--assets/php/vendor/symfony/routing/Tests/Generator/UrlGeneratorTest.php724
-rw-r--r--assets/php/vendor/symfony/routing/Tests/Loader/AbstractAnnotationLoaderTest.php33
-rw-r--r--assets/php/vendor/symfony/routing/Tests/Loader/AnnotationClassLoaderTest.php255
-rw-r--r--assets/php/vendor/symfony/routing/Tests/Loader/AnnotationDirectoryLoaderTest.php98
-rw-r--r--assets/php/vendor/symfony/routing/Tests/Loader/AnnotationFileLoaderTest.php91
-rw-r--r--assets/php/vendor/symfony/routing/Tests/Loader/ClosureLoaderTest.php49
-rw-r--r--assets/php/vendor/symfony/routing/Tests/Loader/DirectoryLoaderTest.php74
-rw-r--r--assets/php/vendor/symfony/routing/Tests/Loader/GlobFileLoaderTest.php45
-rw-r--r--assets/php/vendor/symfony/routing/Tests/Loader/ObjectRouteLoaderTest.php123
-rw-r--r--assets/php/vendor/symfony/routing/Tests/Loader/PhpFileLoaderTest.php133
-rw-r--r--assets/php/vendor/symfony/routing/Tests/Loader/XmlFileLoaderTest.php385
-rw-r--r--assets/php/vendor/symfony/routing/Tests/Loader/YamlFileLoaderTest.php206
-rw-r--r--assets/php/vendor/symfony/routing/Tests/Matcher/DumpedRedirectableUrlMatcherTest.php43
-rw-r--r--assets/php/vendor/symfony/routing/Tests/Matcher/DumpedUrlMatcherTest.php48
-rw-r--r--assets/php/vendor/symfony/routing/Tests/Matcher/Dumper/DumperCollectionTest.php34
-rw-r--r--assets/php/vendor/symfony/routing/Tests/Matcher/Dumper/PhpMatcherDumperTest.php459
-rw-r--r--assets/php/vendor/symfony/routing/Tests/Matcher/Dumper/StaticPrefixCollectionTest.php175
-rw-r--r--assets/php/vendor/symfony/routing/Tests/Matcher/RedirectableUrlMatcherTest.php124
-rw-r--r--assets/php/vendor/symfony/routing/Tests/Matcher/TraceableUrlMatcherTest.php122
-rw-r--r--assets/php/vendor/symfony/routing/Tests/Matcher/UrlMatcherTest.php509
-rw-r--r--assets/php/vendor/symfony/routing/Tests/RequestContextTest.php160
-rw-r--r--assets/php/vendor/symfony/routing/Tests/RouteCollectionBuilderTest.php364
-rw-r--r--assets/php/vendor/symfony/routing/Tests/RouteCollectionTest.php305
-rw-r--r--assets/php/vendor/symfony/routing/Tests/RouteCompilerTest.php389
-rw-r--r--assets/php/vendor/symfony/routing/Tests/RouteTest.php258
-rw-r--r--assets/php/vendor/symfony/routing/Tests/RouterTest.php163
-rw-r--r--assets/php/vendor/symfony/routing/composer.json56
-rw-r--r--assets/php/vendor/symfony/routing/phpunit.xml.dist30
176 files changed, 15484 insertions, 0 deletions
diff --git a/assets/php/vendor/symfony/routing/.gitignore b/assets/php/vendor/symfony/routing/.gitignore
new file mode 100644
index 0000000..c49a5d8
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/.gitignore
@@ -0,0 +1,3 @@
+vendor/
+composer.lock
+phpunit.xml
diff --git a/assets/php/vendor/symfony/routing/Annotation/Route.php b/assets/php/vendor/symfony/routing/Annotation/Route.php
new file mode 100644
index 0000000..5b3cbea
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Annotation/Route.php
@@ -0,0 +1,144 @@
+<?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
+ * @Target({"CLASS", "METHOD"})
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+class Route
+{
+ private $path;
+ private $name;
+ private $requirements = array();
+ private $options = array();
+ private $defaults = array();
+ private $host;
+ private $methods = array();
+ private $schemes = array();
+ private $condition;
+
+ /**
+ * @param array $data An array of key/value parameters
+ *
+ * @throws \BadMethodCallException
+ */
+ public function __construct(array $data)
+ {
+ if (isset($data['value'])) {
+ $data['path'] = $data['value'];
+ unset($data['value']);
+ }
+
+ foreach ($data as $key => $value) {
+ $method = 'set'.str_replace('_', '', $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 setPath($path)
+ {
+ $this->path = $path;
+ }
+
+ public function getPath()
+ {
+ return $this->path;
+ }
+
+ public function setHost($pattern)
+ {
+ $this->host = $pattern;
+ }
+
+ public function getHost()
+ {
+ return $this->host;
+ }
+
+ 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;
+ }
+
+ public function setSchemes($schemes)
+ {
+ $this->schemes = is_array($schemes) ? $schemes : array($schemes);
+ }
+
+ public function getSchemes()
+ {
+ return $this->schemes;
+ }
+
+ public function setMethods($methods)
+ {
+ $this->methods = is_array($methods) ? $methods : array($methods);
+ }
+
+ public function getMethods()
+ {
+ return $this->methods;
+ }
+
+ public function setCondition($condition)
+ {
+ $this->condition = $condition;
+ }
+
+ public function getCondition()
+ {
+ return $this->condition;
+ }
+}
diff --git a/assets/php/vendor/symfony/routing/CHANGELOG.md b/assets/php/vendor/symfony/routing/CHANGELOG.md
new file mode 100644
index 0000000..e278f8b
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/CHANGELOG.md
@@ -0,0 +1,228 @@
+CHANGELOG
+=========
+
+3.4.0
+-----
+
+ * Added `NoConfigurationException`.
+ * Added the possibility to define a prefix for all routes of a controller via @Route(name="prefix_")
+ * Added support for prioritized routing loaders.
+ * Add matched and default parameters to redirect responses
+ * Added support for a `controller` keyword for configuring route controllers in YAML and XML configurations.
+
+3.3.0
+-----
+
+ * [DEPRECATION] Class parameters have been deprecated and will be removed in 4.0.
+ * router.options.generator_class
+ * router.options.generator_base_class
+ * router.options.generator_dumper_class
+ * router.options.matcher_class
+ * router.options.matcher_base_class
+ * router.options.matcher_dumper_class
+ * router.options.matcher.cache_class
+ * router.options.generator.cache_class
+
+3.2.0
+-----
+
+ * Added support for `bool`, `int`, `float`, `string`, `list` and `map` defaults in XML configurations.
+ * Added support for UTF-8 requirements
+
+2.8.0
+-----
+
+ * allowed specifying a directory to recursively load all routing configuration files it contains
+ * Added ObjectRouteLoader and ServiceRouteLoader that allow routes to be loaded
+ by calling a method on an object/service.
+ * [DEPRECATION] Deprecated the hardcoded value for the `$referenceType` argument of the `UrlGeneratorInterface::generate` method.
+ Use the constants defined in the `UrlGeneratorInterface` instead.
+
+ Before:
+
+ ```php
+ $router->generate('blog_show', array('slug' => 'my-blog-post'), true);
+ ```
+
+ After:
+
+ ```php
+ use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
+
+ $router->generate('blog_show', array('slug' => 'my-blog-post'), UrlGeneratorInterface::ABSOLUTE_URL);
+ ```
+
+2.5.0
+-----
+
+ * [DEPRECATION] The `ApacheMatcherDumper` and `ApacheUrlMatcher` were deprecated and
+ will be removed in Symfony 3.0, since the performance gains were minimal and
+ it's hard to replicate the behaviour of PHP implementation.
+
+2.3.0
+-----
+
+ * added RequestContext::getQueryString()
+
+2.2.0
+-----
+
+ * [DEPRECATION] Several route settings have been renamed (the old ones will be removed in 3.0):
+
+ * The `pattern` setting for a route has been deprecated in favor of `path`
+ * The `_scheme` and `_method` requirements have been moved to the `schemes` and `methods` settings
+
+ Before:
+
+ ```yaml
+ article_edit:
+ pattern: /article/{id}
+ requirements: { '_method': 'POST|PUT', '_scheme': 'https', 'id': '\d+' }
+ ```
+
+ ```xml
+ <route id="article_edit" pattern="/article/{id}">
+ <requirement key="_method">POST|PUT</requirement>
+ <requirement key="_scheme">https</requirement>
+ <requirement key="id">\d+</requirement>
+ </route>
+ ```
+
+ ```php
+ $route = new Route();
+ $route->setPattern('/article/{id}');
+ $route->setRequirement('_method', 'POST|PUT');
+ $route->setRequirement('_scheme', 'https');
+ ```
+
+ After:
+
+ ```yaml
+ article_edit:
+ path: /article/{id}
+ methods: [POST, PUT]
+ schemes: https
+ requirements: { 'id': '\d+' }
+ ```
+
+ ```xml
+ <route id="article_edit" pattern="/article/{id}" methods="POST PUT" schemes="https">
+ <requirement key="id">\d+</requirement>
+ </route>
+ ```
+
+ ```php
+ $route = new Route();
+ $route->setPath('/article/{id}');
+ $route->setMethods(array('POST', 'PUT'));
+ $route->setSchemes('https');
+ ```
+
+ * [BC BREAK] RouteCollection does not behave like a tree structure anymore but as
+ a flat array of Routes. So when using PHP to build the RouteCollection, you must
+ make sure to add routes to the sub-collection before adding it to the parent
+ collection (this is not relevant when using YAML or XML for Route definitions).
+
+ Before:
+
+ ```php
+ $rootCollection = new RouteCollection();
+ $subCollection = new RouteCollection();
+ $rootCollection->addCollection($subCollection);
+ $subCollection->add('foo', new Route('/foo'));
+ ```
+
+ After:
+
+ ```php
+ $rootCollection = new RouteCollection();
+ $subCollection = new RouteCollection();
+ $subCollection->add('foo', new Route('/foo'));
+ $rootCollection->addCollection($subCollection);
+ ```
+
+ Also one must call `addCollection` from the bottom to the top hierarchy.
+ So the correct sequence is the following (and not the reverse):
+
+ ```php
+ $childCollection->addCollection($grandchildCollection);
+ $rootCollection->addCollection($childCollection);
+ ```
+
+ * [DEPRECATION] The methods `RouteCollection::getParent()` and `RouteCollection::getRoot()`
+ have been deprecated and will be removed in Symfony 2.3.
+ * [BC BREAK] Misusing the `RouteCollection::addPrefix` method to add defaults, requirements
+ or options without adding a prefix is not supported anymore. So if you called `addPrefix`
+ with an empty prefix or `/` only (both have no relevance), like
+ `addPrefix('', $defaultsArray, $requirementsArray, $optionsArray)`
+ you need to use the new dedicated methods `addDefaults($defaultsArray)`,
+ `addRequirements($requirementsArray)` or `addOptions($optionsArray)` instead.
+ * [DEPRECATION] The `$options` parameter to `RouteCollection::addPrefix()` has been deprecated
+ because adding options has nothing to do with adding a path prefix. If you want to add options
+ to all child routes of a RouteCollection, you can use `addOptions()`.
+ * [DEPRECATION] The method `RouteCollection::getPrefix()` has been deprecated
+ because it suggested that all routes in the collection would have this prefix, which is
+ not necessarily true. On top of that, since there is no tree structure anymore, this method
+ is also useless. Don't worry about performance, prefix optimization for matching is still done
+ in the dumper, which was also improved in 2.2.0 to find even more grouping possibilities.
+ * [DEPRECATION] `RouteCollection::addCollection(RouteCollection $collection)` should now only be
+ used with a single parameter. The other params `$prefix`, `$default`, `$requirements` and `$options`
+ will still work, but have been deprecated. The `addPrefix` method should be used for this
+ use-case instead.
+ Before: `$parentCollection->addCollection($collection, '/prefix', array(...), array(...))`
+ After:
+ ```php
+ $collection->addPrefix('/prefix', array(...), array(...));
+ $parentCollection->addCollection($collection);
+ ```
+ * added support for the method default argument values when defining a @Route
+ * Adjacent placeholders without separator work now, e.g. `/{x}{y}{z}.{_format}`.
+ * Characters that function as separator between placeholders are now whitelisted
+ to fix routes with normal text around a variable, e.g. `/prefix{var}suffix`.
+ * [BC BREAK] The default requirement of a variable has been changed slightly.
+ Previously it disallowed the previous and the next char around a variable. Now
+ it disallows the slash (`/`) and the next char. Using the previous char added
+ no value and was problematic because the route `/index.{_format}` would be
+ matched by `/index.ht/ml`.
+ * The default requirement now uses possessive quantifiers when possible which
+ improves matching performance by up to 20% because it prevents backtracking
+ when it's not needed.
+ * The ConfigurableRequirementsInterface can now also be used to disable the requirements
+ check on URL generation completely by calling `setStrictRequirements(null)`. It
+ improves performance in production environment as you should know that params always
+ pass the requirements (otherwise it would break your link anyway).
+ * There is no restriction on the route name anymore. So non-alphanumeric characters
+ are now also allowed.
+ * [BC BREAK] `RouteCompilerInterface::compile(Route $route)` was made static
+ (only relevant if you implemented your own RouteCompiler).
+ * Added possibility to generate relative paths and network paths in the UrlGenerator, e.g.
+ "../parent-file" and "//example.com/dir/file". The third parameter in
+ `UrlGeneratorInterface::generate($name, $parameters = array(), $referenceType = self::ABSOLUTE_PATH)`
+ now accepts more values and you should use the constants defined in `UrlGeneratorInterface` for
+ claritiy. The old method calls with a Boolean parameter will continue to work because they
+ equal the signature using the constants.
+
+2.1.0
+-----
+
+ * added RequestMatcherInterface
+ * added RequestContext::fromRequest()
+ * the UrlMatcher does not throw a \LogicException anymore when the required
+ scheme is not the current one
+ * added TraceableUrlMatcher
+ * added the possibility to define options, default values and requirements
+ for placeholders in prefix, including imported routes
+ * added RouterInterface::getRouteCollection
+ * [BC BREAK] the UrlMatcher urldecodes the route parameters only once, they
+ were decoded twice before. Note that the `urldecode()` calls have been
+ changed for a single `rawurldecode()` in order to support `+` for input
+ paths.
+ * added RouteCollection::getRoot method to retrieve the root of a
+ RouteCollection tree
+ * [BC BREAK] made RouteCollection::setParent private which could not have
+ been used anyway without creating inconsistencies
+ * [BC BREAK] RouteCollection::remove also removes a route from parent
+ collections (not only from its children)
+ * added ConfigurableRequirementsInterface that allows to disable exceptions
+ (and generate empty URLs instead) when generating a route with an invalid
+ parameter value
diff --git a/assets/php/vendor/symfony/routing/CompiledRoute.php b/assets/php/vendor/symfony/routing/CompiledRoute.php
new file mode 100644
index 0000000..8ecf515
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/CompiledRoute.php
@@ -0,0 +1,169 @@
+<?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 implements \Serializable
+{
+ private $variables;
+ private $tokens;
+ private $staticPrefix;
+ private $regex;
+ private $pathVariables;
+ private $hostVariables;
+ private $hostRegex;
+ private $hostTokens;
+
+ /**
+ * @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 $pathVariables An array of path variables
+ * @param string|null $hostRegex Host regex
+ * @param array $hostTokens Host tokens
+ * @param array $hostVariables An array of host variables
+ * @param array $variables An array of variables (variables defined in the path and in the host patterns)
+ */
+ public function __construct($staticPrefix, $regex, array $tokens, array $pathVariables, $hostRegex = null, array $hostTokens = array(), array $hostVariables = array(), array $variables = array())
+ {
+ $this->staticPrefix = (string) $staticPrefix;
+ $this->regex = $regex;
+ $this->tokens = $tokens;
+ $this->pathVariables = $pathVariables;
+ $this->hostRegex = $hostRegex;
+ $this->hostTokens = $hostTokens;
+ $this->hostVariables = $hostVariables;
+ $this->variables = $variables;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function serialize()
+ {
+ return serialize(array(
+ 'vars' => $this->variables,
+ 'path_prefix' => $this->staticPrefix,
+ 'path_regex' => $this->regex,
+ 'path_tokens' => $this->tokens,
+ 'path_vars' => $this->pathVariables,
+ 'host_regex' => $this->hostRegex,
+ 'host_tokens' => $this->hostTokens,
+ 'host_vars' => $this->hostVariables,
+ ));
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function unserialize($serialized)
+ {
+ if (\PHP_VERSION_ID >= 70000) {
+ $data = unserialize($serialized, array('allowed_classes' => false));
+ } else {
+ $data = unserialize($serialized);
+ }
+
+ $this->variables = $data['vars'];
+ $this->staticPrefix = $data['path_prefix'];
+ $this->regex = $data['path_regex'];
+ $this->tokens = $data['path_tokens'];
+ $this->pathVariables = $data['path_vars'];
+ $this->hostRegex = $data['host_regex'];
+ $this->hostTokens = $data['host_tokens'];
+ $this->hostVariables = $data['host_vars'];
+ }
+
+ /**
+ * 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 host regex.
+ *
+ * @return string|null The host regex or null
+ */
+ public function getHostRegex()
+ {
+ return $this->hostRegex;
+ }
+
+ /**
+ * Returns the tokens.
+ *
+ * @return array The tokens
+ */
+ public function getTokens()
+ {
+ return $this->tokens;
+ }
+
+ /**
+ * Returns the host tokens.
+ *
+ * @return array The tokens
+ */
+ public function getHostTokens()
+ {
+ return $this->hostTokens;
+ }
+
+ /**
+ * Returns the variables.
+ *
+ * @return array The variables
+ */
+ public function getVariables()
+ {
+ return $this->variables;
+ }
+
+ /**
+ * Returns the path variables.
+ *
+ * @return array The variables
+ */
+ public function getPathVariables()
+ {
+ return $this->pathVariables;
+ }
+
+ /**
+ * Returns the host variables.
+ *
+ * @return array The variables
+ */
+ public function getHostVariables()
+ {
+ return $this->hostVariables;
+ }
+}
diff --git a/assets/php/vendor/symfony/routing/DependencyInjection/RoutingResolverPass.php b/assets/php/vendor/symfony/routing/DependencyInjection/RoutingResolverPass.php
new file mode 100644
index 0000000..4af0a5a
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/DependencyInjection/RoutingResolverPass.php
@@ -0,0 +1,49 @@
+<?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\DependencyInjection;
+
+use Symfony\Component\DependencyInjection\Reference;
+use Symfony\Component\DependencyInjection\ContainerBuilder;
+use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
+use Symfony\Component\DependencyInjection\Compiler\PriorityTaggedServiceTrait;
+
+/**
+ * Adds tagged routing.loader services to routing.resolver service.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+class RoutingResolverPass implements CompilerPassInterface
+{
+ use PriorityTaggedServiceTrait;
+
+ private $resolverServiceId;
+ private $loaderTag;
+
+ public function __construct($resolverServiceId = 'routing.resolver', $loaderTag = 'routing.loader')
+ {
+ $this->resolverServiceId = $resolverServiceId;
+ $this->loaderTag = $loaderTag;
+ }
+
+ public function process(ContainerBuilder $container)
+ {
+ if (false === $container->hasDefinition($this->resolverServiceId)) {
+ return;
+ }
+
+ $definition = $container->getDefinition($this->resolverServiceId);
+
+ foreach ($this->findAndSortTaggedServices($this->loaderTag, $container) as $id) {
+ $definition->addMethodCall('addLoader', array(new Reference($id)));
+ }
+ }
+}
diff --git a/assets/php/vendor/symfony/routing/Exception/ExceptionInterface.php b/assets/php/vendor/symfony/routing/Exception/ExceptionInterface.php
new file mode 100644
index 0000000..db76362
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Exception/ExceptionInterface.php
@@ -0,0 +1,21 @@
+<?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>
+ */
+interface ExceptionInterface
+{
+}
diff --git a/assets/php/vendor/symfony/routing/Exception/InvalidParameterException.php b/assets/php/vendor/symfony/routing/Exception/InvalidParameterException.php
new file mode 100644
index 0000000..94d841f
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Exception/InvalidParameterException.php
@@ -0,0 +1,21 @@
+<?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>
+ */
+class InvalidParameterException extends \InvalidArgumentException implements ExceptionInterface
+{
+}
diff --git a/assets/php/vendor/symfony/routing/Exception/MethodNotAllowedException.php b/assets/php/vendor/symfony/routing/Exception/MethodNotAllowedException.php
new file mode 100644
index 0000000..712412f
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Exception/MethodNotAllowedException.php
@@ -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\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>
+ */
+class MethodNotAllowedException extends \RuntimeException implements ExceptionInterface
+{
+ protected $allowedMethods = array();
+
+ public function __construct(array $allowedMethods, $message = null, $code = 0, \Exception $previous = null)
+ {
+ $this->allowedMethods = array_map('strtoupper', $allowedMethods);
+
+ parent::__construct($message, $code, $previous);
+ }
+
+ /**
+ * Gets the allowed HTTP methods.
+ *
+ * @return array
+ */
+ public function getAllowedMethods()
+ {
+ return $this->allowedMethods;
+ }
+}
diff --git a/assets/php/vendor/symfony/routing/Exception/MissingMandatoryParametersException.php b/assets/php/vendor/symfony/routing/Exception/MissingMandatoryParametersException.php
new file mode 100644
index 0000000..57f3a40
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Exception/MissingMandatoryParametersException.php
@@ -0,0 +1,22 @@
+<?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>
+ */
+class MissingMandatoryParametersException extends \InvalidArgumentException implements ExceptionInterface
+{
+}
diff --git a/assets/php/vendor/symfony/routing/Exception/NoConfigurationException.php b/assets/php/vendor/symfony/routing/Exception/NoConfigurationException.php
new file mode 100644
index 0000000..333bc74
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Exception/NoConfigurationException.php
@@ -0,0 +1,21 @@
+<?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 no routes are configured.
+ *
+ * @author Yonel Ceruto <yonelceruto@gmail.com>
+ */
+class NoConfigurationException extends ResourceNotFoundException
+{
+}
diff --git a/assets/php/vendor/symfony/routing/Exception/ResourceNotFoundException.php b/assets/php/vendor/symfony/routing/Exception/ResourceNotFoundException.php
new file mode 100644
index 0000000..ccbca15
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Exception/ResourceNotFoundException.php
@@ -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;
+
+/**
+ * The resource was not found.
+ *
+ * This exception should trigger an HTTP 404 response in your application code.
+ *
+ * @author Kris Wallsmith <kris@symfony.com>
+ */
+class ResourceNotFoundException extends \RuntimeException implements ExceptionInterface
+{
+}
diff --git a/assets/php/vendor/symfony/routing/Exception/RouteNotFoundException.php b/assets/php/vendor/symfony/routing/Exception/RouteNotFoundException.php
new file mode 100644
index 0000000..24ab0b4
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Exception/RouteNotFoundException.php
@@ -0,0 +1,21 @@
+<?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 exist.
+ *
+ * @author Alexandre Salomé <alexandre.salome@gmail.com>
+ */
+class RouteNotFoundException extends \InvalidArgumentException implements ExceptionInterface
+{
+}
diff --git a/assets/php/vendor/symfony/routing/Generator/ConfigurableRequirementsInterface.php b/assets/php/vendor/symfony/routing/Generator/ConfigurableRequirementsInterface.php
new file mode 100644
index 0000000..dc97b7e
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Generator/ConfigurableRequirementsInterface.php
@@ -0,0 +1,55 @@
+<?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;
+
+/**
+ * ConfigurableRequirementsInterface must be implemented by URL generators that
+ * can be configured whether an exception should be generated when the parameters
+ * do not match the requirements. It is also possible to disable the requirements
+ * check for URL generation completely.
+ *
+ * The possible configurations and use-cases:
+ * - setStrictRequirements(true): Throw an exception for mismatching requirements. This
+ * is mostly useful in development environment.
+ * - setStrictRequirements(false): Don't throw an exception but return null as URL for
+ * mismatching requirements and log the problem. Useful when you cannot control all
+ * params because they come from third party libs but don't want to have a 404 in
+ * production environment. It should log the mismatch so one can review it.
+ * - setStrictRequirements(null): Return the URL with the given parameters without
+ * checking the requirements at all. When generating a URL you should either trust
+ * your params or you validated them beforehand because otherwise it would break your
+ * link anyway. So in production environment you should know that params always pass
+ * the requirements. Thus this option allows to disable the check on URL generation for
+ * performance reasons (saving a preg_match for each requirement every time a URL is
+ * generated).
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ * @author Tobias Schultze <http://tobion.de>
+ */
+interface ConfigurableRequirementsInterface
+{
+ /**
+ * Enables or disables the exception on incorrect parameters.
+ * Passing null will deactivate the requirements check completely.
+ *
+ * @param bool|null $enabled
+ */
+ public function setStrictRequirements($enabled);
+
+ /**
+ * Returns whether to throw an exception on incorrect parameters.
+ * Null means the requirements check is deactivated completely.
+ *
+ * @return bool|null
+ */
+ public function isStrictRequirements();
+}
diff --git a/assets/php/vendor/symfony/routing/Generator/Dumper/GeneratorDumper.php b/assets/php/vendor/symfony/routing/Generator/Dumper/GeneratorDumper.php
new file mode 100644
index 0000000..659c5ba
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Generator/Dumper/GeneratorDumper.php
@@ -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\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;
+
+ public function __construct(RouteCollection $routes)
+ {
+ $this->routes = $routes;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getRoutes()
+ {
+ return $this->routes;
+ }
+}
diff --git a/assets/php/vendor/symfony/routing/Generator/Dumper/GeneratorDumperInterface.php b/assets/php/vendor/symfony/routing/Generator/Dumper/GeneratorDumperInterface.php
new file mode 100644
index 0000000..fed3472
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Generator/Dumper/GeneratorDumperInterface.php
@@ -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;
+
+/**
+ * GeneratorDumperInterface is the interface that all generator dumper classes must implement.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+interface GeneratorDumperInterface
+{
+ /**
+ * Dumps a set of routes to a string representation of executable code
+ * that can then be used to generate a URL of such a route.
+ *
+ * @param array $options An array of options
+ *
+ * @return string Executable code
+ */
+ public function dump(array $options = array());
+
+ /**
+ * Gets the routes to dump.
+ *
+ * @return RouteCollection A RouteCollection instance
+ */
+ public function getRoutes();
+}
diff --git a/assets/php/vendor/symfony/routing/Generator/Dumper/PhpGeneratorDumper.php b/assets/php/vendor/symfony/routing/Generator/Dumper/PhpGeneratorDumper.php
new file mode 100644
index 0000000..60bdf1d
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Generator/Dumper/PhpGeneratorDumper.php
@@ -0,0 +1,118 @@
+<?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;
+
+/**
+ * PhpGeneratorDumper creates a PHP class able to generate URLs for a given set of routes.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ * @author Tobias Schultze <http://tobion.de>
+ */
+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
+ */
+ public function dump(array $options = array())
+ {
+ $options = array_merge(array(
+ 'class' => 'ProjectUrlGenerator',
+ 'base_class' => 'Symfony\\Component\\Routing\\Generator\\UrlGenerator',
+ ), $options);
+
+ return <<<EOF
+<?php
+
+use Symfony\Component\Routing\RequestContext;
+use Symfony\Component\Routing\Exception\RouteNotFoundException;
+use Psr\Log\LoggerInterface;
+
+/**
+ * This class has been auto-generated
+ * by the Symfony Routing Component.
+ */
+class {$options['class']} extends {$options['base_class']}
+{
+ private static \$declaredRoutes;
+
+ public function __construct(RequestContext \$context, LoggerInterface \$logger = null)
+ {
+ \$this->context = \$context;
+ \$this->logger = \$logger;
+ if (null === self::\$declaredRoutes) {
+ self::\$declaredRoutes = {$this->generateDeclaredRoutes()};
+ }
+ }
+
+{$this->generateGenerateMethod()}
+}
+
+EOF;
+ }
+
+ /**
+ * Generates PHP code representing an array of defined routes
+ * together with the routes properties (e.g. requirements).
+ *
+ * @return string PHP code
+ */
+ private function generateDeclaredRoutes()
+ {
+ $routes = "array(\n";
+ foreach ($this->getRoutes()->all() as $name => $route) {
+ $compiledRoute = $route->compile();
+
+ $properties = array();
+ $properties[] = $compiledRoute->getVariables();
+ $properties[] = $route->getDefaults();
+ $properties[] = $route->getRequirements();
+ $properties[] = $compiledRoute->getTokens();
+ $properties[] = $compiledRoute->getHostTokens();
+ $properties[] = $route->getSchemes();
+
+ $routes .= sprintf(" '%s' => %s,\n", $name, str_replace("\n", '', var_export($properties, true)));
+ }
+ $routes .= ' )';
+
+ return $routes;
+ }
+
+ /**
+ * Generates PHP code representing the `generate` method that implements the UrlGeneratorInterface.
+ *
+ * @return string PHP code
+ */
+ private function generateGenerateMethod()
+ {
+ return <<<'EOF'
+ public function generate($name, $parameters = array(), $referenceType = self::ABSOLUTE_PATH)
+ {
+ if (!isset(self::$declaredRoutes[$name])) {
+ throw new RouteNotFoundException(sprintf('Unable to generate a URL for the named route "%s" as such route does not exist.', $name));
+ }
+
+ list($variables, $defaults, $requirements, $tokens, $hostTokens, $requiredSchemes) = self::$declaredRoutes[$name];
+
+ return $this->doGenerate($variables, $defaults, $requirements, $tokens, $parameters, $name, $referenceType, $hostTokens, $requiredSchemes);
+ }
+EOF;
+ }
+}
diff --git a/assets/php/vendor/symfony/routing/Generator/UrlGenerator.php b/assets/php/vendor/symfony/routing/Generator/UrlGenerator.php
new file mode 100644
index 0000000..02a59a9
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Generator/UrlGenerator.php
@@ -0,0 +1,321 @@
+<?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\RouteCollection;
+use Symfony\Component\Routing\RequestContext;
+use Symfony\Component\Routing\Exception\InvalidParameterException;
+use Symfony\Component\Routing\Exception\RouteNotFoundException;
+use Symfony\Component\Routing\Exception\MissingMandatoryParametersException;
+use Psr\Log\LoggerInterface;
+
+/**
+ * UrlGenerator can generate a URL or a path for any route in the RouteCollection
+ * based on the passed parameters.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ * @author Tobias Schultze <http://tobion.de>
+ */
+class UrlGenerator implements UrlGeneratorInterface, ConfigurableRequirementsInterface
+{
+ protected $routes;
+ protected $context;
+
+ /**
+ * @var bool|null
+ */
+ protected $strictRequirements = true;
+
+ protected $logger;
+
+ /**
+ * This array defines the characters (besides alphanumeric ones) that will not be percent-encoded in the path segment of the generated URL.
+ *
+ * PHP's rawurlencode() encodes all chars except "a-zA-Z0-9-._~" according to RFC 3986. But we want to allow some chars
+ * to be used in their literal form (reasons below). Other chars inside the path must of course be encoded, e.g.
+ * "?" and "#" (would be interpreted wrongly as query and fragment identifier),
+ * "'" and """ (are used as delimiters in HTML).
+ */
+ protected $decodedChars = array(
+ // the slash can be used to designate a hierarchical structure and we want allow using it with this meaning
+ // some webservers don't allow the slash in encoded form in the path for security reasons anyway
+ // see http://stackoverflow.com/questions/4069002/http-400-if-2f-part-of-get-url-in-jboss
+ '%2F' => '/',
+ // the following chars are general delimiters in the URI specification but have only special meaning in the authority component
+ // so they can safely be used in the path in unencoded form
+ '%40' => '@',
+ '%3A' => ':',
+ // these chars are only sub-delimiters that have no predefined meaning and can therefore be used literally
+ // so URI producing applications can use these chars to delimit subcomponents in a path segment without being encoded for better readability
+ '%3B' => ';',
+ '%2C' => ',',
+ '%3D' => '=',
+ '%2B' => '+',
+ '%21' => '!',
+ '%2A' => '*',
+ '%7C' => '|',
+ );
+
+ public function __construct(RouteCollection $routes, RequestContext $context, LoggerInterface $logger = null)
+ {
+ $this->routes = $routes;
+ $this->context = $context;
+ $this->logger = $logger;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setContext(RequestContext $context)
+ {
+ $this->context = $context;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getContext()
+ {
+ return $this->context;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setStrictRequirements($enabled)
+ {
+ $this->strictRequirements = null === $enabled ? null : (bool) $enabled;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function isStrictRequirements()
+ {
+ return $this->strictRequirements;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function generate($name, $parameters = array(), $referenceType = self::ABSOLUTE_PATH)
+ {
+ if (null === $route = $this->routes->get($name)) {
+ throw new RouteNotFoundException(sprintf('Unable to generate a URL for the named route "%s" as such route does not exist.', $name));
+ }
+
+ // the Route has a cache of its own and is not recompiled as long as it does not get modified
+ $compiledRoute = $route->compile();
+
+ return $this->doGenerate($compiledRoute->getVariables(), $route->getDefaults(), $route->getRequirements(), $compiledRoute->getTokens(), $parameters, $name, $referenceType, $compiledRoute->getHostTokens(), $route->getSchemes());
+ }
+
+ /**
+ * @throws MissingMandatoryParametersException When some parameters are missing that are mandatory for the route
+ * @throws InvalidParameterException When a parameter value for a placeholder is not correct because
+ * it does not match the requirement
+ */
+ protected function doGenerate($variables, $defaults, $requirements, $tokens, $parameters, $name, $referenceType, $hostTokens, array $requiredSchemes = array())
+ {
+ $variables = array_flip($variables);
+ $mergedParams = array_replace($defaults, $this->context->getParameters(), $parameters);
+
+ // all params must be given
+ if ($diff = array_diff_key($variables, $mergedParams)) {
+ throw new MissingMandatoryParametersException(sprintf('Some mandatory parameters are missing ("%s") to generate a URL for route "%s".', implode('", "', array_keys($diff)), $name));
+ }
+
+ $url = '';
+ $optional = true;
+ $message = 'Parameter "{parameter}" for route "{route}" must match "{expected}" ("{given}" given) to generate a corresponding URL.';
+ foreach ($tokens as $token) {
+ if ('variable' === $token[0]) {
+ if (!$optional || !array_key_exists($token[3], $defaults) || null !== $mergedParams[$token[3]] && (string) $mergedParams[$token[3]] !== (string) $defaults[$token[3]]) {
+ // check requirement
+ if (null !== $this->strictRequirements && !preg_match('#^'.$token[2].'$#'.(empty($token[4]) ? '' : 'u'), $mergedParams[$token[3]])) {
+ if ($this->strictRequirements) {
+ throw new InvalidParameterException(strtr($message, array('{parameter}' => $token[3], '{route}' => $name, '{expected}' => $token[2], '{given}' => $mergedParams[$token[3]])));
+ }
+
+ if ($this->logger) {
+ $this->logger->error($message, array('parameter' => $token[3], 'route' => $name, 'expected' => $token[2], 'given' => $mergedParams[$token[3]]));
+ }
+
+ return;
+ }
+
+ $url = $token[1].$mergedParams[$token[3]].$url;
+ $optional = false;
+ }
+ } else {
+ // static text
+ $url = $token[1].$url;
+ $optional = false;
+ }
+ }
+
+ if ('' === $url) {
+ $url = '/';
+ }
+
+ // the contexts base URL is already encoded (see Symfony\Component\HttpFoundation\Request)
+ $url = strtr(rawurlencode($url), $this->decodedChars);
+
+ // the path segments "." and ".." are interpreted as relative reference when resolving a URI; see http://tools.ietf.org/html/rfc3986#section-3.3
+ // so we need to encode them as they are not used for this purpose here
+ // otherwise we would generate a URI that, when followed by a user agent (e.g. browser), does not match this route
+ $url = strtr($url, array('/../' => '/%2E%2E/', '/./' => '/%2E/'));
+ if ('/..' === substr($url, -3)) {
+ $url = substr($url, 0, -2).'%2E%2E';
+ } elseif ('/.' === substr($url, -2)) {
+ $url = substr($url, 0, -1).'%2E';
+ }
+
+ $schemeAuthority = '';
+ $host = $this->context->getHost();
+ $scheme = $this->context->getScheme();
+
+ if ($requiredSchemes) {
+ if (!in_array($scheme, $requiredSchemes, true)) {
+ $referenceType = self::ABSOLUTE_URL;
+ $scheme = current($requiredSchemes);
+ }
+ }
+
+ if ($hostTokens) {
+ $routeHost = '';
+ foreach ($hostTokens as $token) {
+ if ('variable' === $token[0]) {
+ if (null !== $this->strictRequirements && !preg_match('#^'.$token[2].'$#i'.(empty($token[4]) ? '' : 'u'), $mergedParams[$token[3]])) {
+ if ($this->strictRequirements) {
+ throw new InvalidParameterException(strtr($message, array('{parameter}' => $token[3], '{route}' => $name, '{expected}' => $token[2], '{given}' => $mergedParams[$token[3]])));
+ }
+
+ if ($this->logger) {
+ $this->logger->error($message, array('parameter' => $token[3], 'route' => $name, 'expected' => $token[2], 'given' => $mergedParams[$token[3]]));
+ }
+
+ return;
+ }
+
+ $routeHost = $token[1].$mergedParams[$token[3]].$routeHost;
+ } else {
+ $routeHost = $token[1].$routeHost;
+ }
+ }
+
+ if ($routeHost !== $host) {
+ $host = $routeHost;
+ if (self::ABSOLUTE_URL !== $referenceType) {
+ $referenceType = self::NETWORK_PATH;
+ }
+ }
+ }
+
+ if ((self::ABSOLUTE_URL === $referenceType || self::NETWORK_PATH === $referenceType) && !empty($host)) {
+ $port = '';
+ if ('http' === $scheme && 80 != $this->context->getHttpPort()) {
+ $port = ':'.$this->context->getHttpPort();
+ } elseif ('https' === $scheme && 443 != $this->context->getHttpsPort()) {
+ $port = ':'.$this->context->getHttpsPort();
+ }
+
+ $schemeAuthority = self::NETWORK_PATH === $referenceType ? '//' : "$scheme://";
+ $schemeAuthority .= $host.$port;
+ }
+
+ if (self::RELATIVE_PATH === $referenceType) {
+ $url = self::getRelativePath($this->context->getPathInfo(), $url);
+ } else {
+ $url = $schemeAuthority.$this->context->getBaseUrl().$url;
+ }
+
+ // add a query string if needed
+ $extra = array_udiff_assoc(array_diff_key($parameters, $variables), $defaults, function ($a, $b) {
+ return $a == $b ? 0 : 1;
+ });
+
+ // extract fragment
+ $fragment = '';
+ if (isset($defaults['_fragment'])) {
+ $fragment = $defaults['_fragment'];
+ }
+
+ if (isset($extra['_fragment'])) {
+ $fragment = $extra['_fragment'];
+ unset($extra['_fragment']);
+ }
+
+ if ($extra && $query = http_build_query($extra, '', '&', PHP_QUERY_RFC3986)) {
+ // "/" and "?" can be left decoded for better user experience, see
+ // http://tools.ietf.org/html/rfc3986#section-3.4
+ $url .= '?'.strtr($query, array('%2F' => '/'));
+ }
+
+ if ('' !== $fragment) {
+ $url .= '#'.strtr(rawurlencode($fragment), array('%2F' => '/', '%3F' => '?'));
+ }
+
+ return $url;
+ }
+
+ /**
+ * Returns the target path as relative reference from the base path.
+ *
+ * Only the URIs path component (no schema, host etc.) is relevant and must be given, starting with a slash.
+ * Both paths must be absolute and not contain relative parts.
+ * Relative URLs from one resource to another are useful when generating self-contained downloadable document archives.
+ * Furthermore, they can be used to reduce the link size in documents.
+ *
+ * Example target paths, given a base path of "/a/b/c/d":
+ * - "/a/b/c/d" -> ""
+ * - "/a/b/c/" -> "./"
+ * - "/a/b/" -> "../"
+ * - "/a/b/c/other" -> "other"
+ * - "/a/x/y" -> "../../x/y"
+ *
+ * @param string $basePath The base path
+ * @param string $targetPath The target path
+ *
+ * @return string The relative target path
+ */
+ public static function getRelativePath($basePath, $targetPath)
+ {
+ if ($basePath === $targetPath) {
+ return '';
+ }
+
+ $sourceDirs = explode('/', isset($basePath[0]) && '/' === $basePath[0] ? substr($basePath, 1) : $basePath);
+ $targetDirs = explode('/', isset($targetPath[0]) && '/' === $targetPath[0] ? substr($targetPath, 1) : $targetPath);
+ array_pop($sourceDirs);
+ $targetFile = array_pop($targetDirs);
+
+ foreach ($sourceDirs as $i => $dir) {
+ if (isset($targetDirs[$i]) && $dir === $targetDirs[$i]) {
+ unset($sourceDirs[$i], $targetDirs[$i]);
+ } else {
+ break;
+ }
+ }
+
+ $targetDirs[] = $targetFile;
+ $path = str_repeat('../', count($sourceDirs)).implode('/', $targetDirs);
+
+ // A reference to the same base directory or an empty subdirectory must be prefixed with "./".
+ // This also applies to a segment with a colon character (e.g., "file:colon") that cannot be used
+ // as the first segment of a relative-path reference, as it would be mistaken for a scheme name
+ // (see http://tools.ietf.org/html/rfc3986#section-4.2).
+ return '' === $path || '/' === $path[0]
+ || false !== ($colonPos = strpos($path, ':')) && ($colonPos < ($slashPos = strpos($path, '/')) || false === $slashPos)
+ ? "./$path" : $path;
+ }
+}
diff --git a/assets/php/vendor/symfony/routing/Generator/UrlGeneratorInterface.php b/assets/php/vendor/symfony/routing/Generator/UrlGeneratorInterface.php
new file mode 100644
index 0000000..d6e7938
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Generator/UrlGeneratorInterface.php
@@ -0,0 +1,86 @@
+<?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\Exception\InvalidParameterException;
+use Symfony\Component\Routing\Exception\MissingMandatoryParametersException;
+use Symfony\Component\Routing\Exception\RouteNotFoundException;
+use Symfony\Component\Routing\RequestContextAwareInterface;
+
+/**
+ * UrlGeneratorInterface is the interface that all URL generator classes must implement.
+ *
+ * The constants in this interface define the different types of resource references that
+ * are declared in RFC 3986: http://tools.ietf.org/html/rfc3986
+ * We are using the term "URL" instead of "URI" as this is more common in web applications
+ * and we do not need to distinguish them as the difference is mostly semantical and
+ * less technical. Generating URIs, i.e. representation-independent resource identifiers,
+ * is also possible.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ * @author Tobias Schultze <http://tobion.de>
+ */
+interface UrlGeneratorInterface extends RequestContextAwareInterface
+{
+ /**
+ * Generates an absolute URL, e.g. "http://example.com/dir/file".
+ */
+ const ABSOLUTE_URL = 0;
+
+ /**
+ * Generates an absolute path, e.g. "/dir/file".
+ */
+ const ABSOLUTE_PATH = 1;
+
+ /**
+ * Generates a relative path based on the current request path, e.g. "../parent-file".
+ *
+ * @see UrlGenerator::getRelativePath()
+ */
+ const RELATIVE_PATH = 2;
+
+ /**
+ * Generates a network path, e.g. "//example.com/dir/file".
+ * Such reference reuses the current scheme but specifies the host.
+ */
+ const NETWORK_PATH = 3;
+
+ /**
+ * Generates a URL or path for a specific route based on the given parameters.
+ *
+ * Parameters that reference placeholders in the route pattern will substitute them in the
+ * path or host. Extra params are added as query string to the URL.
+ *
+ * When the passed reference type cannot be generated for the route because it requires a different
+ * host or scheme than the current one, the method will return a more comprehensive reference
+ * that includes the required params. For example, when you call this method with $referenceType = ABSOLUTE_PATH
+ * but the route requires the https scheme whereas the current scheme is http, it will instead return an
+ * ABSOLUTE_URL with the https scheme and the current host. This makes sure the generated URL matches
+ * the route in any case.
+ *
+ * If there is no route with the given name, the generator must throw the RouteNotFoundException.
+ *
+ * The special parameter _fragment will be used as the document fragment suffixed to the final URL.
+ *
+ * @param string $name The name of the route
+ * @param mixed $parameters An array of parameters
+ * @param int $referenceType The type of reference to be generated (one of the constants)
+ *
+ * @return string The generated URL
+ *
+ * @throws RouteNotFoundException If the named route doesn't exist
+ * @throws MissingMandatoryParametersException When some parameters are missing that are mandatory for the route
+ * @throws InvalidParameterException When a parameter value for a placeholder is not correct because
+ * it does not match the requirement
+ */
+ public function generate($name, $parameters = array(), $referenceType = self::ABSOLUTE_PATH);
+}
diff --git a/assets/php/vendor/symfony/routing/LICENSE b/assets/php/vendor/symfony/routing/LICENSE
new file mode 100644
index 0000000..21d7fb9
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2004-2018 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.
diff --git a/assets/php/vendor/symfony/routing/Loader/AnnotationClassLoader.php b/assets/php/vendor/symfony/routing/Loader/AnnotationClassLoader.php
new file mode 100644
index 0000000..2fe6fb5
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Loader/AnnotationClassLoader.php
@@ -0,0 +1,269 @@
+<?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\LoaderResolverInterface;
+
+/**
+ * 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 path. The annotation also
+ * recognizes several parameters: requirements, options, defaults, schemes,
+ * methods, host, 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;
+
+ /**
+ * @var string
+ */
+ protected $routeAnnotationClass = 'Symfony\\Component\\Routing\\Annotation\\Route';
+
+ /**
+ * @var int
+ */
+ protected $defaultRouteIndex = 0;
+
+ 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|null $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));
+ }
+
+ $class = new \ReflectionClass($class);
+ if ($class->isAbstract()) {
+ throw new \InvalidArgumentException(sprintf('Annotations from class "%s" cannot be read as it is abstract.', $class->getName()));
+ }
+
+ $globals = $this->getGlobals($class);
+
+ $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);
+ }
+ }
+ }
+
+ if (0 === $collection->count() && $class->hasMethod('__invoke') && $annot = $this->reader->getClassAnnotation($class, $this->routeAnnotationClass)) {
+ $globals['path'] = '';
+ $globals['name'] = '';
+ $this->addRoute($collection, $annot, $globals, $class, $class->getMethod('__invoke'));
+ }
+
+ return $collection;
+ }
+
+ protected function addRoute(RouteCollection $collection, $annot, $globals, \ReflectionClass $class, \ReflectionMethod $method)
+ {
+ $name = $annot->getName();
+ if (null === $name) {
+ $name = $this->getDefaultRouteName($class, $method);
+ }
+ $name = $globals['name'].$name;
+
+ $defaults = array_replace($globals['defaults'], $annot->getDefaults());
+ foreach ($method->getParameters() as $param) {
+ if (false !== strpos($globals['path'].$annot->getPath(), sprintf('{%s}', $param->getName())) && !isset($defaults[$param->getName()]) && $param->isDefaultValueAvailable()) {
+ $defaults[$param->getName()] = $param->getDefaultValue();
+ }
+ }
+ $requirements = array_replace($globals['requirements'], $annot->getRequirements());
+ $options = array_replace($globals['options'], $annot->getOptions());
+ $schemes = array_merge($globals['schemes'], $annot->getSchemes());
+ $methods = array_merge($globals['methods'], $annot->getMethods());
+
+ $host = $annot->getHost();
+ if (null === $host) {
+ $host = $globals['host'];
+ }
+
+ $condition = $annot->getCondition();
+ if (null === $condition) {
+ $condition = $globals['condition'];
+ }
+
+ $route = $this->createRoute($globals['path'].$annot->getPath(), $defaults, $requirements, $options, $host, $schemes, $methods, $condition);
+
+ $this->configureRoute($route, $class, $method, $annot);
+
+ $collection->add($name, $route);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ 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);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setResolver(LoaderResolverInterface $resolver)
+ {
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ 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;
+ }
+
+ protected function getGlobals(\ReflectionClass $class)
+ {
+ $globals = array(
+ 'path' => '',
+ 'requirements' => array(),
+ 'options' => array(),
+ 'defaults' => array(),
+ 'schemes' => array(),
+ 'methods' => array(),
+ 'host' => '',
+ 'condition' => '',
+ 'name' => '',
+ );
+
+ if ($annot = $this->reader->getClassAnnotation($class, $this->routeAnnotationClass)) {
+ if (null !== $annot->getName()) {
+ $globals['name'] = $annot->getName();
+ }
+
+ if (null !== $annot->getPath()) {
+ $globals['path'] = $annot->getPath();
+ }
+
+ if (null !== $annot->getRequirements()) {
+ $globals['requirements'] = $annot->getRequirements();
+ }
+
+ if (null !== $annot->getOptions()) {
+ $globals['options'] = $annot->getOptions();
+ }
+
+ if (null !== $annot->getDefaults()) {
+ $globals['defaults'] = $annot->getDefaults();
+ }
+
+ if (null !== $annot->getSchemes()) {
+ $globals['schemes'] = $annot->getSchemes();
+ }
+
+ if (null !== $annot->getMethods()) {
+ $globals['methods'] = $annot->getMethods();
+ }
+
+ if (null !== $annot->getHost()) {
+ $globals['host'] = $annot->getHost();
+ }
+
+ if (null !== $annot->getCondition()) {
+ $globals['condition'] = $annot->getCondition();
+ }
+ }
+
+ return $globals;
+ }
+
+ protected function createRoute($path, $defaults, $requirements, $options, $host, $schemes, $methods, $condition)
+ {
+ return new Route($path, $defaults, $requirements, $options, $host, $schemes, $methods, $condition);
+ }
+
+ abstract protected function configureRoute(Route $route, \ReflectionClass $class, \ReflectionMethod $method, $annot);
+}
diff --git a/assets/php/vendor/symfony/routing/Loader/AnnotationDirectoryLoader.php b/assets/php/vendor/symfony/routing/Loader/AnnotationDirectoryLoader.php
new file mode 100644
index 0000000..4574a02
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Loader/AnnotationDirectoryLoader.php
@@ -0,0 +1,93 @@
+<?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|null $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)
+ {
+ if (!is_dir($dir = $this->locator->locate($path))) {
+ return parent::supports($path, $type) ? parent::load($path, $type) : new RouteCollection();
+ }
+
+ $collection = new RouteCollection();
+ $collection->addResource(new DirectoryResource($dir, '/\.php$/'));
+ $files = iterator_to_array(new \RecursiveIteratorIterator(
+ new \RecursiveCallbackFilterIterator(
+ new \RecursiveDirectoryIterator($dir, \FilesystemIterator::SKIP_DOTS | \FilesystemIterator::FOLLOW_SYMLINKS),
+ function (\SplFileInfo $current) {
+ return '.' !== substr($current->getBasename(), 0, 1);
+ }
+ ),
+ \RecursiveIteratorIterator::LEAVES_ONLY
+ ));
+ usort($files, function (\SplFileInfo $a, \SplFileInfo $b) {
+ return (string) $a > (string) $b ? 1 : -1;
+ });
+
+ foreach ($files 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;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function supports($resource, $type = null)
+ {
+ if ('annotation' === $type) {
+ return true;
+ }
+
+ if ($type || !is_string($resource)) {
+ return false;
+ }
+
+ try {
+ return is_dir($this->locator->locate($resource));
+ } catch (\Exception $e) {
+ return false;
+ }
+ }
+}
diff --git a/assets/php/vendor/symfony/routing/Loader/AnnotationFileLoader.php b/assets/php/vendor/symfony/routing/Loader/AnnotationFileLoader.php
new file mode 100644
index 0000000..cf9f070
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Loader/AnnotationFileLoader.php
@@ -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\Config\Resource\FileResource;
+use Symfony\Component\Config\Loader\FileLoader;
+use Symfony\Component\Config\FileLocatorInterface;
+
+/**
+ * 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;
+
+ /**
+ * @throws \RuntimeException
+ */
+ public function __construct(FileLocatorInterface $locator, AnnotationClassLoader $loader)
+ {
+ if (!function_exists('token_get_all')) {
+ throw new \RuntimeException('The Tokenizer extension is required for the routing annotation loaders.');
+ }
+
+ parent::__construct($locator);
+
+ $this->loader = $loader;
+ }
+
+ /**
+ * Loads from annotations from a file.
+ *
+ * @param string $file A PHP file path
+ * @param string|null $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));
+ }
+ if (\PHP_VERSION_ID >= 70000) {
+ // PHP 7 memory manager will not release after token_get_all(), see https://bugs.php.net/70098
+ gc_mem_caches();
+ }
+
+ return $collection;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ 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));
+
+ if (1 === count($tokens) && T_INLINE_HTML === $tokens[0][0]) {
+ throw new \InvalidArgumentException(sprintf('The file "%s" does not contain PHP code. Did you forgot to add the "<?php" start tag at the beginning of the file?', $file));
+ }
+
+ for ($i = 0; isset($tokens[$i]); ++$i) {
+ $token = $tokens[$i];
+
+ if (!isset($token[1])) {
+ continue;
+ }
+
+ if (true === $class && T_STRING === $token[0]) {
+ return $namespace.'\\'.$token[1];
+ }
+
+ if (true === $namespace && T_STRING === $token[0]) {
+ $namespace = $token[1];
+ while (isset($tokens[++$i][1]) && in_array($tokens[$i][0], array(T_NS_SEPARATOR, T_STRING))) {
+ $namespace .= $tokens[$i][1];
+ }
+ $token = $tokens[$i];
+ }
+
+ if (T_CLASS === $token[0]) {
+ // Skip usage of ::class constant and anonymous classes
+ $skipClassToken = false;
+ for ($j = $i - 1; $j > 0; --$j) {
+ if (!isset($tokens[$j][1])) {
+ break;
+ }
+
+ if (T_DOUBLE_COLON === $tokens[$j][0] || T_NEW === $tokens[$j][0]) {
+ $skipClassToken = true;
+ break;
+ } elseif (!in_array($tokens[$j][0], array(T_WHITESPACE, T_DOC_COMMENT, T_COMMENT))) {
+ break;
+ }
+ }
+
+ if (!$skipClassToken) {
+ $class = true;
+ }
+ }
+
+ if (T_NAMESPACE === $token[0]) {
+ $namespace = true;
+ }
+ }
+
+ return false;
+ }
+}
diff --git a/assets/php/vendor/symfony/routing/Loader/ClosureLoader.php b/assets/php/vendor/symfony/routing/Loader/ClosureLoader.php
new file mode 100644
index 0000000..5df9f6a
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Loader/ClosureLoader.php
@@ -0,0 +1,46 @@
+<?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;
+use Symfony\Component\Routing\RouteCollection;
+
+/**
+ * ClosureLoader loads routes from a PHP closure.
+ *
+ * The Closure must return a RouteCollection instance.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+class ClosureLoader extends Loader
+{
+ /**
+ * Loads a Closure.
+ *
+ * @param \Closure $closure A Closure
+ * @param string|null $type The resource type
+ *
+ * @return RouteCollection A RouteCollection instance
+ */
+ public function load($closure, $type = null)
+ {
+ return $closure();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function supports($resource, $type = null)
+ {
+ return $resource instanceof \Closure && (!$type || 'closure' === $type);
+ }
+}
diff --git a/assets/php/vendor/symfony/routing/Loader/Configurator/CollectionConfigurator.php b/assets/php/vendor/symfony/routing/Loader/Configurator/CollectionConfigurator.php
new file mode 100644
index 0000000..8baefdd
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Loader/Configurator/CollectionConfigurator.php
@@ -0,0 +1,81 @@
+<?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\Configurator;
+
+use Symfony\Component\Routing\Route;
+use Symfony\Component\Routing\RouteCollection;
+
+/**
+ * @author Nicolas Grekas <p@tchwork.com>
+ */
+class CollectionConfigurator
+{
+ use Traits\AddTrait;
+ use Traits\RouteTrait;
+
+ private $parent;
+ private $parentConfigurator;
+
+ public function __construct(RouteCollection $parent, $name, self $parentConfigurator = null)
+ {
+ $this->parent = $parent;
+ $this->name = $name;
+ $this->collection = new RouteCollection();
+ $this->route = new Route('');
+ $this->parentConfigurator = $parentConfigurator; // for GC control
+ }
+
+ public function __destruct()
+ {
+ $this->collection->addPrefix(rtrim($this->route->getPath(), '/'));
+ $this->parent->addCollection($this->collection);
+ }
+
+ /**
+ * Adds a route.
+ *
+ * @param string $name
+ * @param string $path
+ *
+ * @return RouteConfigurator
+ */
+ final public function add($name, $path)
+ {
+ $this->collection->add($this->name.$name, $route = clone $this->route);
+
+ return new RouteConfigurator($this->collection, $route->setPath($path), $this->name, $this);
+ }
+
+ /**
+ * Creates a sub-collection.
+ *
+ * @return self
+ */
+ final public function collection($name = '')
+ {
+ return new self($this->collection, $this->name.$name, $this);
+ }
+
+ /**
+ * Sets the prefix to add to the path of all child routes.
+ *
+ * @param string $prefix
+ *
+ * @return $this
+ */
+ final public function prefix($prefix)
+ {
+ $this->route->setPath($prefix);
+
+ return $this;
+ }
+}
diff --git a/assets/php/vendor/symfony/routing/Loader/Configurator/ImportConfigurator.php b/assets/php/vendor/symfony/routing/Loader/Configurator/ImportConfigurator.php
new file mode 100644
index 0000000..d0a3c37
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Loader/Configurator/ImportConfigurator.php
@@ -0,0 +1,49 @@
+<?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\Configurator;
+
+use Symfony\Component\Routing\RouteCollection;
+
+/**
+ * @author Nicolas Grekas <p@tchwork.com>
+ */
+class ImportConfigurator
+{
+ use Traits\RouteTrait;
+
+ private $parent;
+
+ public function __construct(RouteCollection $parent, RouteCollection $route)
+ {
+ $this->parent = $parent;
+ $this->route = $route;
+ }
+
+ public function __destruct()
+ {
+ $this->parent->addCollection($this->route);
+ }
+
+ /**
+ * Sets the prefix to add to the path of all child routes.
+ *
+ * @param string $prefix
+ *
+ * @return $this
+ */
+ final public function prefix($prefix)
+ {
+ $this->route->addPrefix($prefix);
+
+ return $this;
+ }
+}
diff --git a/assets/php/vendor/symfony/routing/Loader/Configurator/RouteConfigurator.php b/assets/php/vendor/symfony/routing/Loader/Configurator/RouteConfigurator.php
new file mode 100644
index 0000000..6422bbf
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Loader/Configurator/RouteConfigurator.php
@@ -0,0 +1,34 @@
+<?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\Configurator;
+
+use Symfony\Component\Routing\Route;
+use Symfony\Component\Routing\RouteCollection;
+
+/**
+ * @author Nicolas Grekas <p@tchwork.com>
+ */
+class RouteConfigurator
+{
+ use Traits\AddTrait;
+ use Traits\RouteTrait;
+
+ private $parentConfigurator;
+
+ public function __construct(RouteCollection $collection, Route $route, $name = '', CollectionConfigurator $parentConfigurator = null)
+ {
+ $this->collection = $collection;
+ $this->route = $route;
+ $this->name = $name;
+ $this->parentConfigurator = $parentConfigurator; // for GC control
+ }
+}
diff --git a/assets/php/vendor/symfony/routing/Loader/Configurator/RoutingConfigurator.php b/assets/php/vendor/symfony/routing/Loader/Configurator/RoutingConfigurator.php
new file mode 100644
index 0000000..d992cef
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Loader/Configurator/RoutingConfigurator.php
@@ -0,0 +1,62 @@
+<?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\Configurator;
+
+use Symfony\Component\Routing\Loader\PhpFileLoader;
+use Symfony\Component\Routing\RouteCollection;
+
+/**
+ * @author Nicolas Grekas <p@tchwork.com>
+ */
+class RoutingConfigurator
+{
+ use Traits\AddTrait;
+
+ private $loader;
+ private $path;
+ private $file;
+
+ public function __construct(RouteCollection $collection, PhpFileLoader $loader, $path, $file)
+ {
+ $this->collection = $collection;
+ $this->loader = $loader;
+ $this->path = $path;
+ $this->file = $file;
+ }
+
+ /**
+ * @return ImportConfigurator
+ */
+ final public function import($resource, $type = null, $ignoreErrors = false)
+ {
+ $this->loader->setCurrentDir(dirname($this->path));
+ $imported = $this->loader->import($resource, $type, $ignoreErrors, $this->file);
+ if (!is_array($imported)) {
+ return new ImportConfigurator($this->collection, $imported);
+ }
+
+ $mergedCollection = new RouteCollection();
+ foreach ($imported as $subCollection) {
+ $mergedCollection->addCollection($subCollection);
+ }
+
+ return new ImportConfigurator($this->collection, $mergedCollection);
+ }
+
+ /**
+ * @return CollectionConfigurator
+ */
+ final public function collection($name = '')
+ {
+ return new CollectionConfigurator($this->collection, $name);
+ }
+}
diff --git a/assets/php/vendor/symfony/routing/Loader/Configurator/Traits/AddTrait.php b/assets/php/vendor/symfony/routing/Loader/Configurator/Traits/AddTrait.php
new file mode 100644
index 0000000..e8b8fa2
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Loader/Configurator/Traits/AddTrait.php
@@ -0,0 +1,55 @@
+<?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\Configurator\Traits;
+
+use Symfony\Component\Routing\Loader\Configurator\RouteConfigurator;
+use Symfony\Component\Routing\Route;
+use Symfony\Component\Routing\RouteCollection;
+
+trait AddTrait
+{
+ /**
+ * @var RouteCollection
+ */
+ private $collection;
+
+ private $name = '';
+
+ /**
+ * Adds a route.
+ *
+ * @param string $name
+ * @param string $path
+ *
+ * @return RouteConfigurator
+ */
+ final public function add($name, $path)
+ {
+ $parentConfigurator = $this instanceof RouteConfigurator ? $this->parentConfigurator : null;
+ $this->collection->add($this->name.$name, $route = new Route($path));
+
+ return new RouteConfigurator($this->collection, $route, '', $parentConfigurator);
+ }
+
+ /**
+ * Adds a route.
+ *
+ * @param string $name
+ * @param string $path
+ *
+ * @return RouteConfigurator
+ */
+ final public function __invoke($name, $path)
+ {
+ return $this->add($name, $path);
+ }
+}
diff --git a/assets/php/vendor/symfony/routing/Loader/Configurator/Traits/RouteTrait.php b/assets/php/vendor/symfony/routing/Loader/Configurator/Traits/RouteTrait.php
new file mode 100644
index 0000000..4d2e255
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Loader/Configurator/Traits/RouteTrait.php
@@ -0,0 +1,131 @@
+<?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\Configurator\Traits;
+
+use Symfony\Component\Routing\Route;
+use Symfony\Component\Routing\RouteCollection;
+
+trait RouteTrait
+{
+ /**
+ * @var RouteCollection|Route
+ */
+ private $route;
+
+ /**
+ * Adds defaults.
+ *
+ * @return $this
+ */
+ final public function defaults(array $defaults)
+ {
+ $this->route->addDefaults($defaults);
+
+ return $this;
+ }
+
+ /**
+ * Adds requirements.
+ *
+ * @return $this
+ */
+ final public function requirements(array $requirements)
+ {
+ $this->route->addRequirements($requirements);
+
+ return $this;
+ }
+
+ /**
+ * Adds options.
+ *
+ * @return $this
+ */
+ final public function options(array $options)
+ {
+ $this->route->addOptions($options);
+
+ return $this;
+ }
+
+ /**
+ * Sets the condition.
+ *
+ * @param string $condition
+ *
+ * @return $this
+ */
+ final public function condition($condition)
+ {
+ $this->route->setCondition($condition);
+
+ return $this;
+ }
+
+ /**
+ * Sets the pattern for the host.
+ *
+ * @param string $pattern
+ *
+ * @return $this
+ */
+ final public function host($pattern)
+ {
+ $this->route->setHost($pattern);
+
+ return $this;
+ }
+
+ /**
+ * Sets the schemes (e.g. 'https') this route is restricted to.
+ * So an empty array means that any scheme is allowed.
+ *
+ * @param string[] $schemes
+ *
+ * @return $this
+ */
+ final public function schemes(array $schemes)
+ {
+ $this->route->setSchemes($schemes);
+
+ return $this;
+ }
+
+ /**
+ * Sets the HTTP methods (e.g. 'POST') this route is restricted to.
+ * So an empty array means that any method is allowed.
+ *
+ * @param string[] $methods
+ *
+ * @return $this
+ */
+ final public function methods(array $methods)
+ {
+ $this->route->setMethods($methods);
+
+ return $this;
+ }
+
+ /**
+ * Adds the "_controller" entry to defaults.
+ *
+ * @param callable|string $controller a callable or parseable pseudo-callable
+ *
+ * @return $this
+ */
+ final public function controller($controller)
+ {
+ $this->route->addDefaults(array('_controller' => $controller));
+
+ return $this;
+ }
+}
diff --git a/assets/php/vendor/symfony/routing/Loader/DependencyInjection/ServiceRouterLoader.php b/assets/php/vendor/symfony/routing/Loader/DependencyInjection/ServiceRouterLoader.php
new file mode 100644
index 0000000..6c16216
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Loader/DependencyInjection/ServiceRouterLoader.php
@@ -0,0 +1,40 @@
+<?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\DependencyInjection;
+
+use Psr\Container\ContainerInterface;
+use Symfony\Component\Routing\Loader\ObjectRouteLoader;
+
+/**
+ * A route loader that executes a service to load the routes.
+ *
+ * This depends on the DependencyInjection component.
+ *
+ * @author Ryan Weaver <ryan@knpuniversity.com>
+ */
+class ServiceRouterLoader extends ObjectRouteLoader
+{
+ /**
+ * @var ContainerInterface
+ */
+ private $container;
+
+ public function __construct(ContainerInterface $container)
+ {
+ $this->container = $container;
+ }
+
+ protected function getServiceObject($id)
+ {
+ return $this->container->get($id);
+ }
+}
diff --git a/assets/php/vendor/symfony/routing/Loader/DirectoryLoader.php b/assets/php/vendor/symfony/routing/Loader/DirectoryLoader.php
new file mode 100644
index 0000000..4bb5b31
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Loader/DirectoryLoader.php
@@ -0,0 +1,58 @@
+<?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\FileLoader;
+use Symfony\Component\Routing\RouteCollection;
+use Symfony\Component\Config\Resource\DirectoryResource;
+
+class DirectoryLoader extends FileLoader
+{
+ /**
+ * {@inheritdoc}
+ */
+ public function load($file, $type = null)
+ {
+ $path = $this->locator->locate($file);
+
+ $collection = new RouteCollection();
+ $collection->addResource(new DirectoryResource($path));
+
+ foreach (scandir($path) as $dir) {
+ if ('.' !== $dir[0]) {
+ $this->setCurrentDir($path);
+ $subPath = $path.'/'.$dir;
+ $subType = null;
+
+ if (is_dir($subPath)) {
+ $subPath .= '/';
+ $subType = 'directory';
+ }
+
+ $subCollection = $this->import($subPath, $subType, false, $path);
+ $collection->addCollection($subCollection);
+ }
+ }
+
+ return $collection;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function supports($resource, $type = null)
+ {
+ // only when type is forced to directory, not to conflict with AnnotationLoader
+
+ return 'directory' === $type;
+ }
+}
diff --git a/assets/php/vendor/symfony/routing/Loader/GlobFileLoader.php b/assets/php/vendor/symfony/routing/Loader/GlobFileLoader.php
new file mode 100644
index 0000000..03ee341
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Loader/GlobFileLoader.php
@@ -0,0 +1,47 @@
+<?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\FileLoader;
+use Symfony\Component\Routing\RouteCollection;
+
+/**
+ * GlobFileLoader loads files from a glob pattern.
+ *
+ * @author Nicolas Grekas <p@tchwork.com>
+ */
+class GlobFileLoader extends FileLoader
+{
+ /**
+ * {@inheritdoc}
+ */
+ public function load($resource, $type = null)
+ {
+ $collection = new RouteCollection();
+
+ foreach ($this->glob($resource, false, $globResource) as $path => $info) {
+ $collection->addCollection($this->import($path));
+ }
+
+ $collection->addResource($globResource);
+
+ return $collection;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function supports($resource, $type = null)
+ {
+ return 'glob' === $type;
+ }
+}
diff --git a/assets/php/vendor/symfony/routing/Loader/ObjectRouteLoader.php b/assets/php/vendor/symfony/routing/Loader/ObjectRouteLoader.php
new file mode 100644
index 0000000..0899a81
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Loader/ObjectRouteLoader.php
@@ -0,0 +1,95 @@
+<?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;
+use Symfony\Component\Config\Resource\FileResource;
+use Symfony\Component\Routing\RouteCollection;
+
+/**
+ * A route loader that calls a method on an object to load the routes.
+ *
+ * @author Ryan Weaver <ryan@knpuniversity.com>
+ */
+abstract class ObjectRouteLoader extends Loader
+{
+ /**
+ * Returns the object that the method will be called on to load routes.
+ *
+ * For example, if your application uses a service container,
+ * the $id may be a service id.
+ *
+ * @param string $id
+ *
+ * @return object
+ */
+ abstract protected function getServiceObject($id);
+
+ /**
+ * Calls the service that will load the routes.
+ *
+ * @param mixed $resource Some value that will resolve to a callable
+ * @param string|null $type The resource type
+ *
+ * @return RouteCollection
+ */
+ public function load($resource, $type = null)
+ {
+ $parts = explode(':', $resource);
+ if (2 != count($parts)) {
+ throw new \InvalidArgumentException(sprintf('Invalid resource "%s" passed to the "service" route loader: use the format "service_name:methodName"', $resource));
+ }
+
+ $serviceString = $parts[0];
+ $method = $parts[1];
+
+ $loaderObject = $this->getServiceObject($serviceString);
+
+ if (!is_object($loaderObject)) {
+ throw new \LogicException(sprintf('%s:getServiceObject() must return an object: %s returned', get_class($this), gettype($loaderObject)));
+ }
+
+ if (!method_exists($loaderObject, $method)) {
+ throw new \BadMethodCallException(sprintf('Method "%s" not found on "%s" when importing routing resource "%s"', $method, get_class($loaderObject), $resource));
+ }
+
+ $routeCollection = call_user_func(array($loaderObject, $method), $this);
+
+ if (!$routeCollection instanceof RouteCollection) {
+ $type = is_object($routeCollection) ? get_class($routeCollection) : gettype($routeCollection);
+
+ throw new \LogicException(sprintf('The %s::%s method must return a RouteCollection: %s returned', get_class($loaderObject), $method, $type));
+ }
+
+ // make the service file tracked so that if it changes, the cache rebuilds
+ $this->addClassResource(new \ReflectionClass($loaderObject), $routeCollection);
+
+ return $routeCollection;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function supports($resource, $type = null)
+ {
+ return 'service' === $type;
+ }
+
+ private function addClassResource(\ReflectionClass $class, RouteCollection $collection)
+ {
+ do {
+ if (is_file($class->getFileName())) {
+ $collection->addResource(new FileResource($class->getFileName()));
+ }
+ } while ($class = $class->getParentClass());
+ }
+}
diff --git a/assets/php/vendor/symfony/routing/Loader/PhpFileLoader.php b/assets/php/vendor/symfony/routing/Loader/PhpFileLoader.php
new file mode 100644
index 0000000..3fcd692
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Loader/PhpFileLoader.php
@@ -0,0 +1,75 @@
+<?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\FileLoader;
+use Symfony\Component\Config\Resource\FileResource;
+use Symfony\Component\Routing\Loader\Configurator\RoutingConfigurator;
+use Symfony\Component\Routing\RouteCollection;
+
+/**
+ * PhpFileLoader loads routes from a PHP file.
+ *
+ * The file must return a RouteCollection instance.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+class PhpFileLoader extends FileLoader
+{
+ /**
+ * Loads a PHP file.
+ *
+ * @param string $file A PHP file path
+ * @param string|null $type The resource type
+ *
+ * @return RouteCollection A RouteCollection instance
+ */
+ public function load($file, $type = null)
+ {
+ $path = $this->locator->locate($file);
+ $this->setCurrentDir(dirname($path));
+
+ // the closure forbids access to the private scope in the included file
+ $loader = $this;
+ $load = \Closure::bind(function ($file) use ($loader) {
+ return include $file;
+ }, null, ProtectedPhpFileLoader::class);
+
+ $result = $load($path);
+
+ if ($result instanceof \Closure) {
+ $collection = new RouteCollection();
+ $result(new RoutingConfigurator($collection, $this, $path, $file), $this);
+ } else {
+ $collection = $result;
+ }
+
+ $collection->addResource(new FileResource($path));
+
+ return $collection;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function supports($resource, $type = null)
+ {
+ return is_string($resource) && 'php' === pathinfo($resource, PATHINFO_EXTENSION) && (!$type || 'php' === $type);
+ }
+}
+
+/**
+ * @internal
+ */
+final class ProtectedPhpFileLoader extends PhpFileLoader
+{
+}
diff --git a/assets/php/vendor/symfony/routing/Loader/XmlFileLoader.php b/assets/php/vendor/symfony/routing/Loader/XmlFileLoader.php
new file mode 100644
index 0000000..f3f6605
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Loader/XmlFileLoader.php
@@ -0,0 +1,359 @@
+<?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;
+use Symfony\Component\Config\Util\XmlUtils;
+
+/**
+ * XmlFileLoader loads XML routing files.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ * @author Tobias Schultze <http://tobion.de>
+ */
+class XmlFileLoader extends FileLoader
+{
+ const NAMESPACE_URI = 'http://symfony.com/schema/routing';
+ const SCHEME_PATH = '/schema/routing/routing-1.0.xsd';
+
+ /**
+ * Loads an XML file.
+ *
+ * @param string $file An XML file path
+ * @param string|null $type The resource type
+ *
+ * @return RouteCollection A RouteCollection instance
+ *
+ * @throws \InvalidArgumentException when the file cannot be loaded or when the XML cannot be
+ * parsed because it does not validate against the scheme
+ */
+ 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 Collection to associate with the node
+ * @param \DOMElement $node Element to parse
+ * @param string $path Full path of the XML file being processed
+ * @param string $file Loaded file name
+ *
+ * @throws \InvalidArgumentException When the XML is invalid
+ */
+ protected function parseNode(RouteCollection $collection, \DOMElement $node, $path, $file)
+ {
+ if (self::NAMESPACE_URI !== $node->namespaceURI) {
+ return;
+ }
+
+ switch ($node->localName) {
+ case 'route':
+ $this->parseRoute($collection, $node, $path);
+ break;
+ case 'import':
+ $this->parseImport($collection, $node, $path, $file);
+ break;
+ default:
+ throw new \InvalidArgumentException(sprintf('Unknown tag "%s" used in file "%s". Expected "route" or "import".', $node->localName, $path));
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ 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 RouteCollection instance
+ * @param \DOMElement $node Element to parse that represents a Route
+ * @param string $path Full path of the XML file being processed
+ *
+ * @throws \InvalidArgumentException When the XML is invalid
+ */
+ protected function parseRoute(RouteCollection $collection, \DOMElement $node, $path)
+ {
+ if ('' === ($id = $node->getAttribute('id')) || !$node->hasAttribute('path')) {
+ throw new \InvalidArgumentException(sprintf('The <route> element in file "%s" must have an "id" and a "path" attribute.', $path));
+ }
+
+ $schemes = preg_split('/[\s,\|]++/', $node->getAttribute('schemes'), -1, PREG_SPLIT_NO_EMPTY);
+ $methods = preg_split('/[\s,\|]++/', $node->getAttribute('methods'), -1, PREG_SPLIT_NO_EMPTY);
+
+ list($defaults, $requirements, $options, $condition) = $this->parseConfigs($node, $path);
+
+ $route = new Route($node->getAttribute('path'), $defaults, $requirements, $options, $node->getAttribute('host'), $schemes, $methods, $condition);
+ $collection->add($id, $route);
+ }
+
+ /**
+ * Parses an import and adds the routes in the resource to the RouteCollection.
+ *
+ * @param RouteCollection $collection RouteCollection instance
+ * @param \DOMElement $node Element to parse that represents a Route
+ * @param string $path Full path of the XML file being processed
+ * @param string $file Loaded file name
+ *
+ * @throws \InvalidArgumentException When the XML is invalid
+ */
+ protected function parseImport(RouteCollection $collection, \DOMElement $node, $path, $file)
+ {
+ if ('' === $resource = $node->getAttribute('resource')) {
+ throw new \InvalidArgumentException(sprintf('The <import> element in file "%s" must have a "resource" attribute.', $path));
+ }
+
+ $type = $node->getAttribute('type');
+ $prefix = $node->getAttribute('prefix');
+ $host = $node->hasAttribute('host') ? $node->getAttribute('host') : null;
+ $schemes = $node->hasAttribute('schemes') ? preg_split('/[\s,\|]++/', $node->getAttribute('schemes'), -1, PREG_SPLIT_NO_EMPTY) : null;
+ $methods = $node->hasAttribute('methods') ? preg_split('/[\s,\|]++/', $node->getAttribute('methods'), -1, PREG_SPLIT_NO_EMPTY) : null;
+
+ list($defaults, $requirements, $options, $condition) = $this->parseConfigs($node, $path);
+
+ $this->setCurrentDir(dirname($path));
+
+ $imported = $this->import($resource, ('' !== $type ? $type : null), false, $file);
+
+ if (!is_array($imported)) {
+ $imported = array($imported);
+ }
+
+ foreach ($imported as $subCollection) {
+ /* @var $subCollection RouteCollection */
+ $subCollection->addPrefix($prefix);
+ if (null !== $host) {
+ $subCollection->setHost($host);
+ }
+ if (null !== $condition) {
+ $subCollection->setCondition($condition);
+ }
+ if (null !== $schemes) {
+ $subCollection->setSchemes($schemes);
+ }
+ if (null !== $methods) {
+ $subCollection->setMethods($methods);
+ }
+ $subCollection->addDefaults($defaults);
+ $subCollection->addRequirements($requirements);
+ $subCollection->addOptions($options);
+
+ $collection->addCollection($subCollection);
+ }
+ }
+
+ /**
+ * Loads an XML file.
+ *
+ * @param string $file An XML file path
+ *
+ * @return \DOMDocument
+ *
+ * @throws \InvalidArgumentException When loading of XML file fails because of syntax errors
+ * or when the XML structure is not as expected by the scheme -
+ * see validate()
+ */
+ protected function loadFile($file)
+ {
+ return XmlUtils::loadFile($file, __DIR__.static::SCHEME_PATH);
+ }
+
+ /**
+ * Parses the config elements (default, requirement, option).
+ *
+ * @param \DOMElement $node Element to parse that contains the configs
+ * @param string $path Full path of the XML file being processed
+ *
+ * @return array An array with the defaults as first item, requirements as second and options as third
+ *
+ * @throws \InvalidArgumentException When the XML is invalid
+ */
+ private function parseConfigs(\DOMElement $node, $path)
+ {
+ $defaults = array();
+ $requirements = array();
+ $options = array();
+ $condition = null;
+
+ foreach ($node->getElementsByTagNameNS(self::NAMESPACE_URI, '*') as $n) {
+ if ($node !== $n->parentNode) {
+ continue;
+ }
+
+ switch ($n->localName) {
+ case 'default':
+ if ($this->isElementValueNull($n)) {
+ $defaults[$n->getAttribute('key')] = null;
+ } else {
+ $defaults[$n->getAttribute('key')] = $this->parseDefaultsConfig($n, $path);
+ }
+
+ break;
+ case 'requirement':
+ $requirements[$n->getAttribute('key')] = trim($n->textContent);
+ break;
+ case 'option':
+ $options[$n->getAttribute('key')] = trim($n->textContent);
+ break;
+ case 'condition':
+ $condition = trim($n->textContent);
+ break;
+ default:
+ throw new \InvalidArgumentException(sprintf('Unknown tag "%s" used in file "%s". Expected "default", "requirement", "option" or "condition".', $n->localName, $path));
+ }
+ }
+
+ if ($controller = $node->getAttribute('controller')) {
+ if (isset($defaults['_controller'])) {
+ $name = $node->hasAttribute('id') ? sprintf('"%s"', $node->getAttribute('id')) : sprintf('the "%s" tag', $node->tagName);
+
+ throw new \InvalidArgumentException(sprintf('The routing file "%s" must not specify both the "controller" attribute and the defaults key "_controller" for %s.', $path, $name));
+ }
+
+ $defaults['_controller'] = $controller;
+ }
+
+ return array($defaults, $requirements, $options, $condition);
+ }
+
+ /**
+ * Parses the "default" elements.
+ *
+ * @param \DOMElement $element The "default" element to parse
+ * @param string $path Full path of the XML file being processed
+ *
+ * @return array|bool|float|int|string|null The parsed value of the "default" element
+ */
+ private function parseDefaultsConfig(\DOMElement $element, $path)
+ {
+ if ($this->isElementValueNull($element)) {
+ return;
+ }
+
+ // Check for existing element nodes in the default element. There can
+ // only be a single element inside a default element. So this element
+ // (if one was found) can safely be returned.
+ foreach ($element->childNodes as $child) {
+ if (!$child instanceof \DOMElement) {
+ continue;
+ }
+
+ if (self::NAMESPACE_URI !== $child->namespaceURI) {
+ continue;
+ }
+
+ return $this->parseDefaultNode($child, $path);
+ }
+
+ // If the default element doesn't contain a nested "bool", "int", "float",
+ // "string", "list", or "map" element, the element contents will be treated
+ // as the string value of the associated default option.
+ return trim($element->textContent);
+ }
+
+ /**
+ * Recursively parses the value of a "default" element.
+ *
+ * @param \DOMElement $node The node value
+ * @param string $path Full path of the XML file being processed
+ *
+ * @return array|bool|float|int|string The parsed value
+ *
+ * @throws \InvalidArgumentException when the XML is invalid
+ */
+ private function parseDefaultNode(\DOMElement $node, $path)
+ {
+ if ($this->isElementValueNull($node)) {
+ return;
+ }
+
+ switch ($node->localName) {
+ case 'bool':
+ return 'true' === trim($node->nodeValue) || '1' === trim($node->nodeValue);
+ case 'int':
+ return (int) trim($node->nodeValue);
+ case 'float':
+ return (float) trim($node->nodeValue);
+ case 'string':
+ return trim($node->nodeValue);
+ case 'list':
+ $list = array();
+
+ foreach ($node->childNodes as $element) {
+ if (!$element instanceof \DOMElement) {
+ continue;
+ }
+
+ if (self::NAMESPACE_URI !== $element->namespaceURI) {
+ continue;
+ }
+
+ $list[] = $this->parseDefaultNode($element, $path);
+ }
+
+ return $list;
+ case 'map':
+ $map = array();
+
+ foreach ($node->childNodes as $element) {
+ if (!$element instanceof \DOMElement) {
+ continue;
+ }
+
+ if (self::NAMESPACE_URI !== $element->namespaceURI) {
+ continue;
+ }
+
+ $map[$element->getAttribute('key')] = $this->parseDefaultNode($element, $path);
+ }
+
+ return $map;
+ default:
+ throw new \InvalidArgumentException(sprintf('Unknown tag "%s" used in file "%s". Expected "bool", "int", "float", "string", "list", or "map".', $node->localName, $path));
+ }
+ }
+
+ private function isElementValueNull(\DOMElement $element)
+ {
+ $namespaceUri = 'http://www.w3.org/2001/XMLSchema-instance';
+
+ if (!$element->hasAttributeNS($namespaceUri, 'nil')) {
+ return false;
+ }
+
+ return 'true' === $element->getAttributeNS($namespaceUri, 'nil') || '1' === $element->getAttributeNS($namespaceUri, 'nil');
+ }
+}
diff --git a/assets/php/vendor/symfony/routing/Loader/YamlFileLoader.php b/assets/php/vendor/symfony/routing/Loader/YamlFileLoader.php
new file mode 100644
index 0000000..f59f909
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Loader/YamlFileLoader.php
@@ -0,0 +1,233 @@
+<?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\Exception\ParseException;
+use Symfony\Component\Yaml\Parser as YamlParser;
+use Symfony\Component\Config\Loader\FileLoader;
+
+/**
+ * YamlFileLoader loads Yaml routing files.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ * @author Tobias Schultze <http://tobion.de>
+ */
+class YamlFileLoader extends FileLoader
+{
+ private static $availableKeys = array(
+ 'resource', 'type', 'prefix', 'path', 'host', 'schemes', 'methods', 'defaults', 'requirements', 'options', 'condition', 'controller',
+ );
+ private $yamlParser;
+
+ /**
+ * Loads a Yaml file.
+ *
+ * @param string $file A Yaml file path
+ * @param string|null $type The resource type
+ *
+ * @return RouteCollection A RouteCollection instance
+ *
+ * @throws \InvalidArgumentException When a route can't be parsed because YAML is invalid
+ */
+ public function load($file, $type = null)
+ {
+ $path = $this->locator->locate($file);
+
+ if (!stream_is_local($path)) {
+ throw new \InvalidArgumentException(sprintf('This is not a local file "%s".', $path));
+ }
+
+ if (!file_exists($path)) {
+ throw new \InvalidArgumentException(sprintf('File "%s" not found.', $path));
+ }
+
+ if (null === $this->yamlParser) {
+ $this->yamlParser = new YamlParser();
+ }
+
+ $prevErrorHandler = set_error_handler(function ($level, $message, $script, $line) use ($file, &$prevErrorHandler) {
+ $message = E_USER_DEPRECATED === $level ? preg_replace('/ on line \d+/', ' in "'.$file.'"$0', $message) : $message;
+
+ return $prevErrorHandler ? $prevErrorHandler($level, $message, $script, $line) : false;
+ });
+
+ try {
+ $parsedConfig = $this->yamlParser->parseFile($path);
+ } catch (ParseException $e) {
+ throw new \InvalidArgumentException(sprintf('The file "%s" does not contain valid YAML.', $path), 0, $e);
+ } finally {
+ restore_error_handler();
+ }
+
+ $collection = new RouteCollection();
+ $collection->addResource(new FileResource($path));
+
+ // empty file
+ if (null === $parsedConfig) {
+ return $collection;
+ }
+
+ // not an array
+ if (!is_array($parsedConfig)) {
+ throw new \InvalidArgumentException(sprintf('The file "%s" must contain a YAML array.', $path));
+ }
+
+ foreach ($parsedConfig as $name => $config) {
+ $this->validate($config, $name, $path);
+
+ if (isset($config['resource'])) {
+ $this->parseImport($collection, $config, $path, $file);
+ } else {
+ $this->parseRoute($collection, $name, $config, $path);
+ }
+ }
+
+ return $collection;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function supports($resource, $type = null)
+ {
+ return is_string($resource) && in_array(pathinfo($resource, PATHINFO_EXTENSION), array('yml', 'yaml'), true) && (!$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 $path Full path of the YAML file being processed
+ */
+ protected function parseRoute(RouteCollection $collection, $name, array $config, $path)
+ {
+ $defaults = isset($config['defaults']) ? $config['defaults'] : array();
+ $requirements = isset($config['requirements']) ? $config['requirements'] : array();
+ $options = isset($config['options']) ? $config['options'] : array();
+ $host = isset($config['host']) ? $config['host'] : '';
+ $schemes = isset($config['schemes']) ? $config['schemes'] : array();
+ $methods = isset($config['methods']) ? $config['methods'] : array();
+ $condition = isset($config['condition']) ? $config['condition'] : null;
+
+ if (isset($config['controller'])) {
+ $defaults['_controller'] = $config['controller'];
+ }
+
+ $route = new Route($config['path'], $defaults, $requirements, $options, $host, $schemes, $methods, $condition);
+
+ $collection->add($name, $route);
+ }
+
+ /**
+ * Parses an import and adds the routes in the resource to the RouteCollection.
+ *
+ * @param RouteCollection $collection A RouteCollection instance
+ * @param array $config Route definition
+ * @param string $path Full path of the YAML file being processed
+ * @param string $file Loaded file name
+ */
+ protected function parseImport(RouteCollection $collection, array $config, $path, $file)
+ {
+ $type = isset($config['type']) ? $config['type'] : null;
+ $prefix = isset($config['prefix']) ? $config['prefix'] : '';
+ $defaults = isset($config['defaults']) ? $config['defaults'] : array();
+ $requirements = isset($config['requirements']) ? $config['requirements'] : array();
+ $options = isset($config['options']) ? $config['options'] : array();
+ $host = isset($config['host']) ? $config['host'] : null;
+ $condition = isset($config['condition']) ? $config['condition'] : null;
+ $schemes = isset($config['schemes']) ? $config['schemes'] : null;
+ $methods = isset($config['methods']) ? $config['methods'] : null;
+
+ if (isset($config['controller'])) {
+ $defaults['_controller'] = $config['controller'];
+ }
+
+ $this->setCurrentDir(dirname($path));
+
+ $imported = $this->import($config['resource'], $type, false, $file);
+
+ if (!is_array($imported)) {
+ $imported = array($imported);
+ }
+
+ foreach ($imported as $subCollection) {
+ /* @var $subCollection RouteCollection */
+ $subCollection->addPrefix($prefix);
+ if (null !== $host) {
+ $subCollection->setHost($host);
+ }
+ if (null !== $condition) {
+ $subCollection->setCondition($condition);
+ }
+ if (null !== $schemes) {
+ $subCollection->setSchemes($schemes);
+ }
+ if (null !== $methods) {
+ $subCollection->setMethods($methods);
+ }
+ $subCollection->addDefaults($defaults);
+ $subCollection->addRequirements($requirements);
+ $subCollection->addOptions($options);
+
+ $collection->addCollection($subCollection);
+ }
+ }
+
+ /**
+ * Validates the route configuration.
+ *
+ * @param array $config A resource config
+ * @param string $name The config key
+ * @param string $path The loaded file path
+ *
+ * @throws \InvalidArgumentException If one of the provided config keys is not supported,
+ * something is missing or the combination is nonsense
+ */
+ protected function validate($config, $name, $path)
+ {
+ if (!is_array($config)) {
+ throw new \InvalidArgumentException(sprintf('The definition of "%s" in "%s" must be a YAML array.', $name, $path));
+ }
+ if ($extraKeys = array_diff(array_keys($config), self::$availableKeys)) {
+ throw new \InvalidArgumentException(sprintf(
+ 'The routing file "%s" contains unsupported keys for "%s": "%s". Expected one of: "%s".',
+ $path, $name, implode('", "', $extraKeys), implode('", "', self::$availableKeys)
+ ));
+ }
+ if (isset($config['resource']) && isset($config['path'])) {
+ throw new \InvalidArgumentException(sprintf(
+ 'The routing file "%s" must not specify both the "resource" key and the "path" key for "%s". Choose between an import and a route definition.',
+ $path, $name
+ ));
+ }
+ if (!isset($config['resource']) && isset($config['type'])) {
+ throw new \InvalidArgumentException(sprintf(
+ 'The "type" key for the route definition "%s" in "%s" is unsupported. It is only available for imports in combination with the "resource" key.',
+ $name, $path
+ ));
+ }
+ if (!isset($config['resource']) && !isset($config['path'])) {
+ throw new \InvalidArgumentException(sprintf(
+ 'You must define a "path" for the route "%s" in file "%s".',
+ $name, $path
+ ));
+ }
+ if (isset($config['controller']) && isset($config['defaults']['_controller'])) {
+ throw new \InvalidArgumentException(sprintf('The routing file "%s" must not specify both the "controller" key and the defaults key "_controller" for "%s".', $path, $name));
+ }
+ }
+}
diff --git a/assets/php/vendor/symfony/routing/Loader/schema/routing/routing-1.0.xsd b/assets/php/vendor/symfony/routing/Loader/schema/routing/routing-1.0.xsd
new file mode 100644
index 0000000..a97111a
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Loader/schema/routing/routing-1.0.xsd
@@ -0,0 +1,148 @@
+<?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:annotation>
+ <xsd:documentation><![CDATA[
+ Symfony XML Routing Schema, version 1.0
+ Authors: Fabien Potencier, Tobias Schultze
+
+ This scheme defines the elements and attributes that can be used to define
+ routes. A route maps an HTTP request to a set of configuration variables.
+ ]]></xsd:documentation>
+ </xsd:annotation>
+
+ <xsd:element name="routes" type="routes" />
+
+ <xsd:complexType name="routes">
+ <xsd:choice minOccurs="0" maxOccurs="unbounded">
+ <xsd:element name="import" type="import" />
+ <xsd:element name="route" type="route" />
+ </xsd:choice>
+ </xsd:complexType>
+
+ <xsd:group name="configs">
+ <xsd:choice>
+ <xsd:element name="default" nillable="true" type="default" />
+ <xsd:element name="requirement" type="element" />
+ <xsd:element name="option" type="element" />
+ <xsd:element name="condition" type="xsd:string" />
+ </xsd:choice>
+ </xsd:group>
+
+ <xsd:complexType name="route">
+ <xsd:group ref="configs" minOccurs="0" maxOccurs="unbounded" />
+
+ <xsd:attribute name="id" type="xsd:string" use="required" />
+ <xsd:attribute name="path" type="xsd:string" use="required" />
+ <xsd:attribute name="host" type="xsd:string" />
+ <xsd:attribute name="schemes" type="xsd:string" />
+ <xsd:attribute name="methods" type="xsd:string" />
+ <xsd:attribute name="controller" type="xsd:string" />
+ </xsd:complexType>
+
+ <xsd:complexType name="import">
+ <xsd:group ref="configs" minOccurs="0" maxOccurs="unbounded" />
+
+ <xsd:attribute name="resource" type="xsd:string" use="required" />
+ <xsd:attribute name="type" type="xsd:string" />
+ <xsd:attribute name="prefix" type="xsd:string" />
+ <xsd:attribute name="host" type="xsd:string" />
+ <xsd:attribute name="schemes" type="xsd:string" />
+ <xsd:attribute name="methods" type="xsd:string" />
+ <xsd:attribute name="controller" type="xsd:string" />
+ </xsd:complexType>
+
+ <xsd:complexType name="default" mixed="true">
+ <xsd:choice minOccurs="0" maxOccurs="1">
+ <xsd:element name="bool" type="xsd:boolean" />
+ <xsd:element name="int" type="xsd:integer" />
+ <xsd:element name="float" type="xsd:float" />
+ <xsd:element name="string" type="xsd:string" />
+ <xsd:element name="list" type="list" />
+ <xsd:element name="map" type="map" />
+ </xsd:choice>
+ <xsd:attribute name="key" type="xsd:string" use="required" />
+ </xsd:complexType>
+
+ <xsd:complexType name="element">
+ <xsd:simpleContent>
+ <xsd:extension base="xsd:string">
+ <xsd:attribute name="key" type="xsd:string" use="required" />
+ </xsd:extension>
+ </xsd:simpleContent>
+ </xsd:complexType>
+
+ <xsd:complexType name="list">
+ <xsd:choice minOccurs="0" maxOccurs="unbounded">
+ <xsd:element name="bool" nillable="true" type="xsd:boolean" />
+ <xsd:element name="int" nillable="true" type="xsd:integer" />
+ <xsd:element name="float" nillable="true" type="xsd:float" />
+ <xsd:element name="string" nillable="true" type="xsd:string" />
+ <xsd:element name="list" nillable="true" type="list" />
+ <xsd:element name="map" nillable="true" type="map" />
+ </xsd:choice>
+ </xsd:complexType>
+
+ <xsd:complexType name="map">
+ <xsd:choice minOccurs="0" maxOccurs="unbounded">
+ <xsd:element name="bool" nillable="true" type="map-bool-entry" />
+ <xsd:element name="int" nillable="true" type="map-int-entry" />
+ <xsd:element name="float" nillable="true" type="map-float-entry" />
+ <xsd:element name="string" nillable="true" type="map-string-entry" />
+ <xsd:element name="list" nillable="true" type="map-list-entry" />
+ <xsd:element name="map" nillable="true" type="map-map-entry" />
+ </xsd:choice>
+ </xsd:complexType>
+
+ <xsd:complexType name="map-bool-entry">
+ <xsd:simpleContent>
+ <xsd:extension base="xsd:boolean">
+ <xsd:attribute name="key" type="xsd:string" use="required" />
+ </xsd:extension>
+ </xsd:simpleContent>
+ </xsd:complexType>
+
+ <xsd:complexType name="map-int-entry">
+ <xsd:simpleContent>
+ <xsd:extension base="xsd:integer">
+ <xsd:attribute name="key" type="xsd:string" use="required" />
+ </xsd:extension>
+ </xsd:simpleContent>
+ </xsd:complexType>
+
+ <xsd:complexType name="map-float-entry">
+ <xsd:simpleContent>
+ <xsd:extension base="xsd:float">
+ <xsd:attribute name="key" type="xsd:string" use="required" />
+ </xsd:extension>
+ </xsd:simpleContent>
+ </xsd:complexType>
+
+ <xsd:complexType name="map-string-entry">
+ <xsd:simpleContent>
+ <xsd:extension base="xsd:string">
+ <xsd:attribute name="key" type="xsd:string" use="required" />
+ </xsd:extension>
+ </xsd:simpleContent>
+ </xsd:complexType>
+
+ <xsd:complexType name="map-list-entry">
+ <xsd:complexContent>
+ <xsd:extension base="list">
+ <xsd:attribute name="key" type="xsd:string" use="required" />
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+
+ <xsd:complexType name="map-map-entry">
+ <xsd:complexContent>
+ <xsd:extension base="map">
+ <xsd:attribute name="key" type="xsd:string" use="required" />
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+</xsd:schema>
diff --git a/assets/php/vendor/symfony/routing/Matcher/Dumper/DumperCollection.php b/assets/php/vendor/symfony/routing/Matcher/Dumper/DumperCollection.php
new file mode 100644
index 0000000..6916297
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Matcher/Dumper/DumperCollection.php
@@ -0,0 +1,159 @@
+<?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;
+
+/**
+ * Collection of routes.
+ *
+ * @author Arnaud Le Blanc <arnaud.lb@gmail.com>
+ *
+ * @internal
+ */
+class DumperCollection implements \IteratorAggregate
+{
+ /**
+ * @var DumperCollection|null
+ */
+ private $parent;
+
+ /**
+ * @var DumperCollection[]|DumperRoute[]
+ */
+ private $children = array();
+
+ /**
+ * @var array
+ */
+ private $attributes = array();
+
+ /**
+ * Returns the children routes and collections.
+ *
+ * @return self[]|DumperRoute[]
+ */
+ public function all()
+ {
+ return $this->children;
+ }
+
+ /**
+ * Adds a route or collection.
+ *
+ * @param DumperRoute|DumperCollection The route or collection
+ */
+ public function add($child)
+ {
+ if ($child instanceof self) {
+ $child->setParent($this);
+ }
+ $this->children[] = $child;
+ }
+
+ /**
+ * Sets children.
+ *
+ * @param array $children The children
+ */
+ public function setAll(array $children)
+ {
+ foreach ($children as $child) {
+ if ($child instanceof self) {
+ $child->setParent($this);
+ }
+ }
+ $this->children = $children;
+ }
+
+ /**
+ * Returns an iterator over the children.
+ *
+ * @return \Iterator|DumperCollection[]|DumperRoute[] The iterator
+ */
+ public function getIterator()
+ {
+ return new \ArrayIterator($this->children);
+ }
+
+ /**
+ * Returns the root of the collection.
+ *
+ * @return self The root collection
+ */
+ public function getRoot()
+ {
+ return (null !== $this->parent) ? $this->parent->getRoot() : $this;
+ }
+
+ /**
+ * Returns the parent collection.
+ *
+ * @return self|null The parent collection or null if the collection has no parent
+ */
+ protected function getParent()
+ {
+ return $this->parent;
+ }
+
+ /**
+ * Sets the parent collection.
+ */
+ protected function setParent(DumperCollection $parent)
+ {
+ $this->parent = $parent;
+ }
+
+ /**
+ * Returns true if the attribute is defined.
+ *
+ * @param string $name The attribute name
+ *
+ * @return bool true if the attribute is defined, false otherwise
+ */
+ public function hasAttribute($name)
+ {
+ return array_key_exists($name, $this->attributes);
+ }
+
+ /**
+ * Returns an attribute by name.
+ *
+ * @param string $name The attribute name
+ * @param mixed $default Default value is the attribute doesn't exist
+ *
+ * @return mixed The attribute value
+ */
+ public function getAttribute($name, $default = null)
+ {
+ return $this->hasAttribute($name) ? $this->attributes[$name] : $default;
+ }
+
+ /**
+ * Sets an attribute by name.
+ *
+ * @param string $name The attribute name
+ * @param mixed $value The attribute value
+ */
+ public function setAttribute($name, $value)
+ {
+ $this->attributes[$name] = $value;
+ }
+
+ /**
+ * Sets multiple attributes.
+ *
+ * @param array $attributes The attributes
+ */
+ public function setAttributes($attributes)
+ {
+ $this->attributes = $attributes;
+ }
+}
diff --git a/assets/php/vendor/symfony/routing/Matcher/Dumper/DumperRoute.php b/assets/php/vendor/symfony/routing/Matcher/Dumper/DumperRoute.php
new file mode 100644
index 0000000..c71989a
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Matcher/Dumper/DumperRoute.php
@@ -0,0 +1,57 @@
+<?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;
+
+/**
+ * Container for a Route.
+ *
+ * @author Arnaud Le Blanc <arnaud.lb@gmail.com>
+ *
+ * @internal
+ */
+class DumperRoute
+{
+ private $name;
+ private $route;
+
+ /**
+ * @param string $name The route name
+ * @param Route $route The route
+ */
+ public function __construct($name, Route $route)
+ {
+ $this->name = $name;
+ $this->route = $route;
+ }
+
+ /**
+ * Returns the route name.
+ *
+ * @return string The route name
+ */
+ public function getName()
+ {
+ return $this->name;
+ }
+
+ /**
+ * Returns the route.
+ *
+ * @return Route The route
+ */
+ public function getRoute()
+ {
+ return $this->route;
+ }
+}
diff --git a/assets/php/vendor/symfony/routing/Matcher/Dumper/MatcherDumper.php b/assets/php/vendor/symfony/routing/Matcher/Dumper/MatcherDumper.php
new file mode 100644
index 0000000..ea51ab4
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Matcher/Dumper/MatcherDumper.php
@@ -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\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;
+
+ public function __construct(RouteCollection $routes)
+ {
+ $this->routes = $routes;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getRoutes()
+ {
+ return $this->routes;
+ }
+}
diff --git a/assets/php/vendor/symfony/routing/Matcher/Dumper/MatcherDumperInterface.php b/assets/php/vendor/symfony/routing/Matcher/Dumper/MatcherDumperInterface.php
new file mode 100644
index 0000000..5e7c134
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Matcher/Dumper/MatcherDumperInterface.php
@@ -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\Matcher\Dumper;
+
+use Symfony\Component\Routing\RouteCollection;
+
+/**
+ * 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 string representation of executable code
+ * that can then be used to match a request against these routes.
+ *
+ * @param array $options An array of options
+ *
+ * @return string Executable code
+ */
+ public function dump(array $options = array());
+
+ /**
+ * Gets the routes to dump.
+ *
+ * @return RouteCollection A RouteCollection instance
+ */
+ public function getRoutes();
+}
diff --git a/assets/php/vendor/symfony/routing/Matcher/Dumper/PhpMatcherDumper.php b/assets/php/vendor/symfony/routing/Matcher/Dumper/PhpMatcherDumper.php
new file mode 100644
index 0000000..40d8df6
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Matcher/Dumper/PhpMatcherDumper.php
@@ -0,0 +1,429 @@
+<?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;
+use Symfony\Component\ExpressionLanguage\ExpressionLanguage;
+use Symfony\Component\ExpressionLanguage\ExpressionFunctionProviderInterface;
+
+/**
+ * PhpMatcherDumper creates a PHP class able to match URLs for a given set of routes.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ * @author Tobias Schultze <http://tobion.de>
+ * @author Arnaud Le Blanc <arnaud.lb@gmail.com>
+ */
+class PhpMatcherDumper extends MatcherDumper
+{
+ private $expressionLanguage;
+
+ /**
+ * @var ExpressionFunctionProviderInterface[]
+ */
+ private $expressionLanguageProviders = array();
+
+ /**
+ * 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_replace(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 <<<EOF
+<?php
+
+use Symfony\Component\Routing\Exception\MethodNotAllowedException;
+use Symfony\Component\Routing\Exception\ResourceNotFoundException;
+use Symfony\Component\Routing\RequestContext;
+
+/**
+ * This class has been auto-generated
+ * by the Symfony Routing Component.
+ */
+class {$options['class']} extends {$options['base_class']}
+{
+ public function __construct(RequestContext \$context)
+ {
+ \$this->context = \$context;
+ }
+
+{$this->generateMatchMethod($supportsRedirections)}
+}
+
+EOF;
+ }
+
+ public function addExpressionLanguageProvider(ExpressionFunctionProviderInterface $provider)
+ {
+ $this->expressionLanguageProviders[] = $provider;
+ }
+
+ /**
+ * Generates the code for the match method implementing UrlMatcherInterface.
+ *
+ * @param bool $supportsRedirections Whether redirections are supported by the base class
+ *
+ * @return string Match method as PHP code
+ */
+ private function generateMatchMethod($supportsRedirections)
+ {
+ $code = rtrim($this->compileRoutes($this->getRoutes(), $supportsRedirections), "\n");
+
+ return <<<EOF
+ public function match(\$rawPathinfo)
+ {
+ \$allow = array();
+ \$pathinfo = rawurldecode(\$rawPathinfo);
+ \$trimmedPathinfo = rtrim(\$pathinfo, '/');
+ \$context = \$this->context;
+ \$request = \$this->request ?: \$this->createRequest(\$pathinfo);
+ \$requestMethod = \$canonicalMethod = \$context->getMethod();
+
+ if ('HEAD' === \$requestMethod) {
+ \$canonicalMethod = 'GET';
+ }
+
+$code
+
+ throw 0 < count(\$allow) ? new MethodNotAllowedException(array_unique(\$allow)) : new ResourceNotFoundException();
+ }
+EOF;
+ }
+
+ /**
+ * Generates PHP code to match a RouteCollection with all its routes.
+ *
+ * @param RouteCollection $routes A RouteCollection instance
+ * @param bool $supportsRedirections Whether redirections are supported by the base class
+ *
+ * @return string PHP code
+ */
+ private function compileRoutes(RouteCollection $routes, $supportsRedirections)
+ {
+ $fetchedHost = false;
+ $groups = $this->groupRoutesByHostRegex($routes);
+ $code = '';
+
+ foreach ($groups as $collection) {
+ if (null !== $regex = $collection->getAttribute('host_regex')) {
+ if (!$fetchedHost) {
+ $code .= " \$host = \$context->getHost();\n\n";
+ $fetchedHost = true;
+ }
+
+ $code .= sprintf(" if (preg_match(%s, \$host, \$hostMatches)) {\n", var_export($regex, true));
+ }
+
+ $tree = $this->buildStaticPrefixCollection($collection);
+ $groupCode = $this->compileStaticPrefixRoutes($tree, $supportsRedirections);
+
+ if (null !== $regex) {
+ // apply extra indention at each line (except empty ones)
+ $groupCode = preg_replace('/^.{2,}$/m', ' $0', $groupCode);
+ $code .= $groupCode;
+ $code .= " }\n\n";
+ } else {
+ $code .= $groupCode;
+ }
+ }
+
+ // used to display the Welcome Page in apps that don't define a homepage
+ $code .= " if ('/' === \$pathinfo && !\$allow) {\n";
+ $code .= " throw new Symfony\Component\Routing\Exception\NoConfigurationException();\n";
+ $code .= " }\n";
+
+ return $code;
+ }
+
+ private function buildStaticPrefixCollection(DumperCollection $collection)
+ {
+ $prefixCollection = new StaticPrefixCollection();
+
+ foreach ($collection as $dumperRoute) {
+ $prefix = $dumperRoute->getRoute()->compile()->getStaticPrefix();
+ $prefixCollection->addRoute($prefix, $dumperRoute);
+ }
+
+ $prefixCollection->optimizeGroups();
+
+ return $prefixCollection;
+ }
+
+ /**
+ * Generates PHP code to match a tree of routes.
+ *
+ * @param StaticPrefixCollection $collection A StaticPrefixCollection instance
+ * @param bool $supportsRedirections Whether redirections are supported by the base class
+ * @param string $ifOrElseIf either "if" or "elseif" to influence chaining
+ *
+ * @return string PHP code
+ */
+ private function compileStaticPrefixRoutes(StaticPrefixCollection $collection, $supportsRedirections, $ifOrElseIf = 'if')
+ {
+ $code = '';
+ $prefix = $collection->getPrefix();
+
+ if (!empty($prefix) && '/' !== $prefix) {
+ $code .= sprintf(" %s (0 === strpos(\$pathinfo, %s)) {\n", $ifOrElseIf, var_export($prefix, true));
+ }
+
+ $ifOrElseIf = 'if';
+
+ foreach ($collection->getItems() as $route) {
+ if ($route instanceof StaticPrefixCollection) {
+ $code .= $this->compileStaticPrefixRoutes($route, $supportsRedirections, $ifOrElseIf);
+ $ifOrElseIf = 'elseif';
+ } else {
+ $code .= $this->compileRoute($route[1]->getRoute(), $route[1]->getName(), $supportsRedirections, $prefix)."\n";
+ $ifOrElseIf = 'if';
+ }
+ }
+
+ if (!empty($prefix) && '/' !== $prefix) {
+ $code .= " }\n\n";
+ // apply extra indention at each line (except empty ones)
+ $code = preg_replace('/^.{2,}$/m', ' $0', $code);
+ }
+
+ return $code;
+ }
+
+ /**
+ * Compiles a single Route to PHP code used to match it against the path info.
+ *
+ * @param Route $route A Route instance
+ * @param string $name The name of the Route
+ * @param bool $supportsRedirections Whether redirections are supported by the base class
+ * @param string|null $parentPrefix The prefix of the parent collection used to optimize the code
+ *
+ * @return string PHP code
+ *
+ * @throws \LogicException
+ */
+ private function compileRoute(Route $route, $name, $supportsRedirections, $parentPrefix = null)
+ {
+ $code = '';
+ $compiledRoute = $route->compile();
+ $conditions = array();
+ $hasTrailingSlash = false;
+ $matches = false;
+ $hostMatches = false;
+ $methods = $route->getMethods();
+
+ $supportsTrailingSlash = $supportsRedirections && (!$methods || in_array('GET', $methods));
+ $regex = $compiledRoute->getRegex();
+
+ if (!count($compiledRoute->getPathVariables()) && false !== preg_match('#^(.)\^(?P<url>.*?)\$\1#'.('u' === substr($regex, -1) ? 'u' : ''), $regex, $m)) {
+ if ($supportsTrailingSlash && '/' === substr($m['url'], -1)) {
+ $conditions[] = sprintf('%s === $trimmedPathinfo', var_export(rtrim(str_replace('\\', '', $m['url']), '/'), true));
+ $hasTrailingSlash = true;
+ } else {
+ $conditions[] = sprintf('%s === $pathinfo', 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));
+ }
+
+ if ($supportsTrailingSlash && $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;
+ }
+
+ if ($compiledRoute->getHostVariables()) {
+ $hostMatches = true;
+ }
+
+ if ($route->getCondition()) {
+ $conditions[] = $this->getExpressionLanguage()->compile($route->getCondition(), array('context', 'request'));
+ }
+
+ $conditions = implode(' && ', $conditions);
+
+ $code .= <<<EOF
+ // $name
+ if ($conditions) {
+
+EOF;
+
+ $gotoname = 'not_'.preg_replace('/[^A-Za-z0-9_]/', '', $name);
+
+ // the offset where the return value is appended below, with indendation
+ $retOffset = 12 + strlen($code);
+
+ // optimize parameters array
+ if ($matches || $hostMatches) {
+ $vars = array();
+ if ($hostMatches) {
+ $vars[] = '$hostMatches';
+ }
+ if ($matches) {
+ $vars[] = '$matches';
+ }
+ $vars[] = "array('_route' => '$name')";
+
+ $code .= sprintf(
+ " \$ret = \$this->mergeDefaults(array_replace(%s), %s);\n",
+ implode(', ', $vars),
+ str_replace("\n", '', var_export($route->getDefaults(), true))
+ );
+ } elseif ($route->getDefaults()) {
+ $code .= sprintf(" \$ret = %s;\n", str_replace("\n", '', var_export(array_replace($route->getDefaults(), array('_route' => $name)), true)));
+ } else {
+ $code .= sprintf(" \$ret = array('_route' => '%s');\n", $name);
+ }
+
+ if ($hasTrailingSlash) {
+ $code .= <<<EOF
+ if ('/' === substr(\$pathinfo, -1)) {
+ // no-op
+ } elseif ('GET' !== \$canonicalMethod) {
+ goto $gotoname;
+ } else {
+ return array_replace(\$ret, \$this->redirect(\$rawPathinfo.'/', '$name'));
+ }
+
+
+EOF;
+ }
+
+ if ($methods) {
+ $methodVariable = in_array('GET', $methods) ? '$canonicalMethod' : '$requestMethod';
+ $methods = implode("', '", $methods);
+ }
+
+ if ($schemes = $route->getSchemes()) {
+ if (!$supportsRedirections) {
+ throw new \LogicException('The "schemes" requirement is only supported for URL matchers that implement RedirectableUrlMatcherInterface.');
+ }
+ $schemes = str_replace("\n", '', var_export(array_flip($schemes), true));
+ if ($methods) {
+ $code .= <<<EOF
+ \$requiredSchemes = $schemes;
+ \$hasRequiredScheme = isset(\$requiredSchemes[\$context->getScheme()]);
+ if (!in_array($methodVariable, array('$methods'))) {
+ if (\$hasRequiredScheme) {
+ \$allow = array_merge(\$allow, array('$methods'));
+ }
+ goto $gotoname;
+ }
+ if (!\$hasRequiredScheme) {
+ if ('GET' !== \$canonicalMethod) {
+ goto $gotoname;
+ }
+
+ return array_replace(\$ret, \$this->redirect(\$rawPathinfo, '$name', key(\$requiredSchemes)));
+ }
+
+
+EOF;
+ } else {
+ $code .= <<<EOF
+ \$requiredSchemes = $schemes;
+ if (!isset(\$requiredSchemes[\$context->getScheme()])) {
+ if ('GET' !== \$canonicalMethod) {
+ goto $gotoname;
+ }
+
+ return array_replace(\$ret, \$this->redirect(\$rawPathinfo, '$name', key(\$requiredSchemes)));
+ }
+
+
+EOF;
+ }
+ } elseif ($methods) {
+ $code .= <<<EOF
+ if (!in_array($methodVariable, array('$methods'))) {
+ \$allow = array_merge(\$allow, array('$methods'));
+ goto $gotoname;
+ }
+
+
+EOF;
+ }
+
+ if ($hasTrailingSlash || $schemes || $methods) {
+ $code .= " return \$ret;\n";
+ } else {
+ $code = substr_replace($code, 'return', $retOffset, 6);
+ }
+ $code .= " }\n";
+
+ if ($hasTrailingSlash || $schemes || $methods) {
+ $code .= " $gotoname:\n";
+ }
+
+ return $code;
+ }
+
+ /**
+ * Groups consecutive routes having the same host regex.
+ *
+ * The result is a collection of collections of routes having the same host regex.
+ *
+ * @param RouteCollection $routes A flat RouteCollection
+ *
+ * @return DumperCollection A collection with routes grouped by host regex in sub-collections
+ */
+ private function groupRoutesByHostRegex(RouteCollection $routes)
+ {
+ $groups = new DumperCollection();
+ $currentGroup = new DumperCollection();
+ $currentGroup->setAttribute('host_regex', null);
+ $groups->add($currentGroup);
+
+ foreach ($routes as $name => $route) {
+ $hostRegex = $route->compile()->getHostRegex();
+ if ($currentGroup->getAttribute('host_regex') !== $hostRegex) {
+ $currentGroup = new DumperCollection();
+ $currentGroup->setAttribute('host_regex', $hostRegex);
+ $groups->add($currentGroup);
+ }
+ $currentGroup->add(new DumperRoute($name, $route));
+ }
+
+ return $groups;
+ }
+
+ private function getExpressionLanguage()
+ {
+ if (null === $this->expressionLanguage) {
+ if (!class_exists('Symfony\Component\ExpressionLanguage\ExpressionLanguage')) {
+ throw new \RuntimeException('Unable to use expressions as the Symfony ExpressionLanguage component is not installed.');
+ }
+ $this->expressionLanguage = new ExpressionLanguage(null, $this->expressionLanguageProviders);
+ }
+
+ return $this->expressionLanguage;
+ }
+}
diff --git a/assets/php/vendor/symfony/routing/Matcher/Dumper/StaticPrefixCollection.php b/assets/php/vendor/symfony/routing/Matcher/Dumper/StaticPrefixCollection.php
new file mode 100644
index 0000000..7365808
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Matcher/Dumper/StaticPrefixCollection.php
@@ -0,0 +1,238 @@
+<?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;
+
+/**
+ * Prefix tree of routes preserving routes order.
+ *
+ * @author Frank de Jonge <info@frankdejonge.nl>
+ *
+ * @internal
+ */
+class StaticPrefixCollection
+{
+ /**
+ * @var string
+ */
+ private $prefix;
+
+ /**
+ * @var array[]|StaticPrefixCollection[]
+ */
+ private $items = array();
+
+ /**
+ * @var int
+ */
+ private $matchStart = 0;
+
+ public function __construct($prefix = '')
+ {
+ $this->prefix = $prefix;
+ }
+
+ public function getPrefix()
+ {
+ return $this->prefix;
+ }
+
+ /**
+ * @return mixed[]|StaticPrefixCollection[]
+ */
+ public function getItems()
+ {
+ return $this->items;
+ }
+
+ /**
+ * Adds a route to a group.
+ *
+ * @param string $prefix
+ * @param mixed $route
+ */
+ public function addRoute($prefix, $route)
+ {
+ $prefix = '/' === $prefix ? $prefix : rtrim($prefix, '/');
+ $this->guardAgainstAddingNotAcceptedRoutes($prefix);
+
+ if ($this->prefix === $prefix) {
+ // When a prefix is exactly the same as the base we move up the match start position.
+ // This is needed because otherwise routes that come afterwards have higher precedence
+ // than a possible regular expression, which goes against the input order sorting.
+ $this->items[] = array($prefix, $route);
+ $this->matchStart = count($this->items);
+
+ return;
+ }
+
+ foreach ($this->items as $i => $item) {
+ if ($i < $this->matchStart) {
+ continue;
+ }
+
+ if ($item instanceof self && $item->accepts($prefix)) {
+ $item->addRoute($prefix, $route);
+
+ return;
+ }
+
+ $group = $this->groupWithItem($item, $prefix, $route);
+
+ if ($group instanceof self) {
+ $this->items[$i] = $group;
+
+ return;
+ }
+ }
+
+ // No optimised case was found, in this case we simple add the route for possible
+ // grouping when new routes are added.
+ $this->items[] = array($prefix, $route);
+ }
+
+ /**
+ * Tries to combine a route with another route or group.
+ *
+ * @param StaticPrefixCollection|array $item
+ * @param string $prefix
+ * @param mixed $route
+ *
+ * @return null|StaticPrefixCollection
+ */
+ private function groupWithItem($item, $prefix, $route)
+ {
+ $itemPrefix = $item instanceof self ? $item->prefix : $item[0];
+ $commonPrefix = $this->detectCommonPrefix($prefix, $itemPrefix);
+
+ if (!$commonPrefix) {
+ return;
+ }
+
+ $child = new self($commonPrefix);
+
+ if ($item instanceof self) {
+ $child->items = array($item);
+ } else {
+ $child->addRoute($item[0], $item[1]);
+ }
+
+ $child->addRoute($prefix, $route);
+
+ return $child;
+ }
+
+ /**
+ * Checks whether a prefix can be contained within the group.
+ *
+ * @param string $prefix
+ *
+ * @return bool Whether a prefix could belong in a given group
+ */
+ private function accepts($prefix)
+ {
+ return '' === $this->prefix || 0 === strpos($prefix, $this->prefix);
+ }
+
+ /**
+ * Detects whether there's a common prefix relative to the group prefix and returns it.
+ *
+ * @param string $prefix
+ * @param string $anotherPrefix
+ *
+ * @return false|string A common prefix, longer than the base/group prefix, or false when none available
+ */
+ private function detectCommonPrefix($prefix, $anotherPrefix)
+ {
+ $baseLength = strlen($this->prefix);
+ $commonLength = $baseLength;
+ $end = min(strlen($prefix), strlen($anotherPrefix));
+
+ for ($i = $baseLength; $i <= $end; ++$i) {
+ if (substr($prefix, 0, $i) !== substr($anotherPrefix, 0, $i)) {
+ break;
+ }
+
+ $commonLength = $i;
+ }
+
+ $commonPrefix = rtrim(substr($prefix, 0, $commonLength), '/');
+
+ if (strlen($commonPrefix) > $baseLength) {
+ return $commonPrefix;
+ }
+
+ return false;
+ }
+
+ /**
+ * Optimizes the tree by inlining items from groups with less than 3 items.
+ */
+ public function optimizeGroups()
+ {
+ $index = -1;
+
+ while (isset($this->items[++$index])) {
+ $item = $this->items[$index];
+
+ if ($item instanceof self) {
+ $item->optimizeGroups();
+
+ // When a group contains only two items there's no reason to optimize because at minimum
+ // the amount of prefix check is 2. In this case inline the group.
+ if ($item->shouldBeInlined()) {
+ array_splice($this->items, $index, 1, $item->items);
+
+ // Lower index to pass through the same index again after optimizing.
+ // The first item of the replacements might be a group needing optimization.
+ --$index;
+ }
+ }
+ }
+ }
+
+ private function shouldBeInlined()
+ {
+ if (count($this->items) >= 3) {
+ return false;
+ }
+
+ foreach ($this->items as $item) {
+ if ($item instanceof self) {
+ return true;
+ }
+ }
+
+ foreach ($this->items as $item) {
+ if (is_array($item) && $item[0] === $this->prefix) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ /**
+ * Guards against adding incompatible prefixes in a group.
+ *
+ * @param string $prefix
+ *
+ * @throws \LogicException when a prefix does not belong in a group
+ */
+ private function guardAgainstAddingNotAcceptedRoutes($prefix)
+ {
+ if (!$this->accepts($prefix)) {
+ $message = sprintf('Could not add route with prefix %s to collection with prefix %s', $prefix, $this->prefix);
+
+ throw new \LogicException($message);
+ }
+ }
+}
diff --git a/assets/php/vendor/symfony/routing/Matcher/RedirectableUrlMatcher.php b/assets/php/vendor/symfony/routing/Matcher/RedirectableUrlMatcher.php
new file mode 100644
index 0000000..3770a9c
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Matcher/RedirectableUrlMatcher.php
@@ -0,0 +1,65 @@
+<?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;
+use Symfony\Component\Routing\Route;
+
+/**
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+abstract class RedirectableUrlMatcher extends UrlMatcher implements RedirectableUrlMatcherInterface
+{
+ /**
+ * {@inheritdoc}
+ */
+ public function match($pathinfo)
+ {
+ try {
+ $parameters = parent::match($pathinfo);
+ } catch (ResourceNotFoundException $e) {
+ if ('/' === substr($pathinfo, -1) || !in_array($this->context->getMethod(), array('HEAD', 'GET'))) {
+ throw $e;
+ }
+
+ try {
+ $parameters = parent::match($pathinfo.'/');
+
+ return array_replace($parameters, $this->redirect($pathinfo.'/', isset($parameters['_route']) ? $parameters['_route'] : null));
+ } catch (ResourceNotFoundException $e2) {
+ throw $e;
+ }
+ }
+
+ return $parameters;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function handleRouteRequirements($pathinfo, $name, Route $route)
+ {
+ // expression condition
+ if ($route->getCondition() && !$this->getExpressionLanguage()->evaluate($route->getCondition(), array('context' => $this->context, 'request' => $this->request ?: $this->createRequest($pathinfo)))) {
+ return array(self::REQUIREMENT_MISMATCH, null);
+ }
+
+ // check HTTP scheme requirement
+ $scheme = $this->context->getScheme();
+ $schemes = $route->getSchemes();
+ if ($schemes && !$route->hasScheme($scheme)) {
+ return array(self::ROUTE_MATCH, $this->redirect($pathinfo, $name, current($schemes)));
+ }
+
+ return array(self::REQUIREMENT_MATCH, null);
+ }
+}
diff --git a/assets/php/vendor/symfony/routing/Matcher/RedirectableUrlMatcherInterface.php b/assets/php/vendor/symfony/routing/Matcher/RedirectableUrlMatcherInterface.php
new file mode 100644
index 0000000..7c27bc8
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Matcher/RedirectableUrlMatcherInterface.php
@@ -0,0 +1,31 @@
+<?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>
+ */
+interface RedirectableUrlMatcherInterface
+{
+ /**
+ * Redirects the user to another URL.
+ *
+ * @param string $path The path info to redirect to
+ * @param string $route The route name that matched
+ * @param string|null $scheme The URL scheme (null to keep the current one)
+ *
+ * @return array An array of parameters
+ */
+ public function redirect($path, $route, $scheme = null);
+}
diff --git a/assets/php/vendor/symfony/routing/Matcher/RequestMatcherInterface.php b/assets/php/vendor/symfony/routing/Matcher/RequestMatcherInterface.php
new file mode 100644
index 0000000..1eef778
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Matcher/RequestMatcherInterface.php
@@ -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\Matcher;
+
+use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\Routing\Exception\NoConfigurationException;
+use Symfony\Component\Routing\Exception\ResourceNotFoundException;
+use Symfony\Component\Routing\Exception\MethodNotAllowedException;
+
+/**
+ * RequestMatcherInterface is the interface that all request matcher classes must implement.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+interface RequestMatcherInterface
+{
+ /**
+ * Tries to match a request with a set of routes.
+ *
+ * If the matcher can not find information, it must throw one of the exceptions documented
+ * below.
+ *
+ * @return array An array of parameters
+ *
+ * @throws NoConfigurationException If no routing configuration could be found
+ * @throws ResourceNotFoundException If no matching resource could be found
+ * @throws MethodNotAllowedException If a matching resource was found but the request method is not allowed
+ */
+ public function matchRequest(Request $request);
+}
diff --git a/assets/php/vendor/symfony/routing/Matcher/TraceableUrlMatcher.php b/assets/php/vendor/symfony/routing/Matcher/TraceableUrlMatcher.php
new file mode 100644
index 0000000..9085be0
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Matcher/TraceableUrlMatcher.php
@@ -0,0 +1,141 @@
+<?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\HttpFoundation\Request;
+use Symfony\Component\Routing\Exception\ExceptionInterface;
+use Symfony\Component\Routing\Route;
+use Symfony\Component\Routing\RouteCollection;
+
+/**
+ * TraceableUrlMatcher helps debug path info matching by tracing the match.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+class TraceableUrlMatcher extends UrlMatcher
+{
+ const ROUTE_DOES_NOT_MATCH = 0;
+ const ROUTE_ALMOST_MATCHES = 1;
+ const ROUTE_MATCHES = 2;
+
+ protected $traces;
+
+ public function getTraces($pathinfo)
+ {
+ $this->traces = array();
+
+ try {
+ $this->match($pathinfo);
+ } catch (ExceptionInterface $e) {
+ }
+
+ return $this->traces;
+ }
+
+ public function getTracesForRequest(Request $request)
+ {
+ $this->request = $request;
+ $traces = $this->getTraces($request->getPathInfo());
+ $this->request = null;
+
+ return $traces;
+ }
+
+ protected function matchCollection($pathinfo, RouteCollection $routes)
+ {
+ foreach ($routes as $name => $route) {
+ $compiledRoute = $route->compile();
+
+ if (!preg_match($compiledRoute->getRegex(), $pathinfo, $matches)) {
+ // does it match without any requirements?
+ $r = new Route($route->getPath(), $route->getDefaults(), array(), $route->getOptions());
+ $cr = $r->compile();
+ if (!preg_match($cr->getRegex(), $pathinfo)) {
+ $this->addTrace(sprintf('Path "%s" does not match', $route->getPath()), self::ROUTE_DOES_NOT_MATCH, $name, $route);
+
+ continue;
+ }
+
+ foreach ($route->getRequirements() as $n => $regex) {
+ $r = new Route($route->getPath(), $route->getDefaults(), array($n => $regex), $route->getOptions());
+ $cr = $r->compile();
+
+ if (in_array($n, $cr->getVariables()) && !preg_match($cr->getRegex(), $pathinfo)) {
+ $this->addTrace(sprintf('Requirement for "%s" does not match (%s)', $n, $regex), self::ROUTE_ALMOST_MATCHES, $name, $route);
+
+ continue 2;
+ }
+ }
+
+ continue;
+ }
+
+ // check host requirement
+ $hostMatches = array();
+ if ($compiledRoute->getHostRegex() && !preg_match($compiledRoute->getHostRegex(), $this->context->getHost(), $hostMatches)) {
+ $this->addTrace(sprintf('Host "%s" does not match the requirement ("%s")', $this->context->getHost(), $route->getHost()), self::ROUTE_ALMOST_MATCHES, $name, $route);
+
+ continue;
+ }
+
+ // check HTTP method requirement
+ if ($requiredMethods = $route->getMethods()) {
+ // HEAD and GET are equivalent as per RFC
+ if ('HEAD' === $method = $this->context->getMethod()) {
+ $method = 'GET';
+ }
+
+ if (!in_array($method, $requiredMethods)) {
+ $this->allow = array_merge($this->allow, $requiredMethods);
+
+ $this->addTrace(sprintf('Method "%s" does not match any of the required methods (%s)', $this->context->getMethod(), implode(', ', $requiredMethods)), self::ROUTE_ALMOST_MATCHES, $name, $route);
+
+ continue;
+ }
+ }
+
+ // check condition
+ if ($condition = $route->getCondition()) {
+ if (!$this->getExpressionLanguage()->evaluate($condition, array('context' => $this->context, 'request' => $this->request ?: $this->createRequest($pathinfo)))) {
+ $this->addTrace(sprintf('Condition "%s" does not evaluate to "true"', $condition), self::ROUTE_ALMOST_MATCHES, $name, $route);
+
+ continue;
+ }
+ }
+
+ // check HTTP scheme requirement
+ if ($requiredSchemes = $route->getSchemes()) {
+ $scheme = $this->context->getScheme();
+
+ if (!$route->hasScheme($scheme)) {
+ $this->addTrace(sprintf('Scheme "%s" does not match any of the required schemes (%s); the user will be redirected to first required scheme', $scheme, implode(', ', $requiredSchemes)), self::ROUTE_ALMOST_MATCHES, $name, $route);
+
+ return true;
+ }
+ }
+
+ $this->addTrace('Route matches!', self::ROUTE_MATCHES, $name, $route);
+
+ return true;
+ }
+ }
+
+ private function addTrace($log, $level = self::ROUTE_DOES_NOT_MATCH, $name = null, $route = null)
+ {
+ $this->traces[] = array(
+ 'log' => $log,
+ 'name' => $name,
+ 'level' => $level,
+ 'path' => null !== $route ? $route->getPath() : null,
+ );
+ }
+}
diff --git a/assets/php/vendor/symfony/routing/Matcher/UrlMatcher.php b/assets/php/vendor/symfony/routing/Matcher/UrlMatcher.php
new file mode 100644
index 0000000..445cfc4
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Matcher/UrlMatcher.php
@@ -0,0 +1,252 @@
+<?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\NoConfigurationException;
+use Symfony\Component\Routing\Exception\ResourceNotFoundException;
+use Symfony\Component\Routing\RouteCollection;
+use Symfony\Component\Routing\RequestContext;
+use Symfony\Component\Routing\Route;
+use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\ExpressionLanguage\ExpressionLanguage;
+use Symfony\Component\ExpressionLanguage\ExpressionFunctionProviderInterface;
+
+/**
+ * UrlMatcher matches URL based on a set of routes.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+class UrlMatcher implements UrlMatcherInterface, RequestMatcherInterface
+{
+ const REQUIREMENT_MATCH = 0;
+ const REQUIREMENT_MISMATCH = 1;
+ const ROUTE_MATCH = 2;
+
+ protected $context;
+ protected $allow = array();
+ protected $routes;
+ protected $request;
+ protected $expressionLanguage;
+
+ /**
+ * @var ExpressionFunctionProviderInterface[]
+ */
+ protected $expressionLanguageProviders = array();
+
+ public function __construct(RouteCollection $routes, RequestContext $context)
+ {
+ $this->routes = $routes;
+ $this->context = $context;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setContext(RequestContext $context)
+ {
+ $this->context = $context;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getContext()
+ {
+ return $this->context;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function match($pathinfo)
+ {
+ $this->allow = array();
+
+ if ($ret = $this->matchCollection(rawurldecode($pathinfo), $this->routes)) {
+ return $ret;
+ }
+
+ if ('/' === $pathinfo && !$this->allow) {
+ throw new NoConfigurationException();
+ }
+
+ throw 0 < count($this->allow)
+ ? new MethodNotAllowedException(array_unique($this->allow))
+ : new ResourceNotFoundException(sprintf('No routes found for "%s".', $pathinfo));
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function matchRequest(Request $request)
+ {
+ $this->request = $request;
+
+ $ret = $this->match($request->getPathInfo());
+
+ $this->request = null;
+
+ return $ret;
+ }
+
+ public function addExpressionLanguageProvider(ExpressionFunctionProviderInterface $provider)
+ {
+ $this->expressionLanguageProviders[] = $provider;
+ }
+
+ /**
+ * Tries to match a URL with a set of routes.
+ *
+ * @param string $pathinfo The path info to be parsed
+ * @param RouteCollection $routes The set of routes
+ *
+ * @return array An array of parameters
+ *
+ * @throws NoConfigurationException If no routing configuration could be found
+ * @throws ResourceNotFoundException If the resource could not be found
+ * @throws MethodNotAllowedException If the resource was found but the request method is not allowed
+ */
+ protected function matchCollection($pathinfo, RouteCollection $routes)
+ {
+ foreach ($routes as $name => $route) {
+ $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;
+ }
+
+ $hostMatches = array();
+ if ($compiledRoute->getHostRegex() && !preg_match($compiledRoute->getHostRegex(), $this->context->getHost(), $hostMatches)) {
+ continue;
+ }
+
+ $status = $this->handleRouteRequirements($pathinfo, $name, $route);
+
+ if (self::REQUIREMENT_MISMATCH === $status[0]) {
+ continue;
+ }
+
+ // check HTTP method requirement
+ if ($requiredMethods = $route->getMethods()) {
+ // HEAD and GET are equivalent as per RFC
+ if ('HEAD' === $method = $this->context->getMethod()) {
+ $method = 'GET';
+ }
+
+ if (!in_array($method, $requiredMethods)) {
+ if (self::REQUIREMENT_MATCH === $status[0]) {
+ $this->allow = array_merge($this->allow, $requiredMethods);
+ }
+
+ continue;
+ }
+ }
+
+ return $this->getAttributes($route, $name, array_replace($matches, $hostMatches, isset($status[1]) ? $status[1] : array()));
+ }
+ }
+
+ /**
+ * Returns an array of values to use as request attributes.
+ *
+ * As this method requires the Route object, it is not available
+ * in matchers that do not have access to the matched Route instance
+ * (like the PHP and Apache matcher dumpers).
+ *
+ * @param Route $route The route we are matching against
+ * @param string $name The name of the route
+ * @param array $attributes An array of attributes from the matcher
+ *
+ * @return array An array of parameters
+ */
+ protected function getAttributes(Route $route, $name, array $attributes)
+ {
+ $attributes['_route'] = $name;
+
+ return $this->mergeDefaults($attributes, $route->getDefaults());
+ }
+
+ /**
+ * Handles specific route requirements.
+ *
+ * @param string $pathinfo The path
+ * @param string $name The route name
+ * @param Route $route The route
+ *
+ * @return array The first element represents the status, the second contains additional information
+ */
+ protected function handleRouteRequirements($pathinfo, $name, Route $route)
+ {
+ // expression condition
+ if ($route->getCondition() && !$this->getExpressionLanguage()->evaluate($route->getCondition(), array('context' => $this->context, 'request' => $this->request ?: $this->createRequest($pathinfo)))) {
+ return array(self::REQUIREMENT_MISMATCH, null);
+ }
+
+ // check HTTP scheme requirement
+ $scheme = $this->context->getScheme();
+ $status = $route->getSchemes() && !$route->hasScheme($scheme) ? self::REQUIREMENT_MISMATCH : self::REQUIREMENT_MATCH;
+
+ return array($status, null);
+ }
+
+ /**
+ * Get merged default parameters.
+ *
+ * @param array $params The parameters
+ * @param array $defaults The defaults
+ *
+ * @return array Merged default parameters
+ */
+ protected function mergeDefaults($params, $defaults)
+ {
+ foreach ($params as $key => $value) {
+ if (!is_int($key)) {
+ $defaults[$key] = $value;
+ }
+ }
+
+ return $defaults;
+ }
+
+ protected function getExpressionLanguage()
+ {
+ if (null === $this->expressionLanguage) {
+ if (!class_exists('Symfony\Component\ExpressionLanguage\ExpressionLanguage')) {
+ throw new \RuntimeException('Unable to use expressions as the Symfony ExpressionLanguage component is not installed.');
+ }
+ $this->expressionLanguage = new ExpressionLanguage(null, $this->expressionLanguageProviders);
+ }
+
+ return $this->expressionLanguage;
+ }
+
+ /**
+ * @internal
+ */
+ protected function createRequest($pathinfo)
+ {
+ if (!class_exists('Symfony\Component\HttpFoundation\Request')) {
+ return null;
+ }
+
+ return Request::create($this->context->getScheme().'://'.$this->context->getHost().$this->context->getBaseUrl().$pathinfo, $this->context->getMethod(), $this->context->getParameters(), array(), array(), array(
+ 'SCRIPT_FILENAME' => $this->context->getBaseUrl(),
+ 'SCRIPT_NAME' => $this->context->getBaseUrl(),
+ ));
+ }
+}
diff --git a/assets/php/vendor/symfony/routing/Matcher/UrlMatcherInterface.php b/assets/php/vendor/symfony/routing/Matcher/UrlMatcherInterface.php
new file mode 100644
index 0000000..2c7c313
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Matcher/UrlMatcherInterface.php
@@ -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;
+
+use Symfony\Component\Routing\Exception\NoConfigurationException;
+use Symfony\Component\Routing\RequestContextAwareInterface;
+use Symfony\Component\Routing\Exception\ResourceNotFoundException;
+use Symfony\Component\Routing\Exception\MethodNotAllowedException;
+
+/**
+ * UrlMatcherInterface is the interface that all URL matcher classes must implement.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+interface UrlMatcherInterface extends RequestContextAwareInterface
+{
+ /**
+ * Tries to match a URL path with a set of routes.
+ *
+ * If the matcher can not find information, it must throw one of the exceptions documented
+ * below.
+ *
+ * @param string $pathinfo The path info to be parsed (raw format, i.e. not urldecoded)
+ *
+ * @return array An array of parameters
+ *
+ * @throws NoConfigurationException If no routing configuration could be found
+ * @throws ResourceNotFoundException If the resource could not be found
+ * @throws MethodNotAllowedException If the resource was found but the request method is not allowed
+ */
+ public function match($pathinfo);
+}
diff --git a/assets/php/vendor/symfony/routing/README.md b/assets/php/vendor/symfony/routing/README.md
new file mode 100644
index 0000000..88fb1fd
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/README.md
@@ -0,0 +1,13 @@
+Routing Component
+=================
+
+The Routing component maps an HTTP request to a set of configuration variables.
+
+Resources
+---------
+
+ * [Documentation](https://symfony.com/doc/current/components/routing/index.html)
+ * [Contributing](https://symfony.com/doc/current/contributing/index.html)
+ * [Report issues](https://github.com/symfony/symfony/issues) and
+ [send Pull Requests](https://github.com/symfony/symfony/pulls)
+ in the [main Symfony repository](https://github.com/symfony/symfony)
diff --git a/assets/php/vendor/symfony/routing/RequestContext.php b/assets/php/vendor/symfony/routing/RequestContext.php
new file mode 100644
index 0000000..d62a776
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/RequestContext.php
@@ -0,0 +1,336 @@
+<?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\HttpFoundation\Request;
+
+/**
+ * Holds information about the current request.
+ *
+ * This class implements a fluent interface.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ * @author Tobias Schultze <http://tobion.de>
+ */
+class RequestContext
+{
+ private $baseUrl;
+ private $pathInfo;
+ private $method;
+ private $host;
+ private $scheme;
+ private $httpPort;
+ private $httpsPort;
+ private $queryString;
+ private $parameters = array();
+
+ /**
+ * @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 int $httpPort The HTTP port
+ * @param int $httpsPort The HTTPS port
+ * @param string $path The path
+ * @param string $queryString The query string
+ */
+ public function __construct($baseUrl = '', $method = 'GET', $host = 'localhost', $scheme = 'http', $httpPort = 80, $httpsPort = 443, $path = '/', $queryString = '')
+ {
+ $this->setBaseUrl($baseUrl);
+ $this->setMethod($method);
+ $this->setHost($host);
+ $this->setScheme($scheme);
+ $this->setHttpPort($httpPort);
+ $this->setHttpsPort($httpsPort);
+ $this->setPathInfo($path);
+ $this->setQueryString($queryString);
+ }
+
+ /**
+ * Updates the RequestContext information based on a HttpFoundation Request.
+ *
+ * @return $this
+ */
+ public function fromRequest(Request $request)
+ {
+ $this->setBaseUrl($request->getBaseUrl());
+ $this->setPathInfo($request->getPathInfo());
+ $this->setMethod($request->getMethod());
+ $this->setHost($request->getHost());
+ $this->setScheme($request->getScheme());
+ $this->setHttpPort($request->isSecure() ? $this->httpPort : $request->getPort());
+ $this->setHttpsPort($request->isSecure() ? $request->getPort() : $this->httpsPort);
+ $this->setQueryString($request->server->get('QUERY_STRING', ''));
+
+ return $this;
+ }
+
+ /**
+ * 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
+ *
+ * @return $this
+ */
+ public function setBaseUrl($baseUrl)
+ {
+ $this->baseUrl = $baseUrl;
+
+ return $this;
+ }
+
+ /**
+ * Gets the path info.
+ *
+ * @return string The path info
+ */
+ public function getPathInfo()
+ {
+ return $this->pathInfo;
+ }
+
+ /**
+ * Sets the path info.
+ *
+ * @param string $pathInfo The path info
+ *
+ * @return $this
+ */
+ public function setPathInfo($pathInfo)
+ {
+ $this->pathInfo = $pathInfo;
+
+ return $this;
+ }
+
+ /**
+ * 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
+ *
+ * @return $this
+ */
+ public function setMethod($method)
+ {
+ $this->method = strtoupper($method);
+
+ return $this;
+ }
+
+ /**
+ * Gets the HTTP host.
+ *
+ * The host is always lowercased because it must be treated case-insensitive.
+ *
+ * @return string The HTTP host
+ */
+ public function getHost()
+ {
+ return $this->host;
+ }
+
+ /**
+ * Sets the HTTP host.
+ *
+ * @param string $host The HTTP host
+ *
+ * @return $this
+ */
+ public function setHost($host)
+ {
+ $this->host = strtolower($host);
+
+ return $this;
+ }
+
+ /**
+ * 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
+ *
+ * @return $this
+ */
+ public function setScheme($scheme)
+ {
+ $this->scheme = strtolower($scheme);
+
+ return $this;
+ }
+
+ /**
+ * Gets the HTTP port.
+ *
+ * @return int The HTTP port
+ */
+ public function getHttpPort()
+ {
+ return $this->httpPort;
+ }
+
+ /**
+ * Sets the HTTP port.
+ *
+ * @param int $httpPort The HTTP port
+ *
+ * @return $this
+ */
+ public function setHttpPort($httpPort)
+ {
+ $this->httpPort = (int) $httpPort;
+
+ return $this;
+ }
+
+ /**
+ * Gets the HTTPS port.
+ *
+ * @return int The HTTPS port
+ */
+ public function getHttpsPort()
+ {
+ return $this->httpsPort;
+ }
+
+ /**
+ * Sets the HTTPS port.
+ *
+ * @param int $httpsPort The HTTPS port
+ *
+ * @return $this
+ */
+ public function setHttpsPort($httpsPort)
+ {
+ $this->httpsPort = (int) $httpsPort;
+
+ return $this;
+ }
+
+ /**
+ * Gets the query string.
+ *
+ * @return string The query string without the "?"
+ */
+ public function getQueryString()
+ {
+ return $this->queryString;
+ }
+
+ /**
+ * Sets the query string.
+ *
+ * @param string $queryString The query string (after "?")
+ *
+ * @return $this
+ */
+ public function setQueryString($queryString)
+ {
+ // string cast to be fault-tolerant, accepting null
+ $this->queryString = (string) $queryString;
+
+ return $this;
+ }
+
+ /**
+ * Returns the parameters.
+ *
+ * @return array The parameters
+ */
+ public function getParameters()
+ {
+ return $this->parameters;
+ }
+
+ /**
+ * Sets the parameters.
+ *
+ * @param array $parameters The parameters
+ *
+ * @return $this
+ */
+ 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 or null if nonexistent
+ */
+ 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 bool 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
+ *
+ * @return $this
+ */
+ public function setParameter($name, $parameter)
+ {
+ $this->parameters[$name] = $parameter;
+
+ return $this;
+ }
+}
diff --git a/assets/php/vendor/symfony/routing/RequestContextAwareInterface.php b/assets/php/vendor/symfony/routing/RequestContextAwareInterface.php
new file mode 100644
index 0000000..df5b9fc
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/RequestContextAwareInterface.php
@@ -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;
+
+interface RequestContextAwareInterface
+{
+ /**
+ * Sets the request context.
+ */
+ public function setContext(RequestContext $context);
+
+ /**
+ * Gets the request context.
+ *
+ * @return RequestContext The context
+ */
+ public function getContext();
+}
diff --git a/assets/php/vendor/symfony/routing/Route.php b/assets/php/vendor/symfony/routing/Route.php
new file mode 100644
index 0000000..cd50ac8
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Route.php
@@ -0,0 +1,558 @@
+<?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>
+ * @author Tobias Schultze <http://tobion.de>
+ */
+class Route implements \Serializable
+{
+ private $path = '/';
+ private $host = '';
+ private $schemes = array();
+ private $methods = array();
+ private $defaults = array();
+ private $requirements = array();
+ private $options = array();
+ private $condition = '';
+
+ /**
+ * @var null|CompiledRoute
+ */
+ private $compiled;
+
+ /**
+ * Constructor.
+ *
+ * Available options:
+ *
+ * * compiler_class: A class name able to compile this route instance (RouteCompiler by default)
+ * * utf8: Whether UTF-8 matching is enforced ot not
+ *
+ * @param string $path The path 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
+ * @param string $host The host pattern to match
+ * @param string|string[] $schemes A required URI scheme or an array of restricted schemes
+ * @param string|string[] $methods A required HTTP method or an array of restricted methods
+ * @param string $condition A condition that should evaluate to true for the route to match
+ */
+ public function __construct($path, array $defaults = array(), array $requirements = array(), array $options = array(), $host = '', $schemes = array(), $methods = array(), $condition = '')
+ {
+ $this->setPath($path);
+ $this->setDefaults($defaults);
+ $this->setRequirements($requirements);
+ $this->setOptions($options);
+ $this->setHost($host);
+ $this->setSchemes($schemes);
+ $this->setMethods($methods);
+ $this->setCondition($condition);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function serialize()
+ {
+ return serialize(array(
+ 'path' => $this->path,
+ 'host' => $this->host,
+ 'defaults' => $this->defaults,
+ 'requirements' => $this->requirements,
+ 'options' => $this->options,
+ 'schemes' => $this->schemes,
+ 'methods' => $this->methods,
+ 'condition' => $this->condition,
+ 'compiled' => $this->compiled,
+ ));
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function unserialize($serialized)
+ {
+ $data = unserialize($serialized);
+ $this->path = $data['path'];
+ $this->host = $data['host'];
+ $this->defaults = $data['defaults'];
+ $this->requirements = $data['requirements'];
+ $this->options = $data['options'];
+ $this->schemes = $data['schemes'];
+ $this->methods = $data['methods'];
+
+ if (isset($data['condition'])) {
+ $this->condition = $data['condition'];
+ }
+ if (isset($data['compiled'])) {
+ $this->compiled = $data['compiled'];
+ }
+ }
+
+ /**
+ * Returns the pattern for the path.
+ *
+ * @return string The path pattern
+ */
+ public function getPath()
+ {
+ return $this->path;
+ }
+
+ /**
+ * Sets the pattern for the path.
+ *
+ * This method implements a fluent interface.
+ *
+ * @param string $pattern The path pattern
+ *
+ * @return $this
+ */
+ public function setPath($pattern)
+ {
+ // A pattern must start with a slash and must not have multiple slashes at the beginning because the
+ // generated path for this route would be confused with a network path, e.g. '//domain.com/path'.
+ $this->path = '/'.ltrim(trim($pattern), '/');
+ $this->compiled = null;
+
+ return $this;
+ }
+
+ /**
+ * Returns the pattern for the host.
+ *
+ * @return string The host pattern
+ */
+ public function getHost()
+ {
+ return $this->host;
+ }
+
+ /**
+ * Sets the pattern for the host.
+ *
+ * This method implements a fluent interface.
+ *
+ * @param string $pattern The host pattern
+ *
+ * @return $this
+ */
+ public function setHost($pattern)
+ {
+ $this->host = (string) $pattern;
+ $this->compiled = null;
+
+ return $this;
+ }
+
+ /**
+ * Returns the lowercased schemes this route is restricted to.
+ * So an empty array means that any scheme is allowed.
+ *
+ * @return string[] The schemes
+ */
+ public function getSchemes()
+ {
+ return $this->schemes;
+ }
+
+ /**
+ * Sets the schemes (e.g. 'https') this route is restricted to.
+ * So an empty array means that any scheme is allowed.
+ *
+ * This method implements a fluent interface.
+ *
+ * @param string|string[] $schemes The scheme or an array of schemes
+ *
+ * @return $this
+ */
+ public function setSchemes($schemes)
+ {
+ $this->schemes = array_map('strtolower', (array) $schemes);
+ $this->compiled = null;
+
+ return $this;
+ }
+
+ /**
+ * Checks if a scheme requirement has been set.
+ *
+ * @param string $scheme
+ *
+ * @return bool true if the scheme requirement exists, otherwise false
+ */
+ public function hasScheme($scheme)
+ {
+ return in_array(strtolower($scheme), $this->schemes, true);
+ }
+
+ /**
+ * Returns the uppercased HTTP methods this route is restricted to.
+ * So an empty array means that any method is allowed.
+ *
+ * @return string[] The methods
+ */
+ public function getMethods()
+ {
+ return $this->methods;
+ }
+
+ /**
+ * Sets the HTTP methods (e.g. 'POST') this route is restricted to.
+ * So an empty array means that any method is allowed.
+ *
+ * This method implements a fluent interface.
+ *
+ * @param string|string[] $methods The method or an array of methods
+ *
+ * @return $this
+ */
+ public function setMethods($methods)
+ {
+ $this->methods = array_map('strtoupper', (array) $methods);
+ $this->compiled = null;
+
+ 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 $this
+ */
+ public function setOptions(array $options)
+ {
+ $this->options = array(
+ 'compiler_class' => 'Symfony\\Component\\Routing\\RouteCompiler',
+ );
+
+ return $this->addOptions($options);
+ }
+
+ /**
+ * Adds options.
+ *
+ * This method implements a fluent interface.
+ *
+ * @param array $options The options
+ *
+ * @return $this
+ */
+ public function addOptions(array $options)
+ {
+ foreach ($options as $name => $option) {
+ $this->options[$name] = $option;
+ }
+ $this->compiled = null;
+
+ 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 $this
+ */
+ public function setOption($name, $value)
+ {
+ $this->options[$name] = $value;
+ $this->compiled = null;
+
+ return $this;
+ }
+
+ /**
+ * Get an option value.
+ *
+ * @param string $name An option name
+ *
+ * @return mixed The option value or null when not given
+ */
+ public function getOption($name)
+ {
+ return isset($this->options[$name]) ? $this->options[$name] : null;
+ }
+
+ /**
+ * Checks if an option has been set.
+ *
+ * @param string $name An option name
+ *
+ * @return bool true if the option is set, false otherwise
+ */
+ public function hasOption($name)
+ {
+ return array_key_exists($name, $this->options);
+ }
+
+ /**
+ * 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 $this
+ */
+ public function setDefaults(array $defaults)
+ {
+ $this->defaults = array();
+
+ return $this->addDefaults($defaults);
+ }
+
+ /**
+ * Adds defaults.
+ *
+ * This method implements a fluent interface.
+ *
+ * @param array $defaults The defaults
+ *
+ * @return $this
+ */
+ public function addDefaults(array $defaults)
+ {
+ foreach ($defaults as $name => $default) {
+ $this->defaults[$name] = $default;
+ }
+ $this->compiled = null;
+
+ return $this;
+ }
+
+ /**
+ * Gets a default value.
+ *
+ * @param string $name A variable name
+ *
+ * @return mixed The default value or null when not given
+ */
+ 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 bool 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 $this
+ */
+ public function setDefault($name, $default)
+ {
+ $this->defaults[$name] = $default;
+ $this->compiled = null;
+
+ 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 $this
+ */
+ public function setRequirements(array $requirements)
+ {
+ $this->requirements = array();
+
+ return $this->addRequirements($requirements);
+ }
+
+ /**
+ * Adds requirements.
+ *
+ * This method implements a fluent interface.
+ *
+ * @param array $requirements The requirements
+ *
+ * @return $this
+ */
+ public function addRequirements(array $requirements)
+ {
+ foreach ($requirements as $key => $regex) {
+ $this->requirements[$key] = $this->sanitizeRequirement($key, $regex);
+ }
+ $this->compiled = null;
+
+ return $this;
+ }
+
+ /**
+ * Returns the requirement for the given key.
+ *
+ * @param string $key The key
+ *
+ * @return string|null The regex or null when not given
+ */
+ public function getRequirement($key)
+ {
+ return isset($this->requirements[$key]) ? $this->requirements[$key] : null;
+ }
+
+ /**
+ * Checks if a requirement is set for the given key.
+ *
+ * @param string $key A variable name
+ *
+ * @return bool true if a requirement is specified, false otherwise
+ */
+ public function hasRequirement($key)
+ {
+ return array_key_exists($key, $this->requirements);
+ }
+
+ /**
+ * Sets a requirement for the given key.
+ *
+ * @param string $key The key
+ * @param string $regex The regex
+ *
+ * @return $this
+ */
+ public function setRequirement($key, $regex)
+ {
+ $this->requirements[$key] = $this->sanitizeRequirement($key, $regex);
+ $this->compiled = null;
+
+ return $this;
+ }
+
+ /**
+ * Returns the condition.
+ *
+ * @return string The condition
+ */
+ public function getCondition()
+ {
+ return $this->condition;
+ }
+
+ /**
+ * Sets the condition.
+ *
+ * This method implements a fluent interface.
+ *
+ * @param string $condition The condition
+ *
+ * @return $this
+ */
+ public function setCondition($condition)
+ {
+ $this->condition = (string) $condition;
+ $this->compiled = null;
+
+ return $this;
+ }
+
+ /**
+ * Compiles the route.
+ *
+ * @return CompiledRoute A CompiledRoute instance
+ *
+ * @throws \LogicException If the Route cannot be compiled because the
+ * path or host pattern is invalid
+ *
+ * @see RouteCompiler which is responsible for the compilation process
+ */
+ public function compile()
+ {
+ if (null !== $this->compiled) {
+ return $this->compiled;
+ }
+
+ $class = $this->getOption('compiler_class');
+
+ return $this->compiled = $class::compile($this);
+ }
+
+ private function sanitizeRequirement($key, $regex)
+ {
+ if (!is_string($regex)) {
+ throw new \InvalidArgumentException(sprintf('Routing requirement for "%s" must be a string.', $key));
+ }
+
+ if ('' !== $regex && '^' === $regex[0]) {
+ $regex = (string) substr($regex, 1); // returns false for a single character
+ }
+
+ if ('$' === substr($regex, -1)) {
+ $regex = substr($regex, 0, -1);
+ }
+
+ if ('' === $regex) {
+ throw new \InvalidArgumentException(sprintf('Routing requirement for "%s" cannot be empty.', $key));
+ }
+
+ return $regex;
+ }
+}
diff --git a/assets/php/vendor/symfony/routing/RouteCollection.php b/assets/php/vendor/symfony/routing/RouteCollection.php
new file mode 100644
index 0000000..e22cbc5
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/RouteCollection.php
@@ -0,0 +1,280 @@
+<?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 at the end of the collection, an existing route
+ * with the same name is removed first. So there can only be one route
+ * with a given name.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ * @author Tobias Schultze <http://tobion.de>
+ */
+class RouteCollection implements \IteratorAggregate, \Countable
+{
+ /**
+ * @var Route[]
+ */
+ private $routes = array();
+
+ /**
+ * @var array
+ */
+ private $resources = array();
+
+ public function __clone()
+ {
+ foreach ($this->routes as $name => $route) {
+ $this->routes[$name] = clone $route;
+ }
+ }
+
+ /**
+ * Gets the current RouteCollection as an Iterator that includes all routes.
+ *
+ * It implements \IteratorAggregate.
+ *
+ * @see all()
+ *
+ * @return \ArrayIterator|Route[] An \ArrayIterator object for iterating over routes
+ */
+ public function getIterator()
+ {
+ return new \ArrayIterator($this->routes);
+ }
+
+ /**
+ * Gets the number of Routes in this collection.
+ *
+ * @return int The number of routes
+ */
+ public function count()
+ {
+ return count($this->routes);
+ }
+
+ /**
+ * Adds a route.
+ *
+ * @param string $name The route name
+ * @param Route $route A Route instance
+ */
+ public function add($name, Route $route)
+ {
+ unset($this->routes[$name]);
+
+ $this->routes[$name] = $route;
+ }
+
+ /**
+ * Returns all routes in this collection.
+ *
+ * @return Route[] An array of routes
+ */
+ public function all()
+ {
+ return $this->routes;
+ }
+
+ /**
+ * Gets a route by name.
+ *
+ * @param string $name The route name
+ *
+ * @return Route|null A Route instance or null when not found
+ */
+ public function get($name)
+ {
+ return isset($this->routes[$name]) ? $this->routes[$name] : null;
+ }
+
+ /**
+ * Removes a route or an array of routes by name from the collection.
+ *
+ * @param string|string[] $name The route name or an array of route names
+ */
+ public function remove($name)
+ {
+ foreach ((array) $name as $n) {
+ unset($this->routes[$n]);
+ }
+ }
+
+ /**
+ * Adds a route collection at the end of the current set by appending all
+ * routes of the added collection.
+ */
+ public function addCollection(self $collection)
+ {
+ // we need to remove all routes with the same names first because just replacing them
+ // would not place the new route at the end of the merged array
+ foreach ($collection->all() as $name => $route) {
+ unset($this->routes[$name]);
+ $this->routes[$name] = $route;
+ }
+
+ foreach ($collection->getResources() as $resource) {
+ $this->addResource($resource);
+ }
+ }
+
+ /**
+ * Adds a prefix to the path of all child routes.
+ *
+ * @param string $prefix An optional prefix to add before each pattern of the route collection
+ * @param array $defaults An array of default values
+ * @param array $requirements An array of requirements
+ */
+ public function addPrefix($prefix, array $defaults = array(), array $requirements = array())
+ {
+ $prefix = trim(trim($prefix), '/');
+
+ if ('' === $prefix) {
+ return;
+ }
+
+ foreach ($this->routes as $route) {
+ $route->setPath('/'.$prefix.$route->getPath());
+ $route->addDefaults($defaults);
+ $route->addRequirements($requirements);
+ }
+ }
+
+ /**
+ * Sets the host pattern on all routes.
+ *
+ * @param string $pattern The pattern
+ * @param array $defaults An array of default values
+ * @param array $requirements An array of requirements
+ */
+ public function setHost($pattern, array $defaults = array(), array $requirements = array())
+ {
+ foreach ($this->routes as $route) {
+ $route->setHost($pattern);
+ $route->addDefaults($defaults);
+ $route->addRequirements($requirements);
+ }
+ }
+
+ /**
+ * Sets a condition on all routes.
+ *
+ * Existing conditions will be overridden.
+ *
+ * @param string $condition The condition
+ */
+ public function setCondition($condition)
+ {
+ foreach ($this->routes as $route) {
+ $route->setCondition($condition);
+ }
+ }
+
+ /**
+ * Adds defaults to all routes.
+ *
+ * An existing default value under the same name in a route will be overridden.
+ *
+ * @param array $defaults An array of default values
+ */
+ public function addDefaults(array $defaults)
+ {
+ if ($defaults) {
+ foreach ($this->routes as $route) {
+ $route->addDefaults($defaults);
+ }
+ }
+ }
+
+ /**
+ * Adds requirements to all routes.
+ *
+ * An existing requirement under the same name in a route will be overridden.
+ *
+ * @param array $requirements An array of requirements
+ */
+ public function addRequirements(array $requirements)
+ {
+ if ($requirements) {
+ foreach ($this->routes as $route) {
+ $route->addRequirements($requirements);
+ }
+ }
+ }
+
+ /**
+ * Adds options to all routes.
+ *
+ * An existing option value under the same name in a route will be overridden.
+ *
+ * @param array $options An array of options
+ */
+ public function addOptions(array $options)
+ {
+ if ($options) {
+ foreach ($this->routes as $route) {
+ $route->addOptions($options);
+ }
+ }
+ }
+
+ /**
+ * Sets the schemes (e.g. 'https') all child routes are restricted to.
+ *
+ * @param string|string[] $schemes The scheme or an array of schemes
+ */
+ public function setSchemes($schemes)
+ {
+ foreach ($this->routes as $route) {
+ $route->setSchemes($schemes);
+ }
+ }
+
+ /**
+ * Sets the HTTP methods (e.g. 'POST') all child routes are restricted to.
+ *
+ * @param string|string[] $methods The method or an array of methods
+ */
+ public function setMethods($methods)
+ {
+ foreach ($this->routes as $route) {
+ $route->setMethods($methods);
+ }
+ }
+
+ /**
+ * Returns an array of resources loaded to build this collection.
+ *
+ * @return ResourceInterface[] An array of resources
+ */
+ public function getResources()
+ {
+ return array_values($this->resources);
+ }
+
+ /**
+ * Adds a resource for this collection. If the resource already exists
+ * it is not added.
+ */
+ public function addResource(ResourceInterface $resource)
+ {
+ $key = (string) $resource;
+
+ if (!isset($this->resources[$key])) {
+ $this->resources[$key] = $resource;
+ }
+ }
+}
diff --git a/assets/php/vendor/symfony/routing/RouteCollectionBuilder.php b/assets/php/vendor/symfony/routing/RouteCollectionBuilder.php
new file mode 100644
index 0000000..e8a9a16
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/RouteCollectionBuilder.php
@@ -0,0 +1,380 @@
+<?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\Exception\FileLoaderLoadException;
+use Symfony\Component\Config\Loader\LoaderInterface;
+use Symfony\Component\Config\Resource\ResourceInterface;
+
+/**
+ * Helps add and import routes into a RouteCollection.
+ *
+ * @author Ryan Weaver <ryan@knpuniversity.com>
+ */
+class RouteCollectionBuilder
+{
+ /**
+ * @var Route[]|RouteCollectionBuilder[]
+ */
+ private $routes = array();
+
+ private $loader;
+ private $defaults = array();
+ private $prefix;
+ private $host;
+ private $condition;
+ private $requirements = array();
+ private $options = array();
+ private $schemes;
+ private $methods;
+ private $resources = array();
+
+ public function __construct(LoaderInterface $loader = null)
+ {
+ $this->loader = $loader;
+ }
+
+ /**
+ * Import an external routing resource and returns the RouteCollectionBuilder.
+ *
+ * $routes->import('blog.yml', '/blog');
+ *
+ * @param mixed $resource
+ * @param string|null $prefix
+ * @param string $type
+ *
+ * @return self
+ *
+ * @throws FileLoaderLoadException
+ */
+ public function import($resource, $prefix = '/', $type = null)
+ {
+ /** @var RouteCollection[] $collection */
+ $collections = $this->load($resource, $type);
+
+ // create a builder from the RouteCollection
+ $builder = $this->createBuilder();
+
+ foreach ($collections as $collection) {
+ if (null === $collection) {
+ continue;
+ }
+
+ foreach ($collection->all() as $name => $route) {
+ $builder->addRoute($route, $name);
+ }
+
+ foreach ($collection->getResources() as $resource) {
+ $builder->addResource($resource);
+ }
+ }
+
+ // mount into this builder
+ $this->mount($prefix, $builder);
+
+ return $builder;
+ }
+
+ /**
+ * Adds a route and returns it for future modification.
+ *
+ * @param string $path The route path
+ * @param string $controller The route's controller
+ * @param string|null $name The name to give this route
+ *
+ * @return Route
+ */
+ public function add($path, $controller, $name = null)
+ {
+ $route = new Route($path);
+ $route->setDefault('_controller', $controller);
+ $this->addRoute($route, $name);
+
+ return $route;
+ }
+
+ /**
+ * Returns a RouteCollectionBuilder that can be configured and then added with mount().
+ *
+ * @return self
+ */
+ public function createBuilder()
+ {
+ return new self($this->loader);
+ }
+
+ /**
+ * Add a RouteCollectionBuilder.
+ *
+ * @param string $prefix
+ * @param RouteCollectionBuilder $builder
+ */
+ public function mount($prefix, RouteCollectionBuilder $builder)
+ {
+ $builder->prefix = trim(trim($prefix), '/');
+ $this->routes[] = $builder;
+ }
+
+ /**
+ * Adds a Route object to the builder.
+ *
+ * @param Route $route
+ * @param string|null $name
+ *
+ * @return $this
+ */
+ public function addRoute(Route $route, $name = null)
+ {
+ if (null === $name) {
+ // used as a flag to know which routes will need a name later
+ $name = '_unnamed_route_'.spl_object_hash($route);
+ }
+
+ $this->routes[$name] = $route;
+
+ return $this;
+ }
+
+ /**
+ * Sets the host on all embedded routes (unless already set).
+ *
+ * @param string $pattern
+ *
+ * @return $this
+ */
+ public function setHost($pattern)
+ {
+ $this->host = $pattern;
+
+ return $this;
+ }
+
+ /**
+ * Sets a condition on all embedded routes (unless already set).
+ *
+ * @param string $condition
+ *
+ * @return $this
+ */
+ public function setCondition($condition)
+ {
+ $this->condition = $condition;
+
+ return $this;
+ }
+
+ /**
+ * Sets a default value that will be added to all embedded routes (unless that
+ * default value is already set).
+ *
+ * @param string $key
+ * @param mixed $value
+ *
+ * @return $this
+ */
+ public function setDefault($key, $value)
+ {
+ $this->defaults[$key] = $value;
+
+ return $this;
+ }
+
+ /**
+ * Sets a requirement that will be added to all embedded routes (unless that
+ * requirement is already set).
+ *
+ * @param string $key
+ * @param mixed $regex
+ *
+ * @return $this
+ */
+ public function setRequirement($key, $regex)
+ {
+ $this->requirements[$key] = $regex;
+
+ return $this;
+ }
+
+ /**
+ * Sets an option that will be added to all embedded routes (unless that
+ * option is already set).
+ *
+ * @param string $key
+ * @param mixed $value
+ *
+ * @return $this
+ */
+ public function setOption($key, $value)
+ {
+ $this->options[$key] = $value;
+
+ return $this;
+ }
+
+ /**
+ * Sets the schemes on all embedded routes (unless already set).
+ *
+ * @param array|string $schemes
+ *
+ * @return $this
+ */
+ public function setSchemes($schemes)
+ {
+ $this->schemes = $schemes;
+
+ return $this;
+ }
+
+ /**
+ * Sets the methods on all embedded routes (unless already set).
+ *
+ * @param array|string $methods
+ *
+ * @return $this
+ */
+ public function setMethods($methods)
+ {
+ $this->methods = $methods;
+
+ return $this;
+ }
+
+ /**
+ * Adds a resource for this collection.
+ *
+ * @param ResourceInterface $resource
+ *
+ * @return $this
+ */
+ private function addResource(ResourceInterface $resource)
+ {
+ $this->resources[] = $resource;
+
+ return $this;
+ }
+
+ /**
+ * Creates the final RouteCollection and returns it.
+ *
+ * @return RouteCollection
+ */
+ public function build()
+ {
+ $routeCollection = new RouteCollection();
+
+ foreach ($this->routes as $name => $route) {
+ if ($route instanceof Route) {
+ $route->setDefaults(array_merge($this->defaults, $route->getDefaults()));
+ $route->setOptions(array_merge($this->options, $route->getOptions()));
+
+ foreach ($this->requirements as $key => $val) {
+ if (!$route->hasRequirement($key)) {
+ $route->setRequirement($key, $val);
+ }
+ }
+
+ if (null !== $this->prefix) {
+ $route->setPath('/'.$this->prefix.$route->getPath());
+ }
+
+ if (!$route->getHost()) {
+ $route->setHost($this->host);
+ }
+
+ if (!$route->getCondition()) {
+ $route->setCondition($this->condition);
+ }
+
+ if (!$route->getSchemes()) {
+ $route->setSchemes($this->schemes);
+ }
+
+ if (!$route->getMethods()) {
+ $route->setMethods($this->methods);
+ }
+
+ // auto-generate the route name if it's been marked
+ if ('_unnamed_route_' === substr($name, 0, 15)) {
+ $name = $this->generateRouteName($route);
+ }
+
+ $routeCollection->add($name, $route);
+ } else {
+ /* @var self $route */
+ $subCollection = $route->build();
+ $subCollection->addPrefix($this->prefix);
+
+ $routeCollection->addCollection($subCollection);
+ }
+ }
+
+ foreach ($this->resources as $resource) {
+ $routeCollection->addResource($resource);
+ }
+
+ return $routeCollection;
+ }
+
+ /**
+ * Generates a route name based on details of this route.
+ *
+ * @return string
+ */
+ private function generateRouteName(Route $route)
+ {
+ $methods = implode('_', $route->getMethods()).'_';
+
+ $routeName = $methods.$route->getPath();
+ $routeName = str_replace(array('/', ':', '|', '-'), '_', $routeName);
+ $routeName = preg_replace('/[^a-z0-9A-Z_.]+/', '', $routeName);
+
+ // Collapse consecutive underscores down into a single underscore.
+ $routeName = preg_replace('/_+/', '_', $routeName);
+
+ return $routeName;
+ }
+
+ /**
+ * Finds a loader able to load an imported resource and loads it.
+ *
+ * @param mixed $resource A resource
+ * @param string|null $type The resource type or null if unknown
+ *
+ * @return RouteCollection[]
+ *
+ * @throws FileLoaderLoadException If no loader is found
+ */
+ private function load($resource, $type = null)
+ {
+ if (null === $this->loader) {
+ throw new \BadMethodCallException('Cannot import other routing resources: you must pass a LoaderInterface when constructing RouteCollectionBuilder.');
+ }
+
+ if ($this->loader->supports($resource, $type)) {
+ $collections = $this->loader->load($resource, $type);
+
+ return is_array($collections) ? $collections : array($collections);
+ }
+
+ if (null === $resolver = $this->loader->getResolver()) {
+ throw new FileLoaderLoadException($resource, null, null, null, $type);
+ }
+
+ if (false === $loader = $resolver->resolve($resource, $type)) {
+ throw new FileLoaderLoadException($resource, null, null, null, $type);
+ }
+
+ $collections = $loader->load($resource, $type);
+
+ return is_array($collections) ? $collections : array($collections);
+ }
+}
diff --git a/assets/php/vendor/symfony/routing/RouteCompiler.php b/assets/php/vendor/symfony/routing/RouteCompiler.php
new file mode 100644
index 0000000..dc4e4f8
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/RouteCompiler.php
@@ -0,0 +1,316 @@
+<?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>
+ * @author Tobias Schultze <http://tobion.de>
+ */
+class RouteCompiler implements RouteCompilerInterface
+{
+ const REGEX_DELIMITER = '#';
+
+ /**
+ * This string defines the characters that are automatically considered separators in front of
+ * optional placeholders (with default and no static text following). Such a single separator
+ * can be left out together with the optional placeholder from matching and generating URLs.
+ */
+ const SEPARATORS = '/,;.:-_~+*=@|';
+
+ /**
+ * The maximum supported length of a PCRE subpattern name
+ * http://pcre.org/current/doc/html/pcre2pattern.html#SEC16.
+ *
+ * @internal
+ */
+ const VARIABLE_MAXIMUM_LENGTH = 32;
+
+ /**
+ * {@inheritdoc}
+ *
+ * @throws \InvalidArgumentException if a path variable is named _fragment
+ * @throws \LogicException if a variable is referenced more than once
+ * @throws \DomainException if a variable name starts with a digit or if it is too long to be successfully used as
+ * a PCRE subpattern
+ */
+ public static function compile(Route $route)
+ {
+ $hostVariables = array();
+ $variables = array();
+ $hostRegex = null;
+ $hostTokens = array();
+
+ if ('' !== $host = $route->getHost()) {
+ $result = self::compilePattern($route, $host, true);
+
+ $hostVariables = $result['variables'];
+ $variables = $hostVariables;
+
+ $hostTokens = $result['tokens'];
+ $hostRegex = $result['regex'];
+ }
+
+ $path = $route->getPath();
+
+ $result = self::compilePattern($route, $path, false);
+
+ $staticPrefix = $result['staticPrefix'];
+
+ $pathVariables = $result['variables'];
+
+ foreach ($pathVariables as $pathParam) {
+ if ('_fragment' === $pathParam) {
+ throw new \InvalidArgumentException(sprintf('Route pattern "%s" cannot contain "_fragment" as a path parameter.', $route->getPath()));
+ }
+ }
+
+ $variables = array_merge($variables, $pathVariables);
+
+ $tokens = $result['tokens'];
+ $regex = $result['regex'];
+
+ return new CompiledRoute(
+ $staticPrefix,
+ $regex,
+ $tokens,
+ $pathVariables,
+ $hostRegex,
+ $hostTokens,
+ $hostVariables,
+ array_unique($variables)
+ );
+ }
+
+ private static function compilePattern(Route $route, $pattern, $isHost)
+ {
+ $tokens = array();
+ $variables = array();
+ $matches = array();
+ $pos = 0;
+ $defaultSeparator = $isHost ? '.' : '/';
+ $useUtf8 = preg_match('//u', $pattern);
+ $needsUtf8 = $route->getOption('utf8');
+
+ if (!$needsUtf8 && $useUtf8 && preg_match('/[\x80-\xFF]/', $pattern)) {
+ $needsUtf8 = true;
+ @trigger_error(sprintf('Using UTF-8 route patterns without setting the "utf8" option is deprecated since Symfony 3.2 and will throw a LogicException in 4.0. Turn on the "utf8" route option for pattern "%s".', $pattern), E_USER_DEPRECATED);
+ }
+ if (!$useUtf8 && $needsUtf8) {
+ throw new \LogicException(sprintf('Cannot mix UTF-8 requirements with non-UTF-8 pattern "%s".', $pattern));
+ }
+
+ // Match all variables enclosed in "{}" and iterate over them. But we only want to match the innermost variable
+ // in case of nested "{}", e.g. {foo{bar}}. This in ensured because \w does not match "{" or "}" itself.
+ preg_match_all('#\{\w+\}#', $pattern, $matches, PREG_OFFSET_CAPTURE | PREG_SET_ORDER);
+ foreach ($matches as $match) {
+ $varName = substr($match[0][0], 1, -1);
+ // get all static text preceding the current variable
+ $precedingText = substr($pattern, $pos, $match[0][1] - $pos);
+ $pos = $match[0][1] + strlen($match[0][0]);
+
+ if (!strlen($precedingText)) {
+ $precedingChar = '';
+ } elseif ($useUtf8) {
+ preg_match('/.$/u', $precedingText, $precedingChar);
+ $precedingChar = $precedingChar[0];
+ } else {
+ $precedingChar = substr($precedingText, -1);
+ }
+ $isSeparator = '' !== $precedingChar && false !== strpos(static::SEPARATORS, $precedingChar);
+
+ // A PCRE subpattern name must start with a non-digit. Also a PHP variable cannot start with a digit so the
+ // variable would not be usable as a Controller action argument.
+ if (preg_match('/^\d/', $varName)) {
+ throw new \DomainException(sprintf('Variable name "%s" cannot start with a digit in route pattern "%s". Please use a different name.', $varName, $pattern));
+ }
+ if (in_array($varName, $variables)) {
+ throw new \LogicException(sprintf('Route pattern "%s" cannot reference variable name "%s" more than once.', $pattern, $varName));
+ }
+
+ if (strlen($varName) > self::VARIABLE_MAXIMUM_LENGTH) {
+ throw new \DomainException(sprintf('Variable name "%s" cannot be longer than %s characters in route pattern "%s". Please use a shorter name.', $varName, self::VARIABLE_MAXIMUM_LENGTH, $pattern));
+ }
+
+ if ($isSeparator && $precedingText !== $precedingChar) {
+ $tokens[] = array('text', substr($precedingText, 0, -strlen($precedingChar)));
+ } elseif (!$isSeparator && strlen($precedingText) > 0) {
+ $tokens[] = array('text', $precedingText);
+ }
+
+ $regexp = $route->getRequirement($varName);
+ if (null === $regexp) {
+ $followingPattern = (string) substr($pattern, $pos);
+ // Find the next static character after the variable that functions as a separator. By default, this separator and '/'
+ // are disallowed for the variable. This default requirement makes sure that optional variables can be matched at all
+ // and that the generating-matching-combination of URLs unambiguous, i.e. the params used for generating the URL are
+ // the same that will be matched. Example: new Route('/{page}.{_format}', array('_format' => 'html'))
+ // If {page} would also match the separating dot, {_format} would never match as {page} will eagerly consume everything.
+ // Also even if {_format} was not optional the requirement prevents that {page} matches something that was originally
+ // part of {_format} when generating the URL, e.g. _format = 'mobile.html'.
+ $nextSeparator = self::findNextSeparator($followingPattern, $useUtf8);
+ $regexp = sprintf(
+ '[^%s%s]+',
+ preg_quote($defaultSeparator, self::REGEX_DELIMITER),
+ $defaultSeparator !== $nextSeparator && '' !== $nextSeparator ? preg_quote($nextSeparator, self::REGEX_DELIMITER) : ''
+ );
+ if (('' !== $nextSeparator && !preg_match('#^\{\w+\}#', $followingPattern)) || '' === $followingPattern) {
+ // When we have a separator, which is disallowed for the variable, we can optimize the regex with a possessive
+ // quantifier. This prevents useless backtracking of PCRE and improves performance by 20% for matching those patterns.
+ // Given the above example, there is no point in backtracking into {page} (that forbids the dot) when a dot must follow
+ // after it. This optimization cannot be applied when the next char is no real separator or when the next variable is
+ // directly adjacent, e.g. '/{x}{y}'.
+ $regexp .= '+';
+ }
+ } else {
+ if (!preg_match('//u', $regexp)) {
+ $useUtf8 = false;
+ } elseif (!$needsUtf8 && preg_match('/[\x80-\xFF]|(?<!\\\\)\\\\(?:\\\\\\\\)*+(?-i:X|[pP][\{CLMNPSZ]|x\{[A-Fa-f0-9]{3})/', $regexp)) {
+ $needsUtf8 = true;
+ @trigger_error(sprintf('Using UTF-8 route requirements without setting the "utf8" option is deprecated since Symfony 3.2 and will throw a LogicException in 4.0. Turn on the "utf8" route option for variable "%s" in pattern "%s".', $varName, $pattern), E_USER_DEPRECATED);
+ }
+ if (!$useUtf8 && $needsUtf8) {
+ throw new \LogicException(sprintf('Cannot mix UTF-8 requirement with non-UTF-8 charset for variable "%s" in pattern "%s".', $varName, $pattern));
+ }
+ }
+
+ $tokens[] = array('variable', $isSeparator ? $precedingChar : '', $regexp, $varName);
+ $variables[] = $varName;
+ }
+
+ if ($pos < strlen($pattern)) {
+ $tokens[] = array('text', substr($pattern, $pos));
+ }
+
+ // find the first optional token
+ $firstOptional = PHP_INT_MAX;
+ if (!$isHost) {
+ 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 .= self::computeRegexp($tokens, $i, $firstOptional);
+ }
+ $regexp = self::REGEX_DELIMITER.'^'.$regexp.'$'.self::REGEX_DELIMITER.'sD'.($isHost ? 'i' : '');
+
+ // enable Utf8 matching if really required
+ if ($needsUtf8) {
+ $regexp .= 'u';
+ for ($i = 0, $nbToken = count($tokens); $i < $nbToken; ++$i) {
+ if ('variable' === $tokens[$i][0]) {
+ $tokens[$i][] = true;
+ }
+ }
+ }
+
+ return array(
+ 'staticPrefix' => self::determineStaticPrefix($route, $tokens),
+ 'regex' => $regexp,
+ 'tokens' => array_reverse($tokens),
+ 'variables' => $variables,
+ );
+ }
+
+ /**
+ * Determines the longest static prefix possible for a route.
+ *
+ * @return string The leading static part of a route's path
+ */
+ private static function determineStaticPrefix(Route $route, array $tokens)
+ {
+ if ('text' !== $tokens[0][0]) {
+ return ($route->hasDefault($tokens[0][3]) || '/' === $tokens[0][1]) ? '' : $tokens[0][1];
+ }
+
+ $prefix = $tokens[0][1];
+
+ if (isset($tokens[1][1]) && '/' !== $tokens[1][1] && false === $route->hasDefault($tokens[1][3])) {
+ $prefix .= $tokens[1][1];
+ }
+
+ return $prefix;
+ }
+
+ /**
+ * Returns the next static character in the Route pattern that will serve as a separator.
+ *
+ * @param string $pattern The route pattern
+ * @param bool $useUtf8 Whether the character is encoded in UTF-8 or not
+ *
+ * @return string The next static character that functions as separator (or empty string when none available)
+ */
+ private static function findNextSeparator($pattern, $useUtf8)
+ {
+ if ('' == $pattern) {
+ // return empty string if pattern is empty or false (false which can be returned by substr)
+ return '';
+ }
+ // first remove all placeholders from the pattern so we can find the next real static character
+ if ('' === $pattern = preg_replace('#\{\w+\}#', '', $pattern)) {
+ return '';
+ }
+ if ($useUtf8) {
+ preg_match('/^./u', $pattern, $pattern);
+ }
+
+ return false !== strpos(static::SEPARATORS, $pattern[0]) ? $pattern[0] : '';
+ }
+
+ /**
+ * Computes the regexp used to match a specific token. It can be static text or a subpattern.
+ *
+ * @param array $tokens The route tokens
+ * @param int $index The index of the current token
+ * @param int $firstOptional The index of the first optional token
+ *
+ * @return string The regexp pattern for a single token
+ */
+ private static function computeRegexp(array $tokens, $index, $firstOptional)
+ {
+ $token = $tokens[$index];
+ if ('text' === $token[0]) {
+ // Text tokens
+ return preg_quote($token[1], self::REGEX_DELIMITER);
+ } else {
+ // Variable tokens
+ if (0 === $index && 0 === $firstOptional) {
+ // When the only token is an optional variable token, the separator is required
+ return sprintf('%s(?P<%s>%s)?', preg_quote($token[1], self::REGEX_DELIMITER), $token[3], $token[2]);
+ } else {
+ $regexp = sprintf('%s(?P<%s>%s)', preg_quote($token[1], self::REGEX_DELIMITER), $token[3], $token[2]);
+ if ($index >= $firstOptional) {
+ // Enclose each optional token in a subpattern to make it optional.
+ // "?:" means it is non-capturing, i.e. the portion of the subject string that
+ // matched the optional subpattern is not passed back.
+ $regexp = "(?:$regexp";
+ $nbTokens = count($tokens);
+ if ($nbTokens - 1 == $index) {
+ // Close the optional subpatterns
+ $regexp .= str_repeat(')?', $nbTokens - $firstOptional - (0 === $firstOptional ? 1 : 0));
+ }
+ }
+
+ return $regexp;
+ }
+ }
+ }
+}
diff --git a/assets/php/vendor/symfony/routing/RouteCompilerInterface.php b/assets/php/vendor/symfony/routing/RouteCompilerInterface.php
new file mode 100644
index 0000000..ddfa7ca
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/RouteCompilerInterface.php
@@ -0,0 +1,30 @@
+<?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 implement.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+interface RouteCompilerInterface
+{
+ /**
+ * Compiles the current route instance.
+ *
+ * @return CompiledRoute A CompiledRoute instance
+ *
+ * @throws \LogicException If the Route cannot be compiled because the
+ * path or host pattern is invalid
+ */
+ public static function compile(Route $route);
+}
diff --git a/assets/php/vendor/symfony/routing/Router.php b/assets/php/vendor/symfony/routing/Router.php
new file mode 100644
index 0000000..ed56332
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Router.php
@@ -0,0 +1,388 @@
+<?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\ConfigCacheInterface;
+use Symfony\Component\Config\ConfigCacheFactoryInterface;
+use Symfony\Component\Config\ConfigCacheFactory;
+use Psr\Log\LoggerInterface;
+use Symfony\Component\Routing\Generator\ConfigurableRequirementsInterface;
+use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
+use Symfony\Component\Routing\Generator\Dumper\GeneratorDumperInterface;
+use Symfony\Component\Routing\Matcher\RequestMatcherInterface;
+use Symfony\Component\Routing\Matcher\UrlMatcherInterface;
+use Symfony\Component\Routing\Matcher\Dumper\MatcherDumperInterface;
+use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\ExpressionLanguage\ExpressionFunctionProviderInterface;
+
+/**
+ * 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, RequestMatcherInterface
+{
+ /**
+ * @var UrlMatcherInterface|null
+ */
+ protected $matcher;
+
+ /**
+ * @var UrlGeneratorInterface|null
+ */
+ protected $generator;
+
+ /**
+ * @var RequestContext
+ */
+ protected $context;
+
+ /**
+ * @var LoaderInterface
+ */
+ protected $loader;
+
+ /**
+ * @var RouteCollection|null
+ */
+ protected $collection;
+
+ /**
+ * @var mixed
+ */
+ protected $resource;
+
+ /**
+ * @var array
+ */
+ protected $options = array();
+
+ /**
+ * @var LoggerInterface|null
+ */
+ protected $logger;
+
+ /**
+ * @var ConfigCacheFactoryInterface|null
+ */
+ private $configCacheFactory;
+
+ /**
+ * @var ExpressionFunctionProviderInterface[]
+ */
+ private $expressionLanguageProviders = array();
+
+ /**
+ * @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 LoggerInterface $logger A logger instance
+ */
+ public function __construct(LoaderInterface $loader, $resource, array $options = array(), RequestContext $context = null, LoggerInterface $logger = null)
+ {
+ $this->loader = $loader;
+ $this->resource = $resource;
+ $this->logger = $logger;
+ $this->context = $context ?: new RequestContext();
+ $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)
+ * * generator_class: The name of a UrlGeneratorInterface implementation
+ * * generator_base_class: The base class for the dumped generator class
+ * * generator_cache_class: The class name for the dumped generator class
+ * * generator_dumper_class: The name of a GeneratorDumperInterface implementation
+ * * matcher_class: The name of a UrlMatcherInterface implementation
+ * * matcher_base_class: The base class for the dumped matcher class
+ * * matcher_dumper_class: The class name for the dumped matcher class
+ * * matcher_cache_class: The name of a MatcherDumperInterface implementation
+ * * resource_type: Type hint for the main resource (optional)
+ * * strict_requirements: Configure strict requirement checking for generators
+ * implementing ConfigurableRequirementsInterface (default is true)
+ *
+ * @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,
+ 'strict_requirements' => true,
+ );
+
+ // check option names and live merge, if errors are encountered Exception will be thrown
+ $invalid = array();
+ foreach ($options as $key => $value) {
+ if (array_key_exists($key, $this->options)) {
+ $this->options[$key] = $value;
+ } else {
+ $invalid[] = $key;
+ }
+ }
+
+ if ($invalid) {
+ 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];
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getRouteCollection()
+ {
+ if (null === $this->collection) {
+ $this->collection = $this->loader->load($this->resource, $this->options['resource_type']);
+ }
+
+ return $this->collection;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setContext(RequestContext $context)
+ {
+ $this->context = $context;
+
+ if (null !== $this->matcher) {
+ $this->getMatcher()->setContext($context);
+ }
+ if (null !== $this->generator) {
+ $this->getGenerator()->setContext($context);
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getContext()
+ {
+ return $this->context;
+ }
+
+ /**
+ * Sets the ConfigCache factory to use.
+ */
+ public function setConfigCacheFactory(ConfigCacheFactoryInterface $configCacheFactory)
+ {
+ $this->configCacheFactory = $configCacheFactory;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function generate($name, $parameters = array(), $referenceType = self::ABSOLUTE_PATH)
+ {
+ return $this->getGenerator()->generate($name, $parameters, $referenceType);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function match($pathinfo)
+ {
+ return $this->getMatcher()->match($pathinfo);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function matchRequest(Request $request)
+ {
+ $matcher = $this->getMatcher();
+ if (!$matcher instanceof RequestMatcherInterface) {
+ // fallback to the default UrlMatcherInterface
+ return $matcher->match($request->getPathInfo());
+ }
+
+ return $matcher->matchRequest($request);
+ }
+
+ /**
+ * 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']) {
+ $this->matcher = new $this->options['matcher_class']($this->getRouteCollection(), $this->context);
+ if (method_exists($this->matcher, 'addExpressionLanguageProvider')) {
+ foreach ($this->expressionLanguageProviders as $provider) {
+ $this->matcher->addExpressionLanguageProvider($provider);
+ }
+ }
+
+ return $this->matcher;
+ }
+
+ $cache = $this->getConfigCacheFactory()->cache($this->options['cache_dir'].'/'.$this->options['matcher_cache_class'].'.php',
+ function (ConfigCacheInterface $cache) {
+ $dumper = $this->getMatcherDumperInstance();
+ if (method_exists($dumper, 'addExpressionLanguageProvider')) {
+ foreach ($this->expressionLanguageProviders as $provider) {
+ $dumper->addExpressionLanguageProvider($provider);
+ }
+ }
+
+ $options = array(
+ 'class' => $this->options['matcher_cache_class'],
+ 'base_class' => $this->options['matcher_base_class'],
+ );
+
+ $cache->write($dumper->dump($options), $this->getRouteCollection()->getResources());
+ }
+ );
+
+ if (!class_exists($this->options['matcher_cache_class'], false)) {
+ require_once $cache->getPath();
+ }
+
+ return $this->matcher = new $this->options['matcher_cache_class']($this->context);
+ }
+
+ /**
+ * 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']) {
+ $this->generator = new $this->options['generator_class']($this->getRouteCollection(), $this->context, $this->logger);
+ } else {
+ $cache = $this->getConfigCacheFactory()->cache($this->options['cache_dir'].'/'.$this->options['generator_cache_class'].'.php',
+ function (ConfigCacheInterface $cache) {
+ $dumper = $this->getGeneratorDumperInstance();
+
+ $options = array(
+ 'class' => $this->options['generator_cache_class'],
+ 'base_class' => $this->options['generator_base_class'],
+ );
+
+ $cache->write($dumper->dump($options), $this->getRouteCollection()->getResources());
+ }
+ );
+
+ if (!class_exists($this->options['generator_cache_class'], false)) {
+ require_once $cache->getPath();
+ }
+
+ $this->generator = new $this->options['generator_cache_class']($this->context, $this->logger);
+ }
+
+ if ($this->generator instanceof ConfigurableRequirementsInterface) {
+ $this->generator->setStrictRequirements($this->options['strict_requirements']);
+ }
+
+ return $this->generator;
+ }
+
+ public function addExpressionLanguageProvider(ExpressionFunctionProviderInterface $provider)
+ {
+ $this->expressionLanguageProviders[] = $provider;
+ }
+
+ /**
+ * @return GeneratorDumperInterface
+ */
+ protected function getGeneratorDumperInstance()
+ {
+ return new $this->options['generator_dumper_class']($this->getRouteCollection());
+ }
+
+ /**
+ * @return MatcherDumperInterface
+ */
+ protected function getMatcherDumperInstance()
+ {
+ return new $this->options['matcher_dumper_class']($this->getRouteCollection());
+ }
+
+ /**
+ * Provides the ConfigCache factory implementation, falling back to a
+ * default implementation if necessary.
+ *
+ * @return ConfigCacheFactoryInterface $configCacheFactory
+ */
+ private function getConfigCacheFactory()
+ {
+ if (null === $this->configCacheFactory) {
+ $this->configCacheFactory = new ConfigCacheFactory($this->options['debug']);
+ }
+
+ return $this->configCacheFactory;
+ }
+}
diff --git a/assets/php/vendor/symfony/routing/RouterInterface.php b/assets/php/vendor/symfony/routing/RouterInterface.php
new file mode 100644
index 0000000..a10ae34
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/RouterInterface.php
@@ -0,0 +1,32 @@
+<?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 implement.
+ *
+ * This interface is the concatenation of UrlMatcherInterface and UrlGeneratorInterface.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+interface RouterInterface extends UrlMatcherInterface, UrlGeneratorInterface
+{
+ /**
+ * Gets the RouteCollection instance associated with this Router.
+ *
+ * @return RouteCollection A RouteCollection instance
+ */
+ public function getRouteCollection();
+}
diff --git a/assets/php/vendor/symfony/routing/Tests/Annotation/RouteTest.php b/assets/php/vendor/symfony/routing/Tests/Annotation/RouteTest.php
new file mode 100644
index 0000000..9af22f2
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Tests/Annotation/RouteTest.php
@@ -0,0 +1,50 @@
+<?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\Tests\Annotation;
+
+use PHPUnit\Framework\TestCase;
+use Symfony\Component\Routing\Annotation\Route;
+
+class RouteTest extends TestCase
+{
+ /**
+ * @expectedException \BadMethodCallException
+ */
+ public function testInvalidRouteParameter()
+ {
+ $route = new Route(array('foo' => 'bar'));
+ }
+
+ /**
+ * @dataProvider getValidParameters
+ */
+ public function testRouteParameters($parameter, $value, $getter)
+ {
+ $route = new Route(array($parameter => $value));
+ $this->assertEquals($route->$getter(), $value);
+ }
+
+ public function getValidParameters()
+ {
+ return array(
+ array('value', '/Blog', 'getPath'),
+ array('requirements', array('locale' => 'en'), 'getRequirements'),
+ array('options', array('compiler_class' => 'RouteCompiler'), 'getOptions'),
+ array('name', 'blog_index', 'getName'),
+ array('defaults', array('_controller' => 'MyBlogBundle:Blog:index'), 'getDefaults'),
+ array('schemes', array('https'), 'getSchemes'),
+ array('methods', array('GET', 'POST'), 'getMethods'),
+ array('host', '{locale}.example.com', 'getHost'),
+ array('condition', 'context.getMethod() == "GET"', 'getCondition'),
+ );
+ }
+}
diff --git a/assets/php/vendor/symfony/routing/Tests/CompiledRouteTest.php b/assets/php/vendor/symfony/routing/Tests/CompiledRouteTest.php
new file mode 100644
index 0000000..5bec7bb
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Tests/CompiledRouteTest.php
@@ -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\Tests;
+
+use PHPUnit\Framework\TestCase;
+use Symfony\Component\Routing\CompiledRoute;
+
+class CompiledRouteTest extends TestCase
+{
+ public function testAccessors()
+ {
+ $compiled = new CompiledRoute('prefix', 'regex', array('tokens'), array(), null, array(), array(), array('variables'));
+ $this->assertEquals('prefix', $compiled->getStaticPrefix(), '__construct() takes a static prefix as its second argument');
+ $this->assertEquals('regex', $compiled->getRegex(), '__construct() takes a regexp as its third argument');
+ $this->assertEquals(array('tokens'), $compiled->getTokens(), '__construct() takes an array of tokens as its fourth argument');
+ $this->assertEquals(array('variables'), $compiled->getVariables(), '__construct() takes an array of variables as its ninth argument');
+ }
+}
diff --git a/assets/php/vendor/symfony/routing/Tests/DependencyInjection/RoutingResolverPassTest.php b/assets/php/vendor/symfony/routing/Tests/DependencyInjection/RoutingResolverPassTest.php
new file mode 100644
index 0000000..97a34c9
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Tests/DependencyInjection/RoutingResolverPassTest.php
@@ -0,0 +1,36 @@
+<?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\Tests\DependencyInjection;
+
+use PHPUnit\Framework\TestCase;
+use Symfony\Component\Config\Loader\LoaderResolver;
+use Symfony\Component\DependencyInjection\ContainerBuilder;
+use Symfony\Component\DependencyInjection\Reference;
+use Symfony\Component\Routing\DependencyInjection\RoutingResolverPass;
+
+class RoutingResolverPassTest extends TestCase
+{
+ public function testProcess()
+ {
+ $container = new ContainerBuilder();
+ $container->register('routing.resolver', LoaderResolver::class);
+ $container->register('loader1')->addTag('routing.loader');
+ $container->register('loader2')->addTag('routing.loader');
+
+ (new RoutingResolverPass())->process($container);
+
+ $this->assertEquals(
+ array(array('addLoader', array(new Reference('loader1'))), array('addLoader', array(new Reference('loader2')))),
+ $container->getDefinition('routing.resolver')->getMethodCalls()
+ );
+ }
+}
diff --git a/assets/php/vendor/symfony/routing/Tests/Fixtures/AnnotatedClasses/AbstractClass.php b/assets/php/vendor/symfony/routing/Tests/Fixtures/AnnotatedClasses/AbstractClass.php
new file mode 100644
index 0000000..56bcab2
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Tests/Fixtures/AnnotatedClasses/AbstractClass.php
@@ -0,0 +1,16 @@
+<?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\Tests\Fixtures\AnnotatedClasses;
+
+abstract class AbstractClass
+{
+}
diff --git a/assets/php/vendor/symfony/routing/Tests/Fixtures/AnnotatedClasses/BarClass.php b/assets/php/vendor/symfony/routing/Tests/Fixtures/AnnotatedClasses/BarClass.php
new file mode 100644
index 0000000..a388277
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Tests/Fixtures/AnnotatedClasses/BarClass.php
@@ -0,0 +1,19 @@
+<?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\Tests\Fixtures\AnnotatedClasses;
+
+class BarClass
+{
+ public function routeAction($arg1, $arg2 = 'defaultValue2', $arg3 = 'defaultValue3')
+ {
+ }
+}
diff --git a/assets/php/vendor/symfony/routing/Tests/Fixtures/AnnotatedClasses/BazClass.php b/assets/php/vendor/symfony/routing/Tests/Fixtures/AnnotatedClasses/BazClass.php
new file mode 100644
index 0000000..471968b
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Tests/Fixtures/AnnotatedClasses/BazClass.php
@@ -0,0 +1,19 @@
+<?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\Tests\Fixtures\AnnotatedClasses;
+
+class BazClass
+{
+ public function __invoke()
+ {
+ }
+}
diff --git a/assets/php/vendor/symfony/routing/Tests/Fixtures/AnnotatedClasses/FooClass.php b/assets/php/vendor/symfony/routing/Tests/Fixtures/AnnotatedClasses/FooClass.php
new file mode 100644
index 0000000..320dc35
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Tests/Fixtures/AnnotatedClasses/FooClass.php
@@ -0,0 +1,16 @@
+<?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\Tests\Fixtures\AnnotatedClasses;
+
+class FooClass
+{
+}
diff --git a/assets/php/vendor/symfony/routing/Tests/Fixtures/AnnotatedClasses/FooTrait.php b/assets/php/vendor/symfony/routing/Tests/Fixtures/AnnotatedClasses/FooTrait.php
new file mode 100644
index 0000000..ee8f4b0
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Tests/Fixtures/AnnotatedClasses/FooTrait.php
@@ -0,0 +1,13 @@
+<?php
+
+namespace Symfony\Component\Routing\Tests\Fixtures\AnnotatedClasses;
+
+trait FooTrait
+{
+ public function doBar()
+ {
+ $baz = self::class;
+ if (true) {
+ }
+ }
+}
diff --git a/assets/php/vendor/symfony/routing/Tests/Fixtures/CustomCompiledRoute.php b/assets/php/vendor/symfony/routing/Tests/Fixtures/CustomCompiledRoute.php
new file mode 100644
index 0000000..0f6e198
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Tests/Fixtures/CustomCompiledRoute.php
@@ -0,0 +1,18 @@
+<?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\Tests\Fixtures;
+
+use Symfony\Component\Routing\CompiledRoute;
+
+class CustomCompiledRoute extends CompiledRoute
+{
+}
diff --git a/assets/php/vendor/symfony/routing/Tests/Fixtures/CustomRouteCompiler.php b/assets/php/vendor/symfony/routing/Tests/Fixtures/CustomRouteCompiler.php
new file mode 100644
index 0000000..c2e2afd
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Tests/Fixtures/CustomRouteCompiler.php
@@ -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\Tests\Fixtures;
+
+use Symfony\Component\Routing\Route;
+use Symfony\Component\Routing\RouteCompiler;
+
+class CustomRouteCompiler extends RouteCompiler
+{
+ /**
+ * {@inheritdoc}
+ */
+ public static function compile(Route $route)
+ {
+ return new CustomCompiledRoute('', '', array(), array());
+ }
+}
diff --git a/assets/php/vendor/symfony/routing/Tests/Fixtures/CustomXmlFileLoader.php b/assets/php/vendor/symfony/routing/Tests/Fixtures/CustomXmlFileLoader.php
new file mode 100644
index 0000000..9fd5754
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Tests/Fixtures/CustomXmlFileLoader.php
@@ -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\Tests\Fixtures;
+
+use Symfony\Component\Routing\Loader\XmlFileLoader;
+use Symfony\Component\Config\Util\XmlUtils;
+
+/**
+ * XmlFileLoader with schema validation turned off.
+ */
+class CustomXmlFileLoader extends XmlFileLoader
+{
+ protected function loadFile($file)
+ {
+ return XmlUtils::loadFile($file, function () { return true; });
+ }
+}
diff --git a/assets/php/vendor/symfony/routing/Tests/Fixtures/OtherAnnotatedClasses/AnonymousClassInTrait.php b/assets/php/vendor/symfony/routing/Tests/Fixtures/OtherAnnotatedClasses/AnonymousClassInTrait.php
new file mode 100644
index 0000000..de87895
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Tests/Fixtures/OtherAnnotatedClasses/AnonymousClassInTrait.php
@@ -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\Tests\Fixtures\OtherAnnotatedClasses;
+
+trait AnonymousClassInTrait
+{
+ public function test()
+ {
+ return new class() {
+ public function foo()
+ {
+ }
+ };
+ }
+}
diff --git a/assets/php/vendor/symfony/routing/Tests/Fixtures/OtherAnnotatedClasses/NoStartTagClass.php b/assets/php/vendor/symfony/routing/Tests/Fixtures/OtherAnnotatedClasses/NoStartTagClass.php
new file mode 100644
index 0000000..8900d34
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Tests/Fixtures/OtherAnnotatedClasses/NoStartTagClass.php
@@ -0,0 +1,3 @@
+class NoStartTagClass
+{
+}
diff --git a/assets/php/vendor/symfony/routing/Tests/Fixtures/OtherAnnotatedClasses/VariadicClass.php b/assets/php/vendor/symfony/routing/Tests/Fixtures/OtherAnnotatedClasses/VariadicClass.php
new file mode 100644
index 0000000..729c9b4
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Tests/Fixtures/OtherAnnotatedClasses/VariadicClass.php
@@ -0,0 +1,19 @@
+<?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\Tests\Fixtures\OtherAnnotatedClasses;
+
+class VariadicClass
+{
+ public function routeAction(...$params)
+ {
+ }
+}
diff --git a/assets/php/vendor/symfony/routing/Tests/Fixtures/RedirectableUrlMatcher.php b/assets/php/vendor/symfony/routing/Tests/Fixtures/RedirectableUrlMatcher.php
new file mode 100644
index 0000000..15937bc
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Tests/Fixtures/RedirectableUrlMatcher.php
@@ -0,0 +1,30 @@
+<?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\Tests\Fixtures;
+
+use Symfony\Component\Routing\Matcher\UrlMatcher;
+use Symfony\Component\Routing\Matcher\RedirectableUrlMatcherInterface;
+
+/**
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+class RedirectableUrlMatcher extends UrlMatcher implements RedirectableUrlMatcherInterface
+{
+ public function redirect($path, $route, $scheme = null)
+ {
+ return array(
+ '_controller' => 'Some controller reference...',
+ 'path' => $path,
+ 'scheme' => $scheme,
+ );
+ }
+}
diff --git a/assets/php/vendor/symfony/routing/Tests/Fixtures/annotated.php b/assets/php/vendor/symfony/routing/Tests/Fixtures/annotated.php
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Tests/Fixtures/annotated.php
diff --git a/assets/php/vendor/symfony/routing/Tests/Fixtures/bad_format.yml b/assets/php/vendor/symfony/routing/Tests/Fixtures/bad_format.yml
new file mode 100644
index 0000000..8ba50e2
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Tests/Fixtures/bad_format.yml
@@ -0,0 +1,3 @@
+blog_show:
+ path: /blog/{slug}
+ defaults: { _controller: "MyBundle:Blog:show" }
diff --git a/assets/php/vendor/symfony/routing/Tests/Fixtures/bar.xml b/assets/php/vendor/symfony/routing/Tests/Fixtures/bar.xml
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Tests/Fixtures/bar.xml
diff --git a/assets/php/vendor/symfony/routing/Tests/Fixtures/controller/import__controller.xml b/assets/php/vendor/symfony/routing/Tests/Fixtures/controller/import__controller.xml
new file mode 100644
index 0000000..bbe727d
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Tests/Fixtures/controller/import__controller.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<routes xmlns="http://symfony.com/schema/routing"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://symfony.com/schema/routing
+ http://symfony.com/schema/routing/routing-1.0.xsd">
+
+ <import resource="routing.xml">
+ <default key="_controller">FrameworkBundle:Template:template</default>
+ </import>
+</routes>
diff --git a/assets/php/vendor/symfony/routing/Tests/Fixtures/controller/import__controller.yml b/assets/php/vendor/symfony/routing/Tests/Fixtures/controller/import__controller.yml
new file mode 100644
index 0000000..4240b74
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Tests/Fixtures/controller/import__controller.yml
@@ -0,0 +1,4 @@
+_static:
+ resource: routing.yml
+ defaults:
+ _controller: FrameworkBundle:Template:template
diff --git a/assets/php/vendor/symfony/routing/Tests/Fixtures/controller/import_controller.xml b/assets/php/vendor/symfony/routing/Tests/Fixtures/controller/import_controller.xml
new file mode 100644
index 0000000..378b9ca
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Tests/Fixtures/controller/import_controller.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<routes xmlns="http://symfony.com/schema/routing"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://symfony.com/schema/routing
+ http://symfony.com/schema/routing/routing-1.0.xsd">
+
+ <import resource="routing.xml" controller="FrameworkBundle:Template:template" />
+</routes>
diff --git a/assets/php/vendor/symfony/routing/Tests/Fixtures/controller/import_controller.yml b/assets/php/vendor/symfony/routing/Tests/Fixtures/controller/import_controller.yml
new file mode 100644
index 0000000..1a71c62
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Tests/Fixtures/controller/import_controller.yml
@@ -0,0 +1,3 @@
+_static:
+ resource: routing.yml
+ controller: FrameworkBundle:Template:template
diff --git a/assets/php/vendor/symfony/routing/Tests/Fixtures/controller/import_override_defaults.xml b/assets/php/vendor/symfony/routing/Tests/Fixtures/controller/import_override_defaults.xml
new file mode 100644
index 0000000..e3c755a
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Tests/Fixtures/controller/import_override_defaults.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<routes xmlns="http://symfony.com/schema/routing"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://symfony.com/schema/routing
+ http://symfony.com/schema/routing/routing-1.0.xsd">
+
+ <import resource="routing.xml" controller="FrameworkBundle:Template:template">
+ <default key="_controller">AppBundle:Blog:index</default>
+ </import>
+</routes>
diff --git a/assets/php/vendor/symfony/routing/Tests/Fixtures/controller/import_override_defaults.yml b/assets/php/vendor/symfony/routing/Tests/Fixtures/controller/import_override_defaults.yml
new file mode 100644
index 0000000..db1ab3c
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Tests/Fixtures/controller/import_override_defaults.yml
@@ -0,0 +1,5 @@
+_static:
+ resource: routing.yml
+ controller: FrameworkBundle:Template:template
+ defaults:
+ _controller: AppBundle:Homepage:show
diff --git a/assets/php/vendor/symfony/routing/Tests/Fixtures/controller/override_defaults.xml b/assets/php/vendor/symfony/routing/Tests/Fixtures/controller/override_defaults.xml
new file mode 100644
index 0000000..f47c57b
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Tests/Fixtures/controller/override_defaults.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<routes xmlns="http://symfony.com/schema/routing"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://symfony.com/schema/routing
+ http://symfony.com/schema/routing/routing-1.0.xsd">
+
+ <route id="app_blog" path="/blog" controller="AppBundle:Homepage:show">
+ <default key="_controller">AppBundle:Blog:index</default>
+ </route>
+</routes>
diff --git a/assets/php/vendor/symfony/routing/Tests/Fixtures/controller/override_defaults.yml b/assets/php/vendor/symfony/routing/Tests/Fixtures/controller/override_defaults.yml
new file mode 100644
index 0000000..00a2c0e
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Tests/Fixtures/controller/override_defaults.yml
@@ -0,0 +1,5 @@
+app_blog:
+ path: /blog
+ controller: AppBundle:Homepage:show
+ defaults:
+ _controller: AppBundle:Blog:index
diff --git a/assets/php/vendor/symfony/routing/Tests/Fixtures/controller/routing.xml b/assets/php/vendor/symfony/routing/Tests/Fixtures/controller/routing.xml
new file mode 100644
index 0000000..6420138
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Tests/Fixtures/controller/routing.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<routes xmlns="http://symfony.com/schema/routing"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://symfony.com/schema/routing
+ http://symfony.com/schema/routing/routing-1.0.xsd">
+
+ <route id="app_homepage" path="/" controller="AppBundle:Homepage:show" />
+
+ <route id="app_blog" path="/blog">
+ <default key="_controller">AppBundle:Blog:list</default>
+ </route>
+
+ <route id="app_logout" path="/logout" />
+</routes>
diff --git a/assets/php/vendor/symfony/routing/Tests/Fixtures/controller/routing.yml b/assets/php/vendor/symfony/routing/Tests/Fixtures/controller/routing.yml
new file mode 100644
index 0000000..cb71ec3
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Tests/Fixtures/controller/routing.yml
@@ -0,0 +1,11 @@
+app_homepage:
+ path: /
+ controller: AppBundle:Homepage:show
+
+app_blog:
+ path: /blog
+ defaults:
+ _controller: AppBundle:Blog:list
+
+app_logout:
+ path: /logout
diff --git a/assets/php/vendor/symfony/routing/Tests/Fixtures/directory/recurse/routes1.yml b/assets/php/vendor/symfony/routing/Tests/Fixtures/directory/recurse/routes1.yml
new file mode 100644
index 0000000..d078836
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Tests/Fixtures/directory/recurse/routes1.yml
@@ -0,0 +1,2 @@
+route1:
+ path: /route/1
diff --git a/assets/php/vendor/symfony/routing/Tests/Fixtures/directory/recurse/routes2.yml b/assets/php/vendor/symfony/routing/Tests/Fixtures/directory/recurse/routes2.yml
new file mode 100644
index 0000000..938fb24
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Tests/Fixtures/directory/recurse/routes2.yml
@@ -0,0 +1,2 @@
+route2:
+ path: /route/2
diff --git a/assets/php/vendor/symfony/routing/Tests/Fixtures/directory/routes3.yml b/assets/php/vendor/symfony/routing/Tests/Fixtures/directory/routes3.yml
new file mode 100644
index 0000000..088cfb4
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Tests/Fixtures/directory/routes3.yml
@@ -0,0 +1,2 @@
+route3:
+ path: /route/3
diff --git a/assets/php/vendor/symfony/routing/Tests/Fixtures/directory_import/import.yml b/assets/php/vendor/symfony/routing/Tests/Fixtures/directory_import/import.yml
new file mode 100644
index 0000000..af829e5
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Tests/Fixtures/directory_import/import.yml
@@ -0,0 +1,3 @@
+_directory:
+ resource: "../directory"
+ type: directory
diff --git a/assets/php/vendor/symfony/routing/Tests/Fixtures/dumper/url_matcher0.php b/assets/php/vendor/symfony/routing/Tests/Fixtures/dumper/url_matcher0.php
new file mode 100644
index 0000000..9e9b910
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Tests/Fixtures/dumper/url_matcher0.php
@@ -0,0 +1,37 @@
+<?php
+
+use Symfony\Component\Routing\Exception\MethodNotAllowedException;
+use Symfony\Component\Routing\Exception\ResourceNotFoundException;
+use Symfony\Component\Routing\RequestContext;
+
+/**
+ * This class has been auto-generated
+ * by the Symfony Routing Component.
+ */
+class ProjectUrlMatcher extends Symfony\Component\Routing\Matcher\UrlMatcher
+{
+ public function __construct(RequestContext $context)
+ {
+ $this->context = $context;
+ }
+
+ public function match($rawPathinfo)
+ {
+ $allow = array();
+ $pathinfo = rawurldecode($rawPathinfo);
+ $trimmedPathinfo = rtrim($pathinfo, '/');
+ $context = $this->context;
+ $request = $this->request ?: $this->createRequest($pathinfo);
+ $requestMethod = $canonicalMethod = $context->getMethod();
+
+ if ('HEAD' === $requestMethod) {
+ $canonicalMethod = 'GET';
+ }
+
+ if ('/' === $pathinfo && !$allow) {
+ throw new Symfony\Component\Routing\Exception\NoConfigurationException();
+ }
+
+ throw 0 < count($allow) ? new MethodNotAllowedException(array_unique($allow)) : new ResourceNotFoundException();
+ }
+}
diff --git a/assets/php/vendor/symfony/routing/Tests/Fixtures/dumper/url_matcher1.php b/assets/php/vendor/symfony/routing/Tests/Fixtures/dumper/url_matcher1.php
new file mode 100644
index 0000000..23a93c1
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Tests/Fixtures/dumper/url_matcher1.php
@@ -0,0 +1,318 @@
+<?php
+
+use Symfony\Component\Routing\Exception\MethodNotAllowedException;
+use Symfony\Component\Routing\Exception\ResourceNotFoundException;
+use Symfony\Component\Routing\RequestContext;
+
+/**
+ * This class has been auto-generated
+ * by the Symfony Routing Component.
+ */
+class ProjectUrlMatcher extends Symfony\Component\Routing\Matcher\UrlMatcher
+{
+ public function __construct(RequestContext $context)
+ {
+ $this->context = $context;
+ }
+
+ public function match($rawPathinfo)
+ {
+ $allow = array();
+ $pathinfo = rawurldecode($rawPathinfo);
+ $trimmedPathinfo = rtrim($pathinfo, '/');
+ $context = $this->context;
+ $request = $this->request ?: $this->createRequest($pathinfo);
+ $requestMethod = $canonicalMethod = $context->getMethod();
+
+ if ('HEAD' === $requestMethod) {
+ $canonicalMethod = 'GET';
+ }
+
+ if (0 === strpos($pathinfo, '/foo')) {
+ // foo
+ if (preg_match('#^/foo/(?P<bar>baz|symfony)$#sD', $pathinfo, $matches)) {
+ return $this->mergeDefaults(array_replace($matches, array('_route' => 'foo')), array ( 'def' => 'test',));
+ }
+
+ // foofoo
+ if ('/foofoo' === $pathinfo) {
+ return array ( 'def' => 'test', '_route' => 'foofoo',);
+ }
+
+ }
+
+ elseif (0 === strpos($pathinfo, '/bar')) {
+ // bar
+ if (preg_match('#^/bar/(?P<foo>[^/]++)$#sD', $pathinfo, $matches)) {
+ $ret = $this->mergeDefaults(array_replace($matches, array('_route' => 'bar')), array ());
+ if (!in_array($canonicalMethod, array('GET', 'HEAD'))) {
+ $allow = array_merge($allow, array('GET', 'HEAD'));
+ goto not_bar;
+ }
+
+ return $ret;
+ }
+ not_bar:
+
+ // barhead
+ if (0 === strpos($pathinfo, '/barhead') && preg_match('#^/barhead/(?P<foo>[^/]++)$#sD', $pathinfo, $matches)) {
+ $ret = $this->mergeDefaults(array_replace($matches, array('_route' => 'barhead')), array ());
+ if (!in_array($canonicalMethod, array('GET'))) {
+ $allow = array_merge($allow, array('GET'));
+ goto not_barhead;
+ }
+
+ return $ret;
+ }
+ not_barhead:
+
+ }
+
+ elseif (0 === strpos($pathinfo, '/test')) {
+ if (0 === strpos($pathinfo, '/test/baz')) {
+ // baz
+ if ('/test/baz' === $pathinfo) {
+ return array('_route' => 'baz');
+ }
+
+ // baz2
+ if ('/test/baz.html' === $pathinfo) {
+ return array('_route' => 'baz2');
+ }
+
+ // baz3
+ if ('/test/baz3/' === $pathinfo) {
+ return array('_route' => 'baz3');
+ }
+
+ }
+
+ // baz4
+ if (preg_match('#^/test/(?P<foo>[^/]++)/$#sD', $pathinfo, $matches)) {
+ return $this->mergeDefaults(array_replace($matches, array('_route' => 'baz4')), array ());
+ }
+
+ // baz5
+ if (preg_match('#^/test/(?P<foo>[^/]++)/$#sD', $pathinfo, $matches)) {
+ $ret = $this->mergeDefaults(array_replace($matches, array('_route' => 'baz5')), array ());
+ if (!in_array($requestMethod, array('POST'))) {
+ $allow = array_merge($allow, array('POST'));
+ goto not_baz5;
+ }
+
+ return $ret;
+ }
+ not_baz5:
+
+ // baz.baz6
+ if (preg_match('#^/test/(?P<foo>[^/]++)/$#sD', $pathinfo, $matches)) {
+ $ret = $this->mergeDefaults(array_replace($matches, array('_route' => 'baz.baz6')), array ());
+ if (!in_array($requestMethod, array('PUT'))) {
+ $allow = array_merge($allow, array('PUT'));
+ goto not_bazbaz6;
+ }
+
+ return $ret;
+ }
+ not_bazbaz6:
+
+ }
+
+ // quoter
+ if (preg_match('#^/(?P<quoter>[\']+)$#sD', $pathinfo, $matches)) {
+ return $this->mergeDefaults(array_replace($matches, array('_route' => 'quoter')), array ());
+ }
+
+ // space
+ if ('/spa ce' === $pathinfo) {
+ return array('_route' => 'space');
+ }
+
+ if (0 === strpos($pathinfo, '/a')) {
+ if (0 === strpos($pathinfo, '/a/b\'b')) {
+ // foo1
+ if (preg_match('#^/a/b\'b/(?P<foo>[^/]++)$#sD', $pathinfo, $matches)) {
+ return $this->mergeDefaults(array_replace($matches, array('_route' => 'foo1')), array ());
+ }
+
+ // bar1
+ if (preg_match('#^/a/b\'b/(?P<bar>[^/]++)$#sD', $pathinfo, $matches)) {
+ return $this->mergeDefaults(array_replace($matches, array('_route' => 'bar1')), array ());
+ }
+
+ }
+
+ // overridden
+ if (preg_match('#^/a/(?P<var>.*)$#sD', $pathinfo, $matches)) {
+ return $this->mergeDefaults(array_replace($matches, array('_route' => 'overridden')), array ());
+ }
+
+ if (0 === strpos($pathinfo, '/a/b\'b')) {
+ // foo2
+ if (preg_match('#^/a/b\'b/(?P<foo1>[^/]++)$#sD', $pathinfo, $matches)) {
+ return $this->mergeDefaults(array_replace($matches, array('_route' => 'foo2')), array ());
+ }
+
+ // bar2
+ if (preg_match('#^/a/b\'b/(?P<bar1>[^/]++)$#sD', $pathinfo, $matches)) {
+ return $this->mergeDefaults(array_replace($matches, array('_route' => 'bar2')), array ());
+ }
+
+ }
+
+ }
+
+ elseif (0 === strpos($pathinfo, '/multi')) {
+ // helloWorld
+ if (0 === strpos($pathinfo, '/multi/hello') && preg_match('#^/multi/hello(?:/(?P<who>[^/]++))?$#sD', $pathinfo, $matches)) {
+ return $this->mergeDefaults(array_replace($matches, array('_route' => 'helloWorld')), array ( 'who' => 'World!',));
+ }
+
+ // hey
+ if ('/multi/hey/' === $pathinfo) {
+ return array('_route' => 'hey');
+ }
+
+ // overridden2
+ if ('/multi/new' === $pathinfo) {
+ return array('_route' => 'overridden2');
+ }
+
+ }
+
+ // foo3
+ if (preg_match('#^/(?P<_locale>[^/]++)/b/(?P<foo>[^/]++)$#sD', $pathinfo, $matches)) {
+ return $this->mergeDefaults(array_replace($matches, array('_route' => 'foo3')), array ());
+ }
+
+ // bar3
+ if (preg_match('#^/(?P<_locale>[^/]++)/b/(?P<bar>[^/]++)$#sD', $pathinfo, $matches)) {
+ return $this->mergeDefaults(array_replace($matches, array('_route' => 'bar3')), array ());
+ }
+
+ if (0 === strpos($pathinfo, '/aba')) {
+ // ababa
+ if ('/ababa' === $pathinfo) {
+ return array('_route' => 'ababa');
+ }
+
+ // foo4
+ if (preg_match('#^/aba/(?P<foo>[^/]++)$#sD', $pathinfo, $matches)) {
+ return $this->mergeDefaults(array_replace($matches, array('_route' => 'foo4')), array ());
+ }
+
+ }
+
+ $host = $context->getHost();
+
+ if (preg_match('#^a\\.example\\.com$#sDi', $host, $hostMatches)) {
+ // route1
+ if ('/route1' === $pathinfo) {
+ return array('_route' => 'route1');
+ }
+
+ // route2
+ if ('/c2/route2' === $pathinfo) {
+ return array('_route' => 'route2');
+ }
+
+ }
+
+ if (preg_match('#^b\\.example\\.com$#sDi', $host, $hostMatches)) {
+ // route3
+ if ('/c2/route3' === $pathinfo) {
+ return array('_route' => 'route3');
+ }
+
+ }
+
+ if (preg_match('#^a\\.example\\.com$#sDi', $host, $hostMatches)) {
+ // route4
+ if ('/route4' === $pathinfo) {
+ return array('_route' => 'route4');
+ }
+
+ }
+
+ if (preg_match('#^c\\.example\\.com$#sDi', $host, $hostMatches)) {
+ // route5
+ if ('/route5' === $pathinfo) {
+ return array('_route' => 'route5');
+ }
+
+ }
+
+ // route6
+ if ('/route6' === $pathinfo) {
+ return array('_route' => 'route6');
+ }
+
+ if (preg_match('#^(?P<var1>[^\\.]++)\\.example\\.com$#sDi', $host, $hostMatches)) {
+ if (0 === strpos($pathinfo, '/route1')) {
+ // route11
+ if ('/route11' === $pathinfo) {
+ return $this->mergeDefaults(array_replace($hostMatches, array('_route' => 'route11')), array ());
+ }
+
+ // route12
+ if ('/route12' === $pathinfo) {
+ return $this->mergeDefaults(array_replace($hostMatches, array('_route' => 'route12')), array ( 'var1' => 'val',));
+ }
+
+ // route13
+ if (0 === strpos($pathinfo, '/route13') && preg_match('#^/route13/(?P<name>[^/]++)$#sD', $pathinfo, $matches)) {
+ return $this->mergeDefaults(array_replace($hostMatches, $matches, array('_route' => 'route13')), array ());
+ }
+
+ // route14
+ if (0 === strpos($pathinfo, '/route14') && preg_match('#^/route14/(?P<name>[^/]++)$#sD', $pathinfo, $matches)) {
+ return $this->mergeDefaults(array_replace($hostMatches, $matches, array('_route' => 'route14')), array ( 'var1' => 'val',));
+ }
+
+ }
+
+ }
+
+ if (preg_match('#^c\\.example\\.com$#sDi', $host, $hostMatches)) {
+ // route15
+ if (0 === strpos($pathinfo, '/route15') && preg_match('#^/route15/(?P<name>[^/]++)$#sD', $pathinfo, $matches)) {
+ return $this->mergeDefaults(array_replace($matches, array('_route' => 'route15')), array ());
+ }
+
+ }
+
+ // route16
+ if (0 === strpos($pathinfo, '/route16') && preg_match('#^/route16/(?P<name>[^/]++)$#sD', $pathinfo, $matches)) {
+ return $this->mergeDefaults(array_replace($matches, array('_route' => 'route16')), array ( 'var1' => 'val',));
+ }
+
+ // route17
+ if ('/route17' === $pathinfo) {
+ return array('_route' => 'route17');
+ }
+
+ // a
+ if ('/a/a...' === $pathinfo) {
+ return array('_route' => 'a');
+ }
+
+ if (0 === strpos($pathinfo, '/a/b')) {
+ // b
+ if (preg_match('#^/a/b/(?P<var>[^/]++)$#sD', $pathinfo, $matches)) {
+ return $this->mergeDefaults(array_replace($matches, array('_route' => 'b')), array ());
+ }
+
+ // c
+ if (0 === strpos($pathinfo, '/a/b/c') && preg_match('#^/a/b/c/(?P<var>[^/]++)$#sD', $pathinfo, $matches)) {
+ return $this->mergeDefaults(array_replace($matches, array('_route' => 'c')), array ());
+ }
+
+ }
+
+ if ('/' === $pathinfo && !$allow) {
+ throw new Symfony\Component\Routing\Exception\NoConfigurationException();
+ }
+
+ throw 0 < count($allow) ? new MethodNotAllowedException(array_unique($allow)) : new ResourceNotFoundException();
+ }
+}
diff --git a/assets/php/vendor/symfony/routing/Tests/Fixtures/dumper/url_matcher2.php b/assets/php/vendor/symfony/routing/Tests/Fixtures/dumper/url_matcher2.php
new file mode 100644
index 0000000..e430adb
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Tests/Fixtures/dumper/url_matcher2.php
@@ -0,0 +1,380 @@
+<?php
+
+use Symfony\Component\Routing\Exception\MethodNotAllowedException;
+use Symfony\Component\Routing\Exception\ResourceNotFoundException;
+use Symfony\Component\Routing\RequestContext;
+
+/**
+ * This class has been auto-generated
+ * by the Symfony Routing Component.
+ */
+class ProjectUrlMatcher extends Symfony\Component\Routing\Tests\Fixtures\RedirectableUrlMatcher
+{
+ public function __construct(RequestContext $context)
+ {
+ $this->context = $context;
+ }
+
+ public function match($rawPathinfo)
+ {
+ $allow = array();
+ $pathinfo = rawurldecode($rawPathinfo);
+ $trimmedPathinfo = rtrim($pathinfo, '/');
+ $context = $this->context;
+ $request = $this->request ?: $this->createRequest($pathinfo);
+ $requestMethod = $canonicalMethod = $context->getMethod();
+
+ if ('HEAD' === $requestMethod) {
+ $canonicalMethod = 'GET';
+ }
+
+ if (0 === strpos($pathinfo, '/foo')) {
+ // foo
+ if (preg_match('#^/foo/(?P<bar>baz|symfony)$#sD', $pathinfo, $matches)) {
+ return $this->mergeDefaults(array_replace($matches, array('_route' => 'foo')), array ( 'def' => 'test',));
+ }
+
+ // foofoo
+ if ('/foofoo' === $pathinfo) {
+ return array ( 'def' => 'test', '_route' => 'foofoo',);
+ }
+
+ }
+
+ elseif (0 === strpos($pathinfo, '/bar')) {
+ // bar
+ if (preg_match('#^/bar/(?P<foo>[^/]++)$#sD', $pathinfo, $matches)) {
+ $ret = $this->mergeDefaults(array_replace($matches, array('_route' => 'bar')), array ());
+ if (!in_array($canonicalMethod, array('GET', 'HEAD'))) {
+ $allow = array_merge($allow, array('GET', 'HEAD'));
+ goto not_bar;
+ }
+
+ return $ret;
+ }
+ not_bar:
+
+ // barhead
+ if (0 === strpos($pathinfo, '/barhead') && preg_match('#^/barhead/(?P<foo>[^/]++)$#sD', $pathinfo, $matches)) {
+ $ret = $this->mergeDefaults(array_replace($matches, array('_route' => 'barhead')), array ());
+ if (!in_array($canonicalMethod, array('GET'))) {
+ $allow = array_merge($allow, array('GET'));
+ goto not_barhead;
+ }
+
+ return $ret;
+ }
+ not_barhead:
+
+ }
+
+ elseif (0 === strpos($pathinfo, '/test')) {
+ if (0 === strpos($pathinfo, '/test/baz')) {
+ // baz
+ if ('/test/baz' === $pathinfo) {
+ return array('_route' => 'baz');
+ }
+
+ // baz2
+ if ('/test/baz.html' === $pathinfo) {
+ return array('_route' => 'baz2');
+ }
+
+ // baz3
+ if ('/test/baz3' === $trimmedPathinfo) {
+ $ret = array('_route' => 'baz3');
+ if ('/' === substr($pathinfo, -1)) {
+ // no-op
+ } elseif ('GET' !== $canonicalMethod) {
+ goto not_baz3;
+ } else {
+ return array_replace($ret, $this->redirect($rawPathinfo.'/', 'baz3'));
+ }
+
+ return $ret;
+ }
+ not_baz3:
+
+ }
+
+ // baz4
+ if (preg_match('#^/test/(?P<foo>[^/]++)/?$#sD', $pathinfo, $matches)) {
+ $ret = $this->mergeDefaults(array_replace($matches, array('_route' => 'baz4')), array ());
+ if ('/' === substr($pathinfo, -1)) {
+ // no-op
+ } elseif ('GET' !== $canonicalMethod) {
+ goto not_baz4;
+ } else {
+ return array_replace($ret, $this->redirect($rawPathinfo.'/', 'baz4'));
+ }
+
+ return $ret;
+ }
+ not_baz4:
+
+ // baz5
+ if (preg_match('#^/test/(?P<foo>[^/]++)/$#sD', $pathinfo, $matches)) {
+ $ret = $this->mergeDefaults(array_replace($matches, array('_route' => 'baz5')), array ());
+ if (!in_array($requestMethod, array('POST'))) {
+ $allow = array_merge($allow, array('POST'));
+ goto not_baz5;
+ }
+
+ return $ret;
+ }
+ not_baz5:
+
+ // baz.baz6
+ if (preg_match('#^/test/(?P<foo>[^/]++)/$#sD', $pathinfo, $matches)) {
+ $ret = $this->mergeDefaults(array_replace($matches, array('_route' => 'baz.baz6')), array ());
+ if (!in_array($requestMethod, array('PUT'))) {
+ $allow = array_merge($allow, array('PUT'));
+ goto not_bazbaz6;
+ }
+
+ return $ret;
+ }
+ not_bazbaz6:
+
+ }
+
+ // quoter
+ if (preg_match('#^/(?P<quoter>[\']+)$#sD', $pathinfo, $matches)) {
+ return $this->mergeDefaults(array_replace($matches, array('_route' => 'quoter')), array ());
+ }
+
+ // space
+ if ('/spa ce' === $pathinfo) {
+ return array('_route' => 'space');
+ }
+
+ if (0 === strpos($pathinfo, '/a')) {
+ if (0 === strpos($pathinfo, '/a/b\'b')) {
+ // foo1
+ if (preg_match('#^/a/b\'b/(?P<foo>[^/]++)$#sD', $pathinfo, $matches)) {
+ return $this->mergeDefaults(array_replace($matches, array('_route' => 'foo1')), array ());
+ }
+
+ // bar1
+ if (preg_match('#^/a/b\'b/(?P<bar>[^/]++)$#sD', $pathinfo, $matches)) {
+ return $this->mergeDefaults(array_replace($matches, array('_route' => 'bar1')), array ());
+ }
+
+ }
+
+ // overridden
+ if (preg_match('#^/a/(?P<var>.*)$#sD', $pathinfo, $matches)) {
+ return $this->mergeDefaults(array_replace($matches, array('_route' => 'overridden')), array ());
+ }
+
+ if (0 === strpos($pathinfo, '/a/b\'b')) {
+ // foo2
+ if (preg_match('#^/a/b\'b/(?P<foo1>[^/]++)$#sD', $pathinfo, $matches)) {
+ return $this->mergeDefaults(array_replace($matches, array('_route' => 'foo2')), array ());
+ }
+
+ // bar2
+ if (preg_match('#^/a/b\'b/(?P<bar1>[^/]++)$#sD', $pathinfo, $matches)) {
+ return $this->mergeDefaults(array_replace($matches, array('_route' => 'bar2')), array ());
+ }
+
+ }
+
+ }
+
+ elseif (0 === strpos($pathinfo, '/multi')) {
+ // helloWorld
+ if (0 === strpos($pathinfo, '/multi/hello') && preg_match('#^/multi/hello(?:/(?P<who>[^/]++))?$#sD', $pathinfo, $matches)) {
+ return $this->mergeDefaults(array_replace($matches, array('_route' => 'helloWorld')), array ( 'who' => 'World!',));
+ }
+
+ // hey
+ if ('/multi/hey' === $trimmedPathinfo) {
+ $ret = array('_route' => 'hey');
+ if ('/' === substr($pathinfo, -1)) {
+ // no-op
+ } elseif ('GET' !== $canonicalMethod) {
+ goto not_hey;
+ } else {
+ return array_replace($ret, $this->redirect($rawPathinfo.'/', 'hey'));
+ }
+
+ return $ret;
+ }
+ not_hey:
+
+ // overridden2
+ if ('/multi/new' === $pathinfo) {
+ return array('_route' => 'overridden2');
+ }
+
+ }
+
+ // foo3
+ if (preg_match('#^/(?P<_locale>[^/]++)/b/(?P<foo>[^/]++)$#sD', $pathinfo, $matches)) {
+ return $this->mergeDefaults(array_replace($matches, array('_route' => 'foo3')), array ());
+ }
+
+ // bar3
+ if (preg_match('#^/(?P<_locale>[^/]++)/b/(?P<bar>[^/]++)$#sD', $pathinfo, $matches)) {
+ return $this->mergeDefaults(array_replace($matches, array('_route' => 'bar3')), array ());
+ }
+
+ if (0 === strpos($pathinfo, '/aba')) {
+ // ababa
+ if ('/ababa' === $pathinfo) {
+ return array('_route' => 'ababa');
+ }
+
+ // foo4
+ if (preg_match('#^/aba/(?P<foo>[^/]++)$#sD', $pathinfo, $matches)) {
+ return $this->mergeDefaults(array_replace($matches, array('_route' => 'foo4')), array ());
+ }
+
+ }
+
+ $host = $context->getHost();
+
+ if (preg_match('#^a\\.example\\.com$#sDi', $host, $hostMatches)) {
+ // route1
+ if ('/route1' === $pathinfo) {
+ return array('_route' => 'route1');
+ }
+
+ // route2
+ if ('/c2/route2' === $pathinfo) {
+ return array('_route' => 'route2');
+ }
+
+ }
+
+ if (preg_match('#^b\\.example\\.com$#sDi', $host, $hostMatches)) {
+ // route3
+ if ('/c2/route3' === $pathinfo) {
+ return array('_route' => 'route3');
+ }
+
+ }
+
+ if (preg_match('#^a\\.example\\.com$#sDi', $host, $hostMatches)) {
+ // route4
+ if ('/route4' === $pathinfo) {
+ return array('_route' => 'route4');
+ }
+
+ }
+
+ if (preg_match('#^c\\.example\\.com$#sDi', $host, $hostMatches)) {
+ // route5
+ if ('/route5' === $pathinfo) {
+ return array('_route' => 'route5');
+ }
+
+ }
+
+ // route6
+ if ('/route6' === $pathinfo) {
+ return array('_route' => 'route6');
+ }
+
+ if (preg_match('#^(?P<var1>[^\\.]++)\\.example\\.com$#sDi', $host, $hostMatches)) {
+ if (0 === strpos($pathinfo, '/route1')) {
+ // route11
+ if ('/route11' === $pathinfo) {
+ return $this->mergeDefaults(array_replace($hostMatches, array('_route' => 'route11')), array ());
+ }
+
+ // route12
+ if ('/route12' === $pathinfo) {
+ return $this->mergeDefaults(array_replace($hostMatches, array('_route' => 'route12')), array ( 'var1' => 'val',));
+ }
+
+ // route13
+ if (0 === strpos($pathinfo, '/route13') && preg_match('#^/route13/(?P<name>[^/]++)$#sD', $pathinfo, $matches)) {
+ return $this->mergeDefaults(array_replace($hostMatches, $matches, array('_route' => 'route13')), array ());
+ }
+
+ // route14
+ if (0 === strpos($pathinfo, '/route14') && preg_match('#^/route14/(?P<name>[^/]++)$#sD', $pathinfo, $matches)) {
+ return $this->mergeDefaults(array_replace($hostMatches, $matches, array('_route' => 'route14')), array ( 'var1' => 'val',));
+ }
+
+ }
+
+ }
+
+ if (preg_match('#^c\\.example\\.com$#sDi', $host, $hostMatches)) {
+ // route15
+ if (0 === strpos($pathinfo, '/route15') && preg_match('#^/route15/(?P<name>[^/]++)$#sD', $pathinfo, $matches)) {
+ return $this->mergeDefaults(array_replace($matches, array('_route' => 'route15')), array ());
+ }
+
+ }
+
+ // route16
+ if (0 === strpos($pathinfo, '/route16') && preg_match('#^/route16/(?P<name>[^/]++)$#sD', $pathinfo, $matches)) {
+ return $this->mergeDefaults(array_replace($matches, array('_route' => 'route16')), array ( 'var1' => 'val',));
+ }
+
+ // route17
+ if ('/route17' === $pathinfo) {
+ return array('_route' => 'route17');
+ }
+
+ // a
+ if ('/a/a...' === $pathinfo) {
+ return array('_route' => 'a');
+ }
+
+ if (0 === strpos($pathinfo, '/a/b')) {
+ // b
+ if (preg_match('#^/a/b/(?P<var>[^/]++)$#sD', $pathinfo, $matches)) {
+ return $this->mergeDefaults(array_replace($matches, array('_route' => 'b')), array ());
+ }
+
+ // c
+ if (0 === strpos($pathinfo, '/a/b/c') && preg_match('#^/a/b/c/(?P<var>[^/]++)$#sD', $pathinfo, $matches)) {
+ return $this->mergeDefaults(array_replace($matches, array('_route' => 'c')), array ());
+ }
+
+ }
+
+ // secure
+ if ('/secure' === $pathinfo) {
+ $ret = array('_route' => 'secure');
+ $requiredSchemes = array ( 'https' => 0,);
+ if (!isset($requiredSchemes[$context->getScheme()])) {
+ if ('GET' !== $canonicalMethod) {
+ goto not_secure;
+ }
+
+ return array_replace($ret, $this->redirect($rawPathinfo, 'secure', key($requiredSchemes)));
+ }
+
+ return $ret;
+ }
+ not_secure:
+
+ // nonsecure
+ if ('/nonsecure' === $pathinfo) {
+ $ret = array('_route' => 'nonsecure');
+ $requiredSchemes = array ( 'http' => 0,);
+ if (!isset($requiredSchemes[$context->getScheme()])) {
+ if ('GET' !== $canonicalMethod) {
+ goto not_nonsecure;
+ }
+
+ return array_replace($ret, $this->redirect($rawPathinfo, 'nonsecure', key($requiredSchemes)));
+ }
+
+ return $ret;
+ }
+ not_nonsecure:
+
+ if ('/' === $pathinfo && !$allow) {
+ throw new Symfony\Component\Routing\Exception\NoConfigurationException();
+ }
+
+ throw 0 < count($allow) ? new MethodNotAllowedException(array_unique($allow)) : new ResourceNotFoundException();
+ }
+}
diff --git a/assets/php/vendor/symfony/routing/Tests/Fixtures/dumper/url_matcher3.php b/assets/php/vendor/symfony/routing/Tests/Fixtures/dumper/url_matcher3.php
new file mode 100644
index 0000000..67c4667
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Tests/Fixtures/dumper/url_matcher3.php
@@ -0,0 +1,55 @@
+<?php
+
+use Symfony\Component\Routing\Exception\MethodNotAllowedException;
+use Symfony\Component\Routing\Exception\ResourceNotFoundException;
+use Symfony\Component\Routing\RequestContext;
+
+/**
+ * This class has been auto-generated
+ * by the Symfony Routing Component.
+ */
+class ProjectUrlMatcher extends Symfony\Component\Routing\Matcher\UrlMatcher
+{
+ public function __construct(RequestContext $context)
+ {
+ $this->context = $context;
+ }
+
+ public function match($rawPathinfo)
+ {
+ $allow = array();
+ $pathinfo = rawurldecode($rawPathinfo);
+ $trimmedPathinfo = rtrim($pathinfo, '/');
+ $context = $this->context;
+ $request = $this->request ?: $this->createRequest($pathinfo);
+ $requestMethod = $canonicalMethod = $context->getMethod();
+
+ if ('HEAD' === $requestMethod) {
+ $canonicalMethod = 'GET';
+ }
+
+ if (0 === strpos($pathinfo, '/rootprefix')) {
+ // static
+ if ('/rootprefix/test' === $pathinfo) {
+ return array('_route' => 'static');
+ }
+
+ // dynamic
+ if (preg_match('#^/rootprefix/(?P<var>[^/]++)$#sD', $pathinfo, $matches)) {
+ return $this->mergeDefaults(array_replace($matches, array('_route' => 'dynamic')), array ());
+ }
+
+ }
+
+ // with-condition
+ if ('/with-condition' === $pathinfo && ($context->getMethod() == "GET")) {
+ return array('_route' => 'with-condition');
+ }
+
+ if ('/' === $pathinfo && !$allow) {
+ throw new Symfony\Component\Routing\Exception\NoConfigurationException();
+ }
+
+ throw 0 < count($allow) ? new MethodNotAllowedException(array_unique($allow)) : new ResourceNotFoundException();
+ }
+}
diff --git a/assets/php/vendor/symfony/routing/Tests/Fixtures/dumper/url_matcher4.php b/assets/php/vendor/symfony/routing/Tests/Fixtures/dumper/url_matcher4.php
new file mode 100644
index 0000000..ed07194
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Tests/Fixtures/dumper/url_matcher4.php
@@ -0,0 +1,112 @@
+<?php
+
+use Symfony\Component\Routing\Exception\MethodNotAllowedException;
+use Symfony\Component\Routing\Exception\ResourceNotFoundException;
+use Symfony\Component\Routing\RequestContext;
+
+/**
+ * This class has been auto-generated
+ * by the Symfony Routing Component.
+ */
+class ProjectUrlMatcher extends Symfony\Component\Routing\Matcher\UrlMatcher
+{
+ public function __construct(RequestContext $context)
+ {
+ $this->context = $context;
+ }
+
+ public function match($rawPathinfo)
+ {
+ $allow = array();
+ $pathinfo = rawurldecode($rawPathinfo);
+ $trimmedPathinfo = rtrim($pathinfo, '/');
+ $context = $this->context;
+ $request = $this->request ?: $this->createRequest($pathinfo);
+ $requestMethod = $canonicalMethod = $context->getMethod();
+
+ if ('HEAD' === $requestMethod) {
+ $canonicalMethod = 'GET';
+ }
+
+ // just_head
+ if ('/just_head' === $pathinfo) {
+ $ret = array('_route' => 'just_head');
+ if (!in_array($requestMethod, array('HEAD'))) {
+ $allow = array_merge($allow, array('HEAD'));
+ goto not_just_head;
+ }
+
+ return $ret;
+ }
+ not_just_head:
+
+ // head_and_get
+ if ('/head_and_get' === $pathinfo) {
+ $ret = array('_route' => 'head_and_get');
+ if (!in_array($canonicalMethod, array('HEAD', 'GET'))) {
+ $allow = array_merge($allow, array('HEAD', 'GET'));
+ goto not_head_and_get;
+ }
+
+ return $ret;
+ }
+ not_head_and_get:
+
+ // get_and_head
+ if ('/get_and_head' === $pathinfo) {
+ $ret = array('_route' => 'get_and_head');
+ if (!in_array($canonicalMethod, array('GET', 'HEAD'))) {
+ $allow = array_merge($allow, array('GET', 'HEAD'));
+ goto not_get_and_head;
+ }
+
+ return $ret;
+ }
+ not_get_and_head:
+
+ // post_and_head
+ if ('/post_and_head' === $pathinfo) {
+ $ret = array('_route' => 'post_and_head');
+ if (!in_array($requestMethod, array('POST', 'HEAD'))) {
+ $allow = array_merge($allow, array('POST', 'HEAD'));
+ goto not_post_and_head;
+ }
+
+ return $ret;
+ }
+ not_post_and_head:
+
+ if (0 === strpos($pathinfo, '/put_and_post')) {
+ // put_and_post
+ if ('/put_and_post' === $pathinfo) {
+ $ret = array('_route' => 'put_and_post');
+ if (!in_array($requestMethod, array('PUT', 'POST'))) {
+ $allow = array_merge($allow, array('PUT', 'POST'));
+ goto not_put_and_post;
+ }
+
+ return $ret;
+ }
+ not_put_and_post:
+
+ // put_and_get_and_head
+ if ('/put_and_post' === $pathinfo) {
+ $ret = array('_route' => 'put_and_get_and_head');
+ if (!in_array($canonicalMethod, array('PUT', 'GET', 'HEAD'))) {
+ $allow = array_merge($allow, array('PUT', 'GET', 'HEAD'));
+ goto not_put_and_get_and_head;
+ }
+
+ return $ret;
+ }
+ not_put_and_get_and_head:
+
+ }
+
+ if ('/' === $pathinfo && !$allow) {
+ throw new Symfony\Component\Routing\Exception\NoConfigurationException();
+ }
+
+ throw 0 < count($allow) ? new MethodNotAllowedException(array_unique($allow)) : new ResourceNotFoundException();
+ }
+}
diff --git a/assets/php/vendor/symfony/routing/Tests/Fixtures/dumper/url_matcher5.php b/assets/php/vendor/symfony/routing/Tests/Fixtures/dumper/url_matcher5.php
new file mode 100644
index 0000000..2b22513
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Tests/Fixtures/dumper/url_matcher5.php
@@ -0,0 +1,209 @@
+<?php
+
+use Symfony\Component\Routing\Exception\MethodNotAllowedException;
+use Symfony\Component\Routing\Exception\ResourceNotFoundException;
+use Symfony\Component\Routing\RequestContext;
+
+/**
+ * This class has been auto-generated
+ * by the Symfony Routing Component.
+ */
+class ProjectUrlMatcher extends Symfony\Component\Routing\Tests\Fixtures\RedirectableUrlMatcher
+{
+ public function __construct(RequestContext $context)
+ {
+ $this->context = $context;
+ }
+
+ public function match($rawPathinfo)
+ {
+ $allow = array();
+ $pathinfo = rawurldecode($rawPathinfo);
+ $trimmedPathinfo = rtrim($pathinfo, '/');
+ $context = $this->context;
+ $request = $this->request ?: $this->createRequest($pathinfo);
+ $requestMethod = $canonicalMethod = $context->getMethod();
+
+ if ('HEAD' === $requestMethod) {
+ $canonicalMethod = 'GET';
+ }
+
+ if (0 === strpos($pathinfo, '/a')) {
+ // a_first
+ if ('/a/11' === $pathinfo) {
+ return array('_route' => 'a_first');
+ }
+
+ // a_second
+ if ('/a/22' === $pathinfo) {
+ return array('_route' => 'a_second');
+ }
+
+ // a_third
+ if ('/a/333' === $pathinfo) {
+ return array('_route' => 'a_third');
+ }
+
+ }
+
+ // a_wildcard
+ if (preg_match('#^/(?P<param>[^/]++)$#sD', $pathinfo, $matches)) {
+ return $this->mergeDefaults(array_replace($matches, array('_route' => 'a_wildcard')), array ());
+ }
+
+ if (0 === strpos($pathinfo, '/a')) {
+ // a_fourth
+ if ('/a/44' === $trimmedPathinfo) {
+ $ret = array('_route' => 'a_fourth');
+ if ('/' === substr($pathinfo, -1)) {
+ // no-op
+ } elseif ('GET' !== $canonicalMethod) {
+ goto not_a_fourth;
+ } else {
+ return array_replace($ret, $this->redirect($rawPathinfo.'/', 'a_fourth'));
+ }
+
+ return $ret;
+ }
+ not_a_fourth:
+
+ // a_fifth
+ if ('/a/55' === $trimmedPathinfo) {
+ $ret = array('_route' => 'a_fifth');
+ if ('/' === substr($pathinfo, -1)) {
+ // no-op
+ } elseif ('GET' !== $canonicalMethod) {
+ goto not_a_fifth;
+ } else {
+ return array_replace($ret, $this->redirect($rawPathinfo.'/', 'a_fifth'));
+ }
+
+ return $ret;
+ }
+ not_a_fifth:
+
+ // a_sixth
+ if ('/a/66' === $trimmedPathinfo) {
+ $ret = array('_route' => 'a_sixth');
+ if ('/' === substr($pathinfo, -1)) {
+ // no-op
+ } elseif ('GET' !== $canonicalMethod) {
+ goto not_a_sixth;
+ } else {
+ return array_replace($ret, $this->redirect($rawPathinfo.'/', 'a_sixth'));
+ }
+
+ return $ret;
+ }
+ not_a_sixth:
+
+ }
+
+ // nested_wildcard
+ if (0 === strpos($pathinfo, '/nested') && preg_match('#^/nested/(?P<param>[^/]++)$#sD', $pathinfo, $matches)) {
+ return $this->mergeDefaults(array_replace($matches, array('_route' => 'nested_wildcard')), array ());
+ }
+
+ if (0 === strpos($pathinfo, '/nested/group')) {
+ // nested_a
+ if ('/nested/group/a' === $trimmedPathinfo) {
+ $ret = array('_route' => 'nested_a');
+ if ('/' === substr($pathinfo, -1)) {
+ // no-op
+ } elseif ('GET' !== $canonicalMethod) {
+ goto not_nested_a;
+ } else {
+ return array_replace($ret, $this->redirect($rawPathinfo.'/', 'nested_a'));
+ }
+
+ return $ret;
+ }
+ not_nested_a:
+
+ // nested_b
+ if ('/nested/group/b' === $trimmedPathinfo) {
+ $ret = array('_route' => 'nested_b');
+ if ('/' === substr($pathinfo, -1)) {
+ // no-op
+ } elseif ('GET' !== $canonicalMethod) {
+ goto not_nested_b;
+ } else {
+ return array_replace($ret, $this->redirect($rawPathinfo.'/', 'nested_b'));
+ }
+
+ return $ret;
+ }
+ not_nested_b:
+
+ // nested_c
+ if ('/nested/group/c' === $trimmedPathinfo) {
+ $ret = array('_route' => 'nested_c');
+ if ('/' === substr($pathinfo, -1)) {
+ // no-op
+ } elseif ('GET' !== $canonicalMethod) {
+ goto not_nested_c;
+ } else {
+ return array_replace($ret, $this->redirect($rawPathinfo.'/', 'nested_c'));
+ }
+
+ return $ret;
+ }
+ not_nested_c:
+
+ }
+
+ elseif (0 === strpos($pathinfo, '/slashed/group')) {
+ // slashed_a
+ if ('/slashed/group' === $trimmedPathinfo) {
+ $ret = array('_route' => 'slashed_a');
+ if ('/' === substr($pathinfo, -1)) {
+ // no-op
+ } elseif ('GET' !== $canonicalMethod) {
+ goto not_slashed_a;
+ } else {
+ return array_replace($ret, $this->redirect($rawPathinfo.'/', 'slashed_a'));
+ }
+
+ return $ret;
+ }
+ not_slashed_a:
+
+ // slashed_b
+ if ('/slashed/group/b' === $trimmedPathinfo) {
+ $ret = array('_route' => 'slashed_b');
+ if ('/' === substr($pathinfo, -1)) {
+ // no-op
+ } elseif ('GET' !== $canonicalMethod) {
+ goto not_slashed_b;
+ } else {
+ return array_replace($ret, $this->redirect($rawPathinfo.'/', 'slashed_b'));
+ }
+
+ return $ret;
+ }
+ not_slashed_b:
+
+ // slashed_c
+ if ('/slashed/group/c' === $trimmedPathinfo) {
+ $ret = array('_route' => 'slashed_c');
+ if ('/' === substr($pathinfo, -1)) {
+ // no-op
+ } elseif ('GET' !== $canonicalMethod) {
+ goto not_slashed_c;
+ } else {
+ return array_replace($ret, $this->redirect($rawPathinfo.'/', 'slashed_c'));
+ }
+
+ return $ret;
+ }
+ not_slashed_c:
+
+ }
+
+ if ('/' === $pathinfo && !$allow) {
+ throw new Symfony\Component\Routing\Exception\NoConfigurationException();
+ }
+
+ throw 0 < count($allow) ? new MethodNotAllowedException(array_unique($allow)) : new ResourceNotFoundException();
+ }
+}
diff --git a/assets/php/vendor/symfony/routing/Tests/Fixtures/dumper/url_matcher6.php b/assets/php/vendor/symfony/routing/Tests/Fixtures/dumper/url_matcher6.php
new file mode 100644
index 0000000..48ecdf8
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Tests/Fixtures/dumper/url_matcher6.php
@@ -0,0 +1,213 @@
+<?php
+
+use Symfony\Component\Routing\Exception\MethodNotAllowedException;
+use Symfony\Component\Routing\Exception\ResourceNotFoundException;
+use Symfony\Component\Routing\RequestContext;
+
+/**
+ * This class has been auto-generated
+ * by the Symfony Routing Component.
+ */
+class ProjectUrlMatcher extends Symfony\Component\Routing\Matcher\UrlMatcher
+{
+ public function __construct(RequestContext $context)
+ {
+ $this->context = $context;
+ }
+
+ public function match($rawPathinfo)
+ {
+ $allow = array();
+ $pathinfo = rawurldecode($rawPathinfo);
+ $trimmedPathinfo = rtrim($pathinfo, '/');
+ $context = $this->context;
+ $request = $this->request ?: $this->createRequest($pathinfo);
+ $requestMethod = $canonicalMethod = $context->getMethod();
+
+ if ('HEAD' === $requestMethod) {
+ $canonicalMethod = 'GET';
+ }
+
+ if (0 === strpos($pathinfo, '/trailing/simple')) {
+ // simple_trailing_slash_no_methods
+ if ('/trailing/simple/no-methods/' === $pathinfo) {
+ return array('_route' => 'simple_trailing_slash_no_methods');
+ }
+
+ // simple_trailing_slash_GET_method
+ if ('/trailing/simple/get-method/' === $pathinfo) {
+ $ret = array('_route' => 'simple_trailing_slash_GET_method');
+ if (!in_array($canonicalMethod, array('GET'))) {
+ $allow = array_merge($allow, array('GET'));
+ goto not_simple_trailing_slash_GET_method;
+ }
+
+ return $ret;
+ }
+ not_simple_trailing_slash_GET_method:
+
+ // simple_trailing_slash_HEAD_method
+ if ('/trailing/simple/head-method/' === $pathinfo) {
+ $ret = array('_route' => 'simple_trailing_slash_HEAD_method');
+ if (!in_array($requestMethod, array('HEAD'))) {
+ $allow = array_merge($allow, array('HEAD'));
+ goto not_simple_trailing_slash_HEAD_method;
+ }
+
+ return $ret;
+ }
+ not_simple_trailing_slash_HEAD_method:
+
+ // simple_trailing_slash_POST_method
+ if ('/trailing/simple/post-method/' === $pathinfo) {
+ $ret = array('_route' => 'simple_trailing_slash_POST_method');
+ if (!in_array($requestMethod, array('POST'))) {
+ $allow = array_merge($allow, array('POST'));
+ goto not_simple_trailing_slash_POST_method;
+ }
+
+ return $ret;
+ }
+ not_simple_trailing_slash_POST_method:
+
+ }
+
+ elseif (0 === strpos($pathinfo, '/trailing/regex')) {
+ // regex_trailing_slash_no_methods
+ if (0 === strpos($pathinfo, '/trailing/regex/no-methods') && preg_match('#^/trailing/regex/no\\-methods/(?P<param>[^/]++)/$#sD', $pathinfo, $matches)) {
+ return $this->mergeDefaults(array_replace($matches, array('_route' => 'regex_trailing_slash_no_methods')), array ());
+ }
+
+ // regex_trailing_slash_GET_method
+ if (0 === strpos($pathinfo, '/trailing/regex/get-method') && preg_match('#^/trailing/regex/get\\-method/(?P<param>[^/]++)/$#sD', $pathinfo, $matches)) {
+ $ret = $this->mergeDefaults(array_replace($matches, array('_route' => 'regex_trailing_slash_GET_method')), array ());
+ if (!in_array($canonicalMethod, array('GET'))) {
+ $allow = array_merge($allow, array('GET'));
+ goto not_regex_trailing_slash_GET_method;
+ }
+
+ return $ret;
+ }
+ not_regex_trailing_slash_GET_method:
+
+ // regex_trailing_slash_HEAD_method
+ if (0 === strpos($pathinfo, '/trailing/regex/head-method') && preg_match('#^/trailing/regex/head\\-method/(?P<param>[^/]++)/$#sD', $pathinfo, $matches)) {
+ $ret = $this->mergeDefaults(array_replace($matches, array('_route' => 'regex_trailing_slash_HEAD_method')), array ());
+ if (!in_array($requestMethod, array('HEAD'))) {
+ $allow = array_merge($allow, array('HEAD'));
+ goto not_regex_trailing_slash_HEAD_method;
+ }
+
+ return $ret;
+ }
+ not_regex_trailing_slash_HEAD_method:
+
+ // regex_trailing_slash_POST_method
+ if (0 === strpos($pathinfo, '/trailing/regex/post-method') && preg_match('#^/trailing/regex/post\\-method/(?P<param>[^/]++)/$#sD', $pathinfo, $matches)) {
+ $ret = $this->mergeDefaults(array_replace($matches, array('_route' => 'regex_trailing_slash_POST_method')), array ());
+ if (!in_array($requestMethod, array('POST'))) {
+ $allow = array_merge($allow, array('POST'));
+ goto not_regex_trailing_slash_POST_method;
+ }
+
+ return $ret;
+ }
+ not_regex_trailing_slash_POST_method:
+
+ }
+
+ elseif (0 === strpos($pathinfo, '/not-trailing/simple')) {
+ // simple_not_trailing_slash_no_methods
+ if ('/not-trailing/simple/no-methods' === $pathinfo) {
+ return array('_route' => 'simple_not_trailing_slash_no_methods');
+ }
+
+ // simple_not_trailing_slash_GET_method
+ if ('/not-trailing/simple/get-method' === $pathinfo) {
+ $ret = array('_route' => 'simple_not_trailing_slash_GET_method');
+ if (!in_array($canonicalMethod, array('GET'))) {
+ $allow = array_merge($allow, array('GET'));
+ goto not_simple_not_trailing_slash_GET_method;
+ }
+
+ return $ret;
+ }
+ not_simple_not_trailing_slash_GET_method:
+
+ // simple_not_trailing_slash_HEAD_method
+ if ('/not-trailing/simple/head-method' === $pathinfo) {
+ $ret = array('_route' => 'simple_not_trailing_slash_HEAD_method');
+ if (!in_array($requestMethod, array('HEAD'))) {
+ $allow = array_merge($allow, array('HEAD'));
+ goto not_simple_not_trailing_slash_HEAD_method;
+ }
+
+ return $ret;
+ }
+ not_simple_not_trailing_slash_HEAD_method:
+
+ // simple_not_trailing_slash_POST_method
+ if ('/not-trailing/simple/post-method' === $pathinfo) {
+ $ret = array('_route' => 'simple_not_trailing_slash_POST_method');
+ if (!in_array($requestMethod, array('POST'))) {
+ $allow = array_merge($allow, array('POST'));
+ goto not_simple_not_trailing_slash_POST_method;
+ }
+
+ return $ret;
+ }
+ not_simple_not_trailing_slash_POST_method:
+
+ }
+
+ elseif (0 === strpos($pathinfo, '/not-trailing/regex')) {
+ // regex_not_trailing_slash_no_methods
+ if (0 === strpos($pathinfo, '/not-trailing/regex/no-methods') && preg_match('#^/not\\-trailing/regex/no\\-methods/(?P<param>[^/]++)$#sD', $pathinfo, $matches)) {
+ return $this->mergeDefaults(array_replace($matches, array('_route' => 'regex_not_trailing_slash_no_methods')), array ());
+ }
+
+ // regex_not_trailing_slash_GET_method
+ if (0 === strpos($pathinfo, '/not-trailing/regex/get-method') && preg_match('#^/not\\-trailing/regex/get\\-method/(?P<param>[^/]++)$#sD', $pathinfo, $matches)) {
+ $ret = $this->mergeDefaults(array_replace($matches, array('_route' => 'regex_not_trailing_slash_GET_method')), array ());
+ if (!in_array($canonicalMethod, array('GET'))) {
+ $allow = array_merge($allow, array('GET'));
+ goto not_regex_not_trailing_slash_GET_method;
+ }
+
+ return $ret;
+ }
+ not_regex_not_trailing_slash_GET_method:
+
+ // regex_not_trailing_slash_HEAD_method
+ if (0 === strpos($pathinfo, '/not-trailing/regex/head-method') && preg_match('#^/not\\-trailing/regex/head\\-method/(?P<param>[^/]++)$#sD', $pathinfo, $matches)) {
+ $ret = $this->mergeDefaults(array_replace($matches, array('_route' => 'regex_not_trailing_slash_HEAD_method')), array ());
+ if (!in_array($requestMethod, array('HEAD'))) {
+ $allow = array_merge($allow, array('HEAD'));
+ goto not_regex_not_trailing_slash_HEAD_method;
+ }
+
+ return $ret;
+ }
+ not_regex_not_trailing_slash_HEAD_method:
+
+ // regex_not_trailing_slash_POST_method
+ if (0 === strpos($pathinfo, '/not-trailing/regex/post-method') && preg_match('#^/not\\-trailing/regex/post\\-method/(?P<param>[^/]++)$#sD', $pathinfo, $matches)) {
+ $ret = $this->mergeDefaults(array_replace($matches, array('_route' => 'regex_not_trailing_slash_POST_method')), array ());
+ if (!in_array($requestMethod, array('POST'))) {
+ $allow = array_merge($allow, array('POST'));
+ goto not_regex_not_trailing_slash_POST_method;
+ }
+
+ return $ret;
+ }
+ not_regex_not_trailing_slash_POST_method:
+
+ }
+
+ if ('/' === $pathinfo && !$allow) {
+ throw new Symfony\Component\Routing\Exception\NoConfigurationException();
+ }
+
+ throw 0 < count($allow) ? new MethodNotAllowedException(array_unique($allow)) : new ResourceNotFoundException();
+ }
+}
diff --git a/assets/php/vendor/symfony/routing/Tests/Fixtures/dumper/url_matcher7.php b/assets/php/vendor/symfony/routing/Tests/Fixtures/dumper/url_matcher7.php
new file mode 100644
index 0000000..81d76ea
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Tests/Fixtures/dumper/url_matcher7.php
@@ -0,0 +1,249 @@
+<?php
+
+use Symfony\Component\Routing\Exception\MethodNotAllowedException;
+use Symfony\Component\Routing\Exception\ResourceNotFoundException;
+use Symfony\Component\Routing\RequestContext;
+
+/**
+ * This class has been auto-generated
+ * by the Symfony Routing Component.
+ */
+class ProjectUrlMatcher extends Symfony\Component\Routing\Tests\Fixtures\RedirectableUrlMatcher
+{
+ public function __construct(RequestContext $context)
+ {
+ $this->context = $context;
+ }
+
+ public function match($rawPathinfo)
+ {
+ $allow = array();
+ $pathinfo = rawurldecode($rawPathinfo);
+ $trimmedPathinfo = rtrim($pathinfo, '/');
+ $context = $this->context;
+ $request = $this->request ?: $this->createRequest($pathinfo);
+ $requestMethod = $canonicalMethod = $context->getMethod();
+
+ if ('HEAD' === $requestMethod) {
+ $canonicalMethod = 'GET';
+ }
+
+ if (0 === strpos($pathinfo, '/trailing/simple')) {
+ // simple_trailing_slash_no_methods
+ if ('/trailing/simple/no-methods' === $trimmedPathinfo) {
+ $ret = array('_route' => 'simple_trailing_slash_no_methods');
+ if ('/' === substr($pathinfo, -1)) {
+ // no-op
+ } elseif ('GET' !== $canonicalMethod) {
+ goto not_simple_trailing_slash_no_methods;
+ } else {
+ return array_replace($ret, $this->redirect($rawPathinfo.'/', 'simple_trailing_slash_no_methods'));
+ }
+
+ return $ret;
+ }
+ not_simple_trailing_slash_no_methods:
+
+ // simple_trailing_slash_GET_method
+ if ('/trailing/simple/get-method' === $trimmedPathinfo) {
+ $ret = array('_route' => 'simple_trailing_slash_GET_method');
+ if ('/' === substr($pathinfo, -1)) {
+ // no-op
+ } elseif ('GET' !== $canonicalMethod) {
+ goto not_simple_trailing_slash_GET_method;
+ } else {
+ return array_replace($ret, $this->redirect($rawPathinfo.'/', 'simple_trailing_slash_GET_method'));
+ }
+
+ if (!in_array($canonicalMethod, array('GET'))) {
+ $allow = array_merge($allow, array('GET'));
+ goto not_simple_trailing_slash_GET_method;
+ }
+
+ return $ret;
+ }
+ not_simple_trailing_slash_GET_method:
+
+ // simple_trailing_slash_HEAD_method
+ if ('/trailing/simple/head-method/' === $pathinfo) {
+ $ret = array('_route' => 'simple_trailing_slash_HEAD_method');
+ if (!in_array($requestMethod, array('HEAD'))) {
+ $allow = array_merge($allow, array('HEAD'));
+ goto not_simple_trailing_slash_HEAD_method;
+ }
+
+ return $ret;
+ }
+ not_simple_trailing_slash_HEAD_method:
+
+ // simple_trailing_slash_POST_method
+ if ('/trailing/simple/post-method/' === $pathinfo) {
+ $ret = array('_route' => 'simple_trailing_slash_POST_method');
+ if (!in_array($requestMethod, array('POST'))) {
+ $allow = array_merge($allow, array('POST'));
+ goto not_simple_trailing_slash_POST_method;
+ }
+
+ return $ret;
+ }
+ not_simple_trailing_slash_POST_method:
+
+ }
+
+ elseif (0 === strpos($pathinfo, '/trailing/regex')) {
+ // regex_trailing_slash_no_methods
+ if (0 === strpos($pathinfo, '/trailing/regex/no-methods') && preg_match('#^/trailing/regex/no\\-methods/(?P<param>[^/]++)/?$#sD', $pathinfo, $matches)) {
+ $ret = $this->mergeDefaults(array_replace($matches, array('_route' => 'regex_trailing_slash_no_methods')), array ());
+ if ('/' === substr($pathinfo, -1)) {
+ // no-op
+ } elseif ('GET' !== $canonicalMethod) {
+ goto not_regex_trailing_slash_no_methods;
+ } else {
+ return array_replace($ret, $this->redirect($rawPathinfo.'/', 'regex_trailing_slash_no_methods'));
+ }
+
+ return $ret;
+ }
+ not_regex_trailing_slash_no_methods:
+
+ // regex_trailing_slash_GET_method
+ if (0 === strpos($pathinfo, '/trailing/regex/get-method') && preg_match('#^/trailing/regex/get\\-method/(?P<param>[^/]++)/?$#sD', $pathinfo, $matches)) {
+ $ret = $this->mergeDefaults(array_replace($matches, array('_route' => 'regex_trailing_slash_GET_method')), array ());
+ if ('/' === substr($pathinfo, -1)) {
+ // no-op
+ } elseif ('GET' !== $canonicalMethod) {
+ goto not_regex_trailing_slash_GET_method;
+ } else {
+ return array_replace($ret, $this->redirect($rawPathinfo.'/', 'regex_trailing_slash_GET_method'));
+ }
+
+ if (!in_array($canonicalMethod, array('GET'))) {
+ $allow = array_merge($allow, array('GET'));
+ goto not_regex_trailing_slash_GET_method;
+ }
+
+ return $ret;
+ }
+ not_regex_trailing_slash_GET_method:
+
+ // regex_trailing_slash_HEAD_method
+ if (0 === strpos($pathinfo, '/trailing/regex/head-method') && preg_match('#^/trailing/regex/head\\-method/(?P<param>[^/]++)/$#sD', $pathinfo, $matches)) {
+ $ret = $this->mergeDefaults(array_replace($matches, array('_route' => 'regex_trailing_slash_HEAD_method')), array ());
+ if (!in_array($requestMethod, array('HEAD'))) {
+ $allow = array_merge($allow, array('HEAD'));
+ goto not_regex_trailing_slash_HEAD_method;
+ }
+
+ return $ret;
+ }
+ not_regex_trailing_slash_HEAD_method:
+
+ // regex_trailing_slash_POST_method
+ if (0 === strpos($pathinfo, '/trailing/regex/post-method') && preg_match('#^/trailing/regex/post\\-method/(?P<param>[^/]++)/$#sD', $pathinfo, $matches)) {
+ $ret = $this->mergeDefaults(array_replace($matches, array('_route' => 'regex_trailing_slash_POST_method')), array ());
+ if (!in_array($requestMethod, array('POST'))) {
+ $allow = array_merge($allow, array('POST'));
+ goto not_regex_trailing_slash_POST_method;
+ }
+
+ return $ret;
+ }
+ not_regex_trailing_slash_POST_method:
+
+ }
+
+ elseif (0 === strpos($pathinfo, '/not-trailing/simple')) {
+ // simple_not_trailing_slash_no_methods
+ if ('/not-trailing/simple/no-methods' === $pathinfo) {
+ return array('_route' => 'simple_not_trailing_slash_no_methods');
+ }
+
+ // simple_not_trailing_slash_GET_method
+ if ('/not-trailing/simple/get-method' === $pathinfo) {
+ $ret = array('_route' => 'simple_not_trailing_slash_GET_method');
+ if (!in_array($canonicalMethod, array('GET'))) {
+ $allow = array_merge($allow, array('GET'));
+ goto not_simple_not_trailing_slash_GET_method;
+ }
+
+ return $ret;
+ }
+ not_simple_not_trailing_slash_GET_method:
+
+ // simple_not_trailing_slash_HEAD_method
+ if ('/not-trailing/simple/head-method' === $pathinfo) {
+ $ret = array('_route' => 'simple_not_trailing_slash_HEAD_method');
+ if (!in_array($requestMethod, array('HEAD'))) {
+ $allow = array_merge($allow, array('HEAD'));
+ goto not_simple_not_trailing_slash_HEAD_method;
+ }
+
+ return $ret;
+ }
+ not_simple_not_trailing_slash_HEAD_method:
+
+ // simple_not_trailing_slash_POST_method
+ if ('/not-trailing/simple/post-method' === $pathinfo) {
+ $ret = array('_route' => 'simple_not_trailing_slash_POST_method');
+ if (!in_array($requestMethod, array('POST'))) {
+ $allow = array_merge($allow, array('POST'));
+ goto not_simple_not_trailing_slash_POST_method;
+ }
+
+ return $ret;
+ }
+ not_simple_not_trailing_slash_POST_method:
+
+ }
+
+ elseif (0 === strpos($pathinfo, '/not-trailing/regex')) {
+ // regex_not_trailing_slash_no_methods
+ if (0 === strpos($pathinfo, '/not-trailing/regex/no-methods') && preg_match('#^/not\\-trailing/regex/no\\-methods/(?P<param>[^/]++)$#sD', $pathinfo, $matches)) {
+ return $this->mergeDefaults(array_replace($matches, array('_route' => 'regex_not_trailing_slash_no_methods')), array ());
+ }
+
+ // regex_not_trailing_slash_GET_method
+ if (0 === strpos($pathinfo, '/not-trailing/regex/get-method') && preg_match('#^/not\\-trailing/regex/get\\-method/(?P<param>[^/]++)$#sD', $pathinfo, $matches)) {
+ $ret = $this->mergeDefaults(array_replace($matches, array('_route' => 'regex_not_trailing_slash_GET_method')), array ());
+ if (!in_array($canonicalMethod, array('GET'))) {
+ $allow = array_merge($allow, array('GET'));
+ goto not_regex_not_trailing_slash_GET_method;
+ }
+
+ return $ret;
+ }
+ not_regex_not_trailing_slash_GET_method:
+
+ // regex_not_trailing_slash_HEAD_method
+ if (0 === strpos($pathinfo, '/not-trailing/regex/head-method') && preg_match('#^/not\\-trailing/regex/head\\-method/(?P<param>[^/]++)$#sD', $pathinfo, $matches)) {
+ $ret = $this->mergeDefaults(array_replace($matches, array('_route' => 'regex_not_trailing_slash_HEAD_method')), array ());
+ if (!in_array($requestMethod, array('HEAD'))) {
+ $allow = array_merge($allow, array('HEAD'));
+ goto not_regex_not_trailing_slash_HEAD_method;
+ }
+
+ return $ret;
+ }
+ not_regex_not_trailing_slash_HEAD_method:
+
+ // regex_not_trailing_slash_POST_method
+ if (0 === strpos($pathinfo, '/not-trailing/regex/post-method') && preg_match('#^/not\\-trailing/regex/post\\-method/(?P<param>[^/]++)$#sD', $pathinfo, $matches)) {
+ $ret = $this->mergeDefaults(array_replace($matches, array('_route' => 'regex_not_trailing_slash_POST_method')), array ());
+ if (!in_array($requestMethod, array('POST'))) {
+ $allow = array_merge($allow, array('POST'));
+ goto not_regex_not_trailing_slash_POST_method;
+ }
+
+ return $ret;
+ }
+ not_regex_not_trailing_slash_POST_method:
+
+ }
+
+ if ('/' === $pathinfo && !$allow) {
+ throw new Symfony\Component\Routing\Exception\NoConfigurationException();
+ }
+
+ throw 0 < count($allow) ? new MethodNotAllowedException(array_unique($allow)) : new ResourceNotFoundException();
+ }
+}
diff --git a/assets/php/vendor/symfony/routing/Tests/Fixtures/empty.yml b/assets/php/vendor/symfony/routing/Tests/Fixtures/empty.yml
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Tests/Fixtures/empty.yml
diff --git a/assets/php/vendor/symfony/routing/Tests/Fixtures/file_resource.yml b/assets/php/vendor/symfony/routing/Tests/Fixtures/file_resource.yml
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Tests/Fixtures/file_resource.yml
diff --git a/assets/php/vendor/symfony/routing/Tests/Fixtures/foo.xml b/assets/php/vendor/symfony/routing/Tests/Fixtures/foo.xml
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Tests/Fixtures/foo.xml
diff --git a/assets/php/vendor/symfony/routing/Tests/Fixtures/foo1.xml b/assets/php/vendor/symfony/routing/Tests/Fixtures/foo1.xml
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Tests/Fixtures/foo1.xml
diff --git a/assets/php/vendor/symfony/routing/Tests/Fixtures/glob/bar.xml b/assets/php/vendor/symfony/routing/Tests/Fixtures/glob/bar.xml
new file mode 100644
index 0000000..0d31eeb
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Tests/Fixtures/glob/bar.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<routes xmlns="http://symfony.com/schema/routing"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://symfony.com/schema/routing
+ http://symfony.com/schema/routing/routing-1.0.xsd">
+
+ <route id="bar_route" path="/bar" controller="AppBundle:Bar:view" />
+</routes>
diff --git a/assets/php/vendor/symfony/routing/Tests/Fixtures/glob/bar.yml b/assets/php/vendor/symfony/routing/Tests/Fixtures/glob/bar.yml
new file mode 100644
index 0000000..ba3bc22
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Tests/Fixtures/glob/bar.yml
@@ -0,0 +1,4 @@
+bar_route:
+ path: /bar
+ defaults:
+ _controller: AppBundle:Bar:view
diff --git a/assets/php/vendor/symfony/routing/Tests/Fixtures/glob/baz.xml b/assets/php/vendor/symfony/routing/Tests/Fixtures/glob/baz.xml
new file mode 100644
index 0000000..3abba1a
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Tests/Fixtures/glob/baz.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<routes xmlns="http://symfony.com/schema/routing"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://symfony.com/schema/routing
+ http://symfony.com/schema/routing/routing-1.0.xsd">
+
+ <route id="baz_route" path="/baz" controller="AppBundle:Baz:view" />
+</routes>
diff --git a/assets/php/vendor/symfony/routing/Tests/Fixtures/glob/baz.yml b/assets/php/vendor/symfony/routing/Tests/Fixtures/glob/baz.yml
new file mode 100644
index 0000000..f7d8c67
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Tests/Fixtures/glob/baz.yml
@@ -0,0 +1,4 @@
+baz_route:
+ path: /baz
+ defaults:
+ _controller: AppBundle:Baz:view
diff --git a/assets/php/vendor/symfony/routing/Tests/Fixtures/glob/import_multiple.xml b/assets/php/vendor/symfony/routing/Tests/Fixtures/glob/import_multiple.xml
new file mode 100644
index 0000000..ca6b1b5
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Tests/Fixtures/glob/import_multiple.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<routes xmlns="http://symfony.com/schema/routing"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://symfony.com/schema/routing
+ http://symfony.com/schema/routing/routing-1.0.xsd">
+
+ <import resource="ba?.xml" />
+</routes>
diff --git a/assets/php/vendor/symfony/routing/Tests/Fixtures/glob/import_multiple.yml b/assets/php/vendor/symfony/routing/Tests/Fixtures/glob/import_multiple.yml
new file mode 100644
index 0000000..d1ae585
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Tests/Fixtures/glob/import_multiple.yml
@@ -0,0 +1,2 @@
+_static:
+ resource: ba?.yml
diff --git a/assets/php/vendor/symfony/routing/Tests/Fixtures/glob/import_single.xml b/assets/php/vendor/symfony/routing/Tests/Fixtures/glob/import_single.xml
new file mode 100644
index 0000000..15f5698
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Tests/Fixtures/glob/import_single.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<routes xmlns="http://symfony.com/schema/routing"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://symfony.com/schema/routing
+ http://symfony.com/schema/routing/routing-1.0.xsd">
+
+ <import resource="b?r.xml" />
+</routes>
diff --git a/assets/php/vendor/symfony/routing/Tests/Fixtures/glob/import_single.yml b/assets/php/vendor/symfony/routing/Tests/Fixtures/glob/import_single.yml
new file mode 100644
index 0000000..f56ddbd
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Tests/Fixtures/glob/import_single.yml
@@ -0,0 +1,2 @@
+_static:
+ resource: b?r.yml
diff --git a/assets/php/vendor/symfony/routing/Tests/Fixtures/glob/php_dsl.php b/assets/php/vendor/symfony/routing/Tests/Fixtures/glob/php_dsl.php
new file mode 100644
index 0000000..897fa11
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Tests/Fixtures/glob/php_dsl.php
@@ -0,0 +1,7 @@
+<?php
+
+namespace Symfony\Component\Routing\Loader\Configurator;
+
+return function (RoutingConfigurator $routes) {
+ return $routes->import('php_dsl_ba?.php');
+};
diff --git a/assets/php/vendor/symfony/routing/Tests/Fixtures/glob/php_dsl_bar.php b/assets/php/vendor/symfony/routing/Tests/Fixtures/glob/php_dsl_bar.php
new file mode 100644
index 0000000..e2b91b1
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Tests/Fixtures/glob/php_dsl_bar.php
@@ -0,0 +1,12 @@
+<?php
+
+namespace Symfony\Component\Routing\Loader\Configurator;
+
+return function (RoutingConfigurator $routes) {
+ $collection = $routes->collection();
+
+ $collection->add('bar_route', '/bar')
+ ->defaults(array('_controller' => 'AppBundle:Bar:view'));
+
+ return $collection;
+};
diff --git a/assets/php/vendor/symfony/routing/Tests/Fixtures/glob/php_dsl_baz.php b/assets/php/vendor/symfony/routing/Tests/Fixtures/glob/php_dsl_baz.php
new file mode 100644
index 0000000..ca8f188
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Tests/Fixtures/glob/php_dsl_baz.php
@@ -0,0 +1,12 @@
+<?php
+
+namespace Symfony\Component\Routing\Loader\Configurator;
+
+return function (RoutingConfigurator $routes) {
+ $collection = $routes->collection();
+
+ $collection->add('baz_route', '/baz')
+ ->defaults(array('_controller' => 'AppBundle:Baz:view'));
+
+ return $collection;
+};
diff --git a/assets/php/vendor/symfony/routing/Tests/Fixtures/incomplete.yml b/assets/php/vendor/symfony/routing/Tests/Fixtures/incomplete.yml
new file mode 100644
index 0000000..df64d32
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Tests/Fixtures/incomplete.yml
@@ -0,0 +1,2 @@
+blog_show:
+ defaults: { _controller: MyBlogBundle:Blog:show }
diff --git a/assets/php/vendor/symfony/routing/Tests/Fixtures/list_defaults.xml b/assets/php/vendor/symfony/routing/Tests/Fixtures/list_defaults.xml
new file mode 100644
index 0000000..f93bf9c
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Tests/Fixtures/list_defaults.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<routes xmlns="http://symfony.com/schema/routing"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://symfony.com/schema/routing
+ http://symfony.com/schema/routing/routing-1.0.xsd">
+
+ <route id="blog" path="/blog">
+ <default key="_controller">
+ <string>AcmeBlogBundle:Blog:index</string>
+ </default>
+ <default key="values">
+ <list>
+ <bool>true</bool>
+ <int>1</int>
+ <float>3.5</float>
+ <string>foo</string>
+ </list>
+ </default>
+ </route>
+</routes>
diff --git a/assets/php/vendor/symfony/routing/Tests/Fixtures/list_in_list_defaults.xml b/assets/php/vendor/symfony/routing/Tests/Fixtures/list_in_list_defaults.xml
new file mode 100644
index 0000000..987086d
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Tests/Fixtures/list_in_list_defaults.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<routes xmlns="http://symfony.com/schema/routing"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://symfony.com/schema/routing
+ http://symfony.com/schema/routing/routing-1.0.xsd">
+
+ <route id="blog" path="/blog">
+ <default key="_controller">
+ <string>AcmeBlogBundle:Blog:index</string>
+ </default>
+ <default key="values">
+ <list>
+ <list>
+ <bool>true</bool>
+ <int>1</int>
+ <float>3.5</float>
+ <string>foo</string>
+ </list>
+ </list>
+ </default>
+ </route>
+</routes>
diff --git a/assets/php/vendor/symfony/routing/Tests/Fixtures/list_in_map_defaults.xml b/assets/php/vendor/symfony/routing/Tests/Fixtures/list_in_map_defaults.xml
new file mode 100644
index 0000000..32d393c
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Tests/Fixtures/list_in_map_defaults.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<routes xmlns="http://symfony.com/schema/routing"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://symfony.com/schema/routing
+ http://symfony.com/schema/routing/routing-1.0.xsd">
+
+ <route id="blog" path="/blog">
+ <default key="_controller">
+ <string>AcmeBlogBundle:Blog:index</string>
+ </default>
+ <default key="values">
+ <map>
+ <list key="list">
+ <bool>true</bool>
+ <int>1</int>
+ <float>3.5</float>
+ <string>foo</string>
+ </list>
+ </map>
+ </default>
+ </route>
+</routes>
diff --git a/assets/php/vendor/symfony/routing/Tests/Fixtures/list_null_values.xml b/assets/php/vendor/symfony/routing/Tests/Fixtures/list_null_values.xml
new file mode 100644
index 0000000..c70e03c
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Tests/Fixtures/list_null_values.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<routes xmlns="http://symfony.com/schema/routing"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://symfony.com/schema/routing
+ http://symfony.com/schema/routing/routing-1.0.xsd">
+
+ <route id="blog" path="/blog">
+ <default key="_controller">
+ <string>AcmeBlogBundle:Blog:index</string>
+ </default>
+ <default key="list">
+ <list>
+ <bool xsi:nil="true" />
+ <int xsi:nil="true" />
+ <float xsi:nil="1" />
+ <string xsi:nil="true" />
+ <list xsi:nil="true" />
+ <map xsi:nil="true" />
+ </list>
+ </default>
+ </route>
+</routes>
diff --git a/assets/php/vendor/symfony/routing/Tests/Fixtures/map_defaults.xml b/assets/php/vendor/symfony/routing/Tests/Fixtures/map_defaults.xml
new file mode 100644
index 0000000..47feb29
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Tests/Fixtures/map_defaults.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<routes xmlns="http://symfony.com/schema/routing"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://symfony.com/schema/routing
+ http://symfony.com/schema/routing/routing-1.0.xsd">
+
+ <route id="blog" path="/blog">
+ <default key="_controller">
+ <string>AcmeBlogBundle:Blog:index</string>
+ </default>
+ <default key="values">
+ <map>
+ <bool key="public">true</bool>
+ <int key="page">1</int>
+ <float key="price">3.5</float>
+ <string key="title">foo</string>
+ </map>
+ </default>
+ </route>
+</routes>
diff --git a/assets/php/vendor/symfony/routing/Tests/Fixtures/map_in_list_defaults.xml b/assets/php/vendor/symfony/routing/Tests/Fixtures/map_in_list_defaults.xml
new file mode 100644
index 0000000..6d77065
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Tests/Fixtures/map_in_list_defaults.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<routes xmlns="http://symfony.com/schema/routing"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://symfony.com/schema/routing
+ http://symfony.com/schema/routing/routing-1.0.xsd">
+
+ <route id="blog" path="/blog">
+ <default key="_controller">
+ <string>AcmeBlogBundle:Blog:index</string>
+ </default>
+ <default key="values">
+ <list>
+ <map>
+ <bool key="public">true</bool>
+ <int key="page">1</int>
+ <float key="price">3.5</float>
+ <string key="title">foo</string>
+ </map>
+ </list>
+ </default>
+ </route>
+</routes>
diff --git a/assets/php/vendor/symfony/routing/Tests/Fixtures/map_in_map_defaults.xml b/assets/php/vendor/symfony/routing/Tests/Fixtures/map_in_map_defaults.xml
new file mode 100644
index 0000000..2beee61
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Tests/Fixtures/map_in_map_defaults.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<routes xmlns="http://symfony.com/schema/routing"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://symfony.com/schema/routing
+ http://symfony.com/schema/routing/routing-1.0.xsd">
+
+ <route id="blog" path="/blog">
+ <default key="_controller">
+ <string>AcmeBlogBundle:Blog:index</string>
+ </default>
+ <default key="values">
+ <map>
+ <map key="map">
+ <bool key="public">true</bool>
+ <int key="page">1</int>
+ <float key="price">3.5</float>
+ <string key="title">foo</string>
+ </map>
+ </map>
+ </default>
+ </route>
+</routes>
diff --git a/assets/php/vendor/symfony/routing/Tests/Fixtures/map_null_values.xml b/assets/php/vendor/symfony/routing/Tests/Fixtures/map_null_values.xml
new file mode 100644
index 0000000..8fd8954
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Tests/Fixtures/map_null_values.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<routes xmlns="http://symfony.com/schema/routing"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://symfony.com/schema/routing
+ http://symfony.com/schema/routing/routing-1.0.xsd">
+
+ <route id="blog" path="/blog">
+ <default key="_controller">
+ <string>AcmeBlogBundle:Blog:index</string>
+ </default>
+ <default key="map">
+ <map>
+ <bool key="boolean" xsi:nil="true" />
+ <int key="integer" xsi:nil="true" />
+ <float key="float" xsi:nil="true" />
+ <string key="string" xsi:nil="1" />
+ <list key="list" xsi:nil="true" />
+ <map key="map" xsi:nil="true" />
+ </map>
+ </default>
+ </route>
+</routes>
diff --git a/assets/php/vendor/symfony/routing/Tests/Fixtures/missing_id.xml b/assets/php/vendor/symfony/routing/Tests/Fixtures/missing_id.xml
new file mode 100644
index 0000000..4ea4115
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Tests/Fixtures/missing_id.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<routes xmlns="http://symfony.com/schema/routing"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://symfony.com/schema/routing http://symfony.com/schema/routing/routing-1.0.xsd">
+
+ <route path="/test"></route>
+</routes>
diff --git a/assets/php/vendor/symfony/routing/Tests/Fixtures/missing_path.xml b/assets/php/vendor/symfony/routing/Tests/Fixtures/missing_path.xml
new file mode 100644
index 0000000..ef5bc08
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Tests/Fixtures/missing_path.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<routes xmlns="http://symfony.com/schema/routing"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://symfony.com/schema/routing http://symfony.com/schema/routing/routing-1.0.xsd">
+
+ <route id="myroute"></route>
+</routes>
diff --git a/assets/php/vendor/symfony/routing/Tests/Fixtures/namespaceprefix.xml b/assets/php/vendor/symfony/routing/Tests/Fixtures/namespaceprefix.xml
new file mode 100644
index 0000000..e33955a
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Tests/Fixtures/namespaceprefix.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<r:routes xmlns:r="http://symfony.com/schema/routing"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://symfony.com/schema/routing http://symfony.com/schema/routing/routing-1.0.xsd">
+
+ <r:route id="blog_show" path="/blog/{slug}" host="{_locale}.example.com">
+ <r:default key="_controller">MyBundle:Blog:show</r:default>
+ <requirement xmlns="http://symfony.com/schema/routing" key="slug">\w+</requirement>
+ <r2:requirement xmlns:r2="http://symfony.com/schema/routing" key="_locale">en|fr|de</r2:requirement>
+ <r:option key="compiler_class">RouteCompiler</r:option>
+ <r:default key="page">
+ <r3:int xmlns:r3="http://symfony.com/schema/routing">1</r3:int>
+ </r:default>
+ </r:route>
+</r:routes>
diff --git a/assets/php/vendor/symfony/routing/Tests/Fixtures/nonesense_resource_plus_path.yml b/assets/php/vendor/symfony/routing/Tests/Fixtures/nonesense_resource_plus_path.yml
new file mode 100644
index 0000000..a3e9473
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Tests/Fixtures/nonesense_resource_plus_path.yml
@@ -0,0 +1,3 @@
+blog_show:
+ resource: validpattern.yml
+ path: /test
diff --git a/assets/php/vendor/symfony/routing/Tests/Fixtures/nonesense_type_without_resource.yml b/assets/php/vendor/symfony/routing/Tests/Fixtures/nonesense_type_without_resource.yml
new file mode 100644
index 0000000..547cda3
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Tests/Fixtures/nonesense_type_without_resource.yml
@@ -0,0 +1,3 @@
+blog_show:
+ path: /blog/{slug}
+ type: custom
diff --git a/assets/php/vendor/symfony/routing/Tests/Fixtures/nonvalid.xml b/assets/php/vendor/symfony/routing/Tests/Fixtures/nonvalid.xml
new file mode 100644
index 0000000..dc147d2
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Tests/Fixtures/nonvalid.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<routes xmlns="http://symfony.com/schema/routing"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://symfony.com/schema/routing http://symfony.com/schema/routing/routing-1.0.xsd">
+
+ <route id="blog_show" path="/blog/{slug}">
+ <default key="_controller">MyBundle:Blog:show</default>
+ <!-- </route> -->
+</routes>
diff --git a/assets/php/vendor/symfony/routing/Tests/Fixtures/nonvalid.yml b/assets/php/vendor/symfony/routing/Tests/Fixtures/nonvalid.yml
new file mode 100644
index 0000000..257cc56
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Tests/Fixtures/nonvalid.yml
@@ -0,0 +1 @@
+foo
diff --git a/assets/php/vendor/symfony/routing/Tests/Fixtures/nonvalid2.yml b/assets/php/vendor/symfony/routing/Tests/Fixtures/nonvalid2.yml
new file mode 100644
index 0000000..cfa9992
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Tests/Fixtures/nonvalid2.yml
@@ -0,0 +1 @@
+route: string
diff --git a/assets/php/vendor/symfony/routing/Tests/Fixtures/nonvalidkeys.yml b/assets/php/vendor/symfony/routing/Tests/Fixtures/nonvalidkeys.yml
new file mode 100644
index 0000000..015e270
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Tests/Fixtures/nonvalidkeys.yml
@@ -0,0 +1,3 @@
+someroute:
+ resource: path/to/some.yml
+ name_prefix: test_
diff --git a/assets/php/vendor/symfony/routing/Tests/Fixtures/nonvalidnode.xml b/assets/php/vendor/symfony/routing/Tests/Fixtures/nonvalidnode.xml
new file mode 100644
index 0000000..863ef03
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Tests/Fixtures/nonvalidnode.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<routes xmlns="http://symfony.com/schema/routing"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://symfony.com/schema/routing http://symfony.com/schema/routing/routing-1.0.xsd">
+
+ <foo>bar</foo>
+</routes>
diff --git a/assets/php/vendor/symfony/routing/Tests/Fixtures/nonvalidroute.xml b/assets/php/vendor/symfony/routing/Tests/Fixtures/nonvalidroute.xml
new file mode 100644
index 0000000..908958c
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Tests/Fixtures/nonvalidroute.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<routes xmlns="http://symfony.com/schema/routing"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://symfony.com/schema/routing http://symfony.com/schema/routing/routing-1.0.xsd">
+
+ <route id="blog_show" path="/blog/{slug}">
+ <default key="_controller">MyBundle:Blog:show</default>
+ <option key="compiler_class">RouteCompiler</option>
+ <foo key="bar">baz</foo>
+ </route>
+</routes>
diff --git a/assets/php/vendor/symfony/routing/Tests/Fixtures/null_values.xml b/assets/php/vendor/symfony/routing/Tests/Fixtures/null_values.xml
new file mode 100644
index 0000000..f9e2aa2
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Tests/Fixtures/null_values.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<routes xmlns="http://symfony.com/schema/routing"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://symfony.com/schema/routing http://symfony.com/schema/routing/routing-1.0.xsd">
+
+ <route id="blog_show" path="/blog/{slug}">
+ <default key="foo" xsi:nil="true" />
+ <default key="bar" xsi:nil="1" />
+ <default key="foobar" xsi:nil="false">foo</default>
+ <default key="baz" xsi:nil="0">bar</default>
+ </route>
+</routes>
diff --git a/assets/php/vendor/symfony/routing/Tests/Fixtures/php_dsl.php b/assets/php/vendor/symfony/routing/Tests/Fixtures/php_dsl.php
new file mode 100644
index 0000000..0780c9f
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Tests/Fixtures/php_dsl.php
@@ -0,0 +1,22 @@
+<?php
+
+namespace Symfony\Component\Routing\Loader\Configurator;
+
+return function (RoutingConfigurator $routes) {
+ $routes
+ ->collection()
+ ->add('foo', '/foo')
+ ->condition('abc')
+ ->options(array('utf8' => true))
+ ->add('buz', 'zub')
+ ->controller('foo:act');
+
+ $routes->import('php_dsl_sub.php')
+ ->prefix('/sub')
+ ->requirements(array('id' => '\d+'));
+
+ $routes->add('ouf', '/ouf')
+ ->schemes(array('https'))
+ ->methods(array('GET'))
+ ->defaults(array('id' => 0));
+};
diff --git a/assets/php/vendor/symfony/routing/Tests/Fixtures/php_dsl_sub.php b/assets/php/vendor/symfony/routing/Tests/Fixtures/php_dsl_sub.php
new file mode 100644
index 0000000..9eb444d
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Tests/Fixtures/php_dsl_sub.php
@@ -0,0 +1,14 @@
+<?php
+
+namespace Symfony\Component\Routing\Loader\Configurator;
+
+return function (RoutingConfigurator $routes) {
+ $add = $routes->collection('c_')
+ ->prefix('pub');
+
+ $add('bar', '/bar');
+
+ $add->collection('pub_')
+ ->host('host')
+ ->add('buz', 'buz');
+};
diff --git a/assets/php/vendor/symfony/routing/Tests/Fixtures/scalar_defaults.xml b/assets/php/vendor/symfony/routing/Tests/Fixtures/scalar_defaults.xml
new file mode 100644
index 0000000..ecfde28
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Tests/Fixtures/scalar_defaults.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<routes xmlns="http://symfony.com/schema/routing"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://symfony.com/schema/routing
+ http://symfony.com/schema/routing/routing-1.0.xsd">
+
+ <route id="blog" path="/blog">
+ <default key="_controller">
+ <string>AcmeBlogBundle:Blog:index</string>
+ </default>
+ <default key="slug" xsi:nil="true" />
+ <default key="published">
+ <bool>true</bool>
+ </default>
+ <default key="page">
+ <int>1</int>
+ </default>
+ <default key="price">
+ <float>3.5</float>
+ </default>
+ <default key="archived">
+ <bool>false</bool>
+ </default>
+ <default key="free">
+ <bool>1</bool>
+ </default>
+ <default key="locked">
+ <bool>0</bool>
+ </default>
+ <default key="foo" xsi:nil="true" />
+ <default key="bar" xsi:nil="1" />
+ </route>
+</routes>
diff --git a/assets/php/vendor/symfony/routing/Tests/Fixtures/special_route_name.yml b/assets/php/vendor/symfony/routing/Tests/Fixtures/special_route_name.yml
new file mode 100644
index 0000000..78be239
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Tests/Fixtures/special_route_name.yml
@@ -0,0 +1,2 @@
+"#$péß^a|":
+ path: "true"
diff --git a/assets/php/vendor/symfony/routing/Tests/Fixtures/validpattern.php b/assets/php/vendor/symfony/routing/Tests/Fixtures/validpattern.php
new file mode 100644
index 0000000..edc16d8
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Tests/Fixtures/validpattern.php
@@ -0,0 +1,18 @@
+<?php
+
+use Symfony\Component\Routing\RouteCollection;
+use Symfony\Component\Routing\Route;
+
+$collection = new RouteCollection();
+$collection->add('blog_show', new Route(
+ '/blog/{slug}',
+ array('_controller' => 'MyBlogBundle:Blog:show'),
+ array('locale' => '\w+'),
+ array('compiler_class' => 'RouteCompiler'),
+ '{locale}.example.com',
+ array('https'),
+ array('GET', 'POST', 'put', 'OpTiOnS'),
+ 'context.getMethod() == "GET"'
+));
+
+return $collection;
diff --git a/assets/php/vendor/symfony/routing/Tests/Fixtures/validpattern.xml b/assets/php/vendor/symfony/routing/Tests/Fixtures/validpattern.xml
new file mode 100644
index 0000000..dbc72e4
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Tests/Fixtures/validpattern.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<routes xmlns="http://symfony.com/schema/routing"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://symfony.com/schema/routing http://symfony.com/schema/routing/routing-1.0.xsd">
+
+ <route id="blog_show" path="/blog/{slug}" host="{locale}.example.com" methods="GET|POST put,OpTiOnS" schemes="hTTps">
+ <default key="_controller">MyBundle:Blog:show</default>
+ <requirement key="locale">\w+</requirement>
+ <option key="compiler_class">RouteCompiler</option>
+ <condition>context.getMethod() == "GET"</condition>
+ </route>
+
+ <route id="blog_show_inherited" path="/blog/{slug}" />
+</routes>
diff --git a/assets/php/vendor/symfony/routing/Tests/Fixtures/validpattern.yml b/assets/php/vendor/symfony/routing/Tests/Fixtures/validpattern.yml
new file mode 100644
index 0000000..565abaa
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Tests/Fixtures/validpattern.yml
@@ -0,0 +1,13 @@
+blog_show:
+ path: /blog/{slug}
+ defaults: { _controller: "MyBundle:Blog:show" }
+ host: "{locale}.example.com"
+ requirements: { 'locale': '\w+' }
+ methods: ['GET','POST','put','OpTiOnS']
+ schemes: ['https']
+ condition: 'context.getMethod() == "GET"'
+ options:
+ compiler_class: RouteCompiler
+
+blog_show_inherited:
+ path: /blog/{slug}
diff --git a/assets/php/vendor/symfony/routing/Tests/Fixtures/validresource.php b/assets/php/vendor/symfony/routing/Tests/Fixtures/validresource.php
new file mode 100644
index 0000000..482c80b
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Tests/Fixtures/validresource.php
@@ -0,0 +1,18 @@
+<?php
+
+/** @var $loader \Symfony\Component\Routing\Loader\PhpFileLoader */
+/** @var \Symfony\Component\Routing\RouteCollection $collection */
+$collection = $loader->import('validpattern.php');
+$collection->addDefaults(array(
+ 'foo' => 123,
+));
+$collection->addRequirements(array(
+ 'foo' => '\d+',
+));
+$collection->addOptions(array(
+ 'foo' => 'bar',
+));
+$collection->setCondition('context.getMethod() == "POST"');
+$collection->addPrefix('/prefix');
+
+return $collection;
diff --git a/assets/php/vendor/symfony/routing/Tests/Fixtures/validresource.xml b/assets/php/vendor/symfony/routing/Tests/Fixtures/validresource.xml
new file mode 100644
index 0000000..b7a15dd
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Tests/Fixtures/validresource.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<routes xmlns="http://symfony.com/schema/routing"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://symfony.com/schema/routing http://symfony.com/schema/routing/routing-1.0.xsd">
+
+ <import resource="validpattern.xml" prefix="/{foo}" host="">
+ <default key="foo">123</default>
+ <requirement key="foo">\d+</requirement>
+ <option key="foo">bar</option>
+ <condition>context.getMethod() == "POST"</condition>
+ </import>
+</routes>
diff --git a/assets/php/vendor/symfony/routing/Tests/Fixtures/validresource.yml b/assets/php/vendor/symfony/routing/Tests/Fixtures/validresource.yml
new file mode 100644
index 0000000..faf2263
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Tests/Fixtures/validresource.yml
@@ -0,0 +1,8 @@
+_blog:
+ resource: validpattern.yml
+ prefix: /{foo}
+ defaults: { 'foo': '123' }
+ requirements: { 'foo': '\d+' }
+ options: { 'foo': 'bar' }
+ host: ""
+ condition: 'context.getMethod() == "POST"'
diff --git a/assets/php/vendor/symfony/routing/Tests/Fixtures/with_define_path_variable.php b/assets/php/vendor/symfony/routing/Tests/Fixtures/with_define_path_variable.php
new file mode 100644
index 0000000..5871420
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Tests/Fixtures/with_define_path_variable.php
@@ -0,0 +1,5 @@
+<?php
+
+$path = '/1/2/3';
+
+return new \Symfony\Component\Routing\RouteCollection();
diff --git a/assets/php/vendor/symfony/routing/Tests/Fixtures/withdoctype.xml b/assets/php/vendor/symfony/routing/Tests/Fixtures/withdoctype.xml
new file mode 100644
index 0000000..f217d5b
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Tests/Fixtures/withdoctype.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<!DOCTYPE foo>
+<foo></foo>
diff --git a/assets/php/vendor/symfony/routing/Tests/Generator/Dumper/PhpGeneratorDumperTest.php b/assets/php/vendor/symfony/routing/Tests/Generator/Dumper/PhpGeneratorDumperTest.php
new file mode 100644
index 0000000..f84802b
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Tests/Generator/Dumper/PhpGeneratorDumperTest.php
@@ -0,0 +1,181 @@
+<?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\Tests\Generator\Dumper;
+
+use PHPUnit\Framework\TestCase;
+use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
+use Symfony\Component\Routing\RouteCollection;
+use Symfony\Component\Routing\Route;
+use Symfony\Component\Routing\Generator\Dumper\PhpGeneratorDumper;
+use Symfony\Component\Routing\RequestContext;
+
+class PhpGeneratorDumperTest extends TestCase
+{
+ /**
+ * @var RouteCollection
+ */
+ private $routeCollection;
+
+ /**
+ * @var PhpGeneratorDumper
+ */
+ private $generatorDumper;
+
+ /**
+ * @var string
+ */
+ private $testTmpFilepath;
+
+ /**
+ * @var string
+ */
+ private $largeTestTmpFilepath;
+
+ protected function setUp()
+ {
+ parent::setUp();
+
+ $this->routeCollection = new RouteCollection();
+ $this->generatorDumper = new PhpGeneratorDumper($this->routeCollection);
+ $this->testTmpFilepath = sys_get_temp_dir().DIRECTORY_SEPARATOR.'php_generator.'.$this->getName().'.php';
+ $this->largeTestTmpFilepath = sys_get_temp_dir().DIRECTORY_SEPARATOR.'php_generator.'.$this->getName().'.large.php';
+ @unlink($this->testTmpFilepath);
+ @unlink($this->largeTestTmpFilepath);
+ }
+
+ protected function tearDown()
+ {
+ parent::tearDown();
+
+ @unlink($this->testTmpFilepath);
+
+ $this->routeCollection = null;
+ $this->generatorDumper = null;
+ $this->testTmpFilepath = null;
+ }
+
+ public function testDumpWithRoutes()
+ {
+ $this->routeCollection->add('Test', new Route('/testing/{foo}'));
+ $this->routeCollection->add('Test2', new Route('/testing2'));
+
+ file_put_contents($this->testTmpFilepath, $this->generatorDumper->dump());
+ include $this->testTmpFilepath;
+
+ $projectUrlGenerator = new \ProjectUrlGenerator(new RequestContext('/app.php'));
+
+ $absoluteUrlWithParameter = $projectUrlGenerator->generate('Test', array('foo' => 'bar'), UrlGeneratorInterface::ABSOLUTE_URL);
+ $absoluteUrlWithoutParameter = $projectUrlGenerator->generate('Test2', array(), UrlGeneratorInterface::ABSOLUTE_URL);
+ $relativeUrlWithParameter = $projectUrlGenerator->generate('Test', array('foo' => 'bar'), UrlGeneratorInterface::ABSOLUTE_PATH);
+ $relativeUrlWithoutParameter = $projectUrlGenerator->generate('Test2', array(), UrlGeneratorInterface::ABSOLUTE_PATH);
+
+ $this->assertEquals('http://localhost/app.php/testing/bar', $absoluteUrlWithParameter);
+ $this->assertEquals('http://localhost/app.php/testing2', $absoluteUrlWithoutParameter);
+ $this->assertEquals('/app.php/testing/bar', $relativeUrlWithParameter);
+ $this->assertEquals('/app.php/testing2', $relativeUrlWithoutParameter);
+ }
+
+ public function testDumpWithTooManyRoutes()
+ {
+ if (defined('HHVM_VERSION_ID')) {
+ $this->markTestSkipped('HHVM consumes too much memory on this test.');
+ }
+
+ $this->routeCollection->add('Test', new Route('/testing/{foo}'));
+ for ($i = 0; $i < 32769; ++$i) {
+ $this->routeCollection->add('route_'.$i, new Route('/route_'.$i));
+ }
+ $this->routeCollection->add('Test2', new Route('/testing2'));
+
+ file_put_contents($this->largeTestTmpFilepath, $this->generatorDumper->dump(array(
+ 'class' => 'ProjectLargeUrlGenerator',
+ )));
+ $this->routeCollection = $this->generatorDumper = null;
+ include $this->largeTestTmpFilepath;
+
+ $projectUrlGenerator = new \ProjectLargeUrlGenerator(new RequestContext('/app.php'));
+
+ $absoluteUrlWithParameter = $projectUrlGenerator->generate('Test', array('foo' => 'bar'), UrlGeneratorInterface::ABSOLUTE_URL);
+ $absoluteUrlWithoutParameter = $projectUrlGenerator->generate('Test2', array(), UrlGeneratorInterface::ABSOLUTE_URL);
+ $relativeUrlWithParameter = $projectUrlGenerator->generate('Test', array('foo' => 'bar'), UrlGeneratorInterface::ABSOLUTE_PATH);
+ $relativeUrlWithoutParameter = $projectUrlGenerator->generate('Test2', array(), UrlGeneratorInterface::ABSOLUTE_PATH);
+
+ $this->assertEquals('http://localhost/app.php/testing/bar', $absoluteUrlWithParameter);
+ $this->assertEquals('http://localhost/app.php/testing2', $absoluteUrlWithoutParameter);
+ $this->assertEquals('/app.php/testing/bar', $relativeUrlWithParameter);
+ $this->assertEquals('/app.php/testing2', $relativeUrlWithoutParameter);
+ }
+
+ /**
+ * @expectedException \InvalidArgumentException
+ */
+ public function testDumpWithoutRoutes()
+ {
+ file_put_contents($this->testTmpFilepath, $this->generatorDumper->dump(array('class' => 'WithoutRoutesUrlGenerator')));
+ include $this->testTmpFilepath;
+
+ $projectUrlGenerator = new \WithoutRoutesUrlGenerator(new RequestContext('/app.php'));
+
+ $projectUrlGenerator->generate('Test', array());
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Routing\Exception\RouteNotFoundException
+ */
+ public function testGenerateNonExistingRoute()
+ {
+ $this->routeCollection->add('Test', new Route('/test'));
+
+ file_put_contents($this->testTmpFilepath, $this->generatorDumper->dump(array('class' => 'NonExistingRoutesUrlGenerator')));
+ include $this->testTmpFilepath;
+
+ $projectUrlGenerator = new \NonExistingRoutesUrlGenerator(new RequestContext());
+ $url = $projectUrlGenerator->generate('NonExisting', array());
+ }
+
+ public function testDumpForRouteWithDefaults()
+ {
+ $this->routeCollection->add('Test', new Route('/testing/{foo}', array('foo' => 'bar')));
+
+ file_put_contents($this->testTmpFilepath, $this->generatorDumper->dump(array('class' => 'DefaultRoutesUrlGenerator')));
+ include $this->testTmpFilepath;
+
+ $projectUrlGenerator = new \DefaultRoutesUrlGenerator(new RequestContext());
+ $url = $projectUrlGenerator->generate('Test', array());
+
+ $this->assertEquals('/testing', $url);
+ }
+
+ public function testDumpWithSchemeRequirement()
+ {
+ $this->routeCollection->add('Test1', new Route('/testing', array(), array(), array(), '', array('ftp', 'https')));
+
+ file_put_contents($this->testTmpFilepath, $this->generatorDumper->dump(array('class' => 'SchemeUrlGenerator')));
+ include $this->testTmpFilepath;
+
+ $projectUrlGenerator = new \SchemeUrlGenerator(new RequestContext('/app.php'));
+
+ $absoluteUrl = $projectUrlGenerator->generate('Test1', array(), UrlGeneratorInterface::ABSOLUTE_URL);
+ $relativeUrl = $projectUrlGenerator->generate('Test1', array(), UrlGeneratorInterface::ABSOLUTE_PATH);
+
+ $this->assertEquals('ftp://localhost/app.php/testing', $absoluteUrl);
+ $this->assertEquals('ftp://localhost/app.php/testing', $relativeUrl);
+
+ $projectUrlGenerator = new \SchemeUrlGenerator(new RequestContext('/app.php', 'GET', 'localhost', 'https'));
+
+ $absoluteUrl = $projectUrlGenerator->generate('Test1', array(), UrlGeneratorInterface::ABSOLUTE_URL);
+ $relativeUrl = $projectUrlGenerator->generate('Test1', array(), UrlGeneratorInterface::ABSOLUTE_PATH);
+
+ $this->assertEquals('https://localhost/app.php/testing', $absoluteUrl);
+ $this->assertEquals('/app.php/testing', $relativeUrl);
+ }
+}
diff --git a/assets/php/vendor/symfony/routing/Tests/Generator/UrlGeneratorTest.php b/assets/php/vendor/symfony/routing/Tests/Generator/UrlGeneratorTest.php
new file mode 100644
index 0000000..68add77
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Tests/Generator/UrlGeneratorTest.php
@@ -0,0 +1,724 @@
+<?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\Tests\Generator;
+
+use PHPUnit\Framework\TestCase;
+use Symfony\Component\Routing\RouteCollection;
+use Symfony\Component\Routing\Route;
+use Symfony\Component\Routing\Generator\UrlGenerator;
+use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
+use Symfony\Component\Routing\RequestContext;
+
+class UrlGeneratorTest extends TestCase
+{
+ public function testAbsoluteUrlWithPort80()
+ {
+ $routes = $this->getRoutes('test', new Route('/testing'));
+ $url = $this->getGenerator($routes)->generate('test', array(), UrlGeneratorInterface::ABSOLUTE_URL);
+
+ $this->assertEquals('http://localhost/app.php/testing', $url);
+ }
+
+ public function testAbsoluteSecureUrlWithPort443()
+ {
+ $routes = $this->getRoutes('test', new Route('/testing'));
+ $url = $this->getGenerator($routes, array('scheme' => 'https'))->generate('test', array(), UrlGeneratorInterface::ABSOLUTE_URL);
+
+ $this->assertEquals('https://localhost/app.php/testing', $url);
+ }
+
+ public function testAbsoluteUrlWithNonStandardPort()
+ {
+ $routes = $this->getRoutes('test', new Route('/testing'));
+ $url = $this->getGenerator($routes, array('httpPort' => 8080))->generate('test', array(), UrlGeneratorInterface::ABSOLUTE_URL);
+
+ $this->assertEquals('http://localhost:8080/app.php/testing', $url);
+ }
+
+ public function testAbsoluteSecureUrlWithNonStandardPort()
+ {
+ $routes = $this->getRoutes('test', new Route('/testing'));
+ $url = $this->getGenerator($routes, array('httpsPort' => 8080, 'scheme' => 'https'))->generate('test', array(), UrlGeneratorInterface::ABSOLUTE_URL);
+
+ $this->assertEquals('https://localhost:8080/app.php/testing', $url);
+ }
+
+ public function testRelativeUrlWithoutParameters()
+ {
+ $routes = $this->getRoutes('test', new Route('/testing'));
+ $url = $this->getGenerator($routes)->generate('test', array(), UrlGeneratorInterface::ABSOLUTE_PATH);
+
+ $this->assertEquals('/app.php/testing', $url);
+ }
+
+ public function testRelativeUrlWithParameter()
+ {
+ $routes = $this->getRoutes('test', new Route('/testing/{foo}'));
+ $url = $this->getGenerator($routes)->generate('test', array('foo' => 'bar'), UrlGeneratorInterface::ABSOLUTE_PATH);
+
+ $this->assertEquals('/app.php/testing/bar', $url);
+ }
+
+ public function testRelativeUrlWithNullParameter()
+ {
+ $routes = $this->getRoutes('test', new Route('/testing.{format}', array('format' => null)));
+ $url = $this->getGenerator($routes)->generate('test', array(), UrlGeneratorInterface::ABSOLUTE_PATH);
+
+ $this->assertEquals('/app.php/testing', $url);
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Routing\Exception\InvalidParameterException
+ */
+ public function testRelativeUrlWithNullParameterButNotOptional()
+ {
+ $routes = $this->getRoutes('test', new Route('/testing/{foo}/bar', array('foo' => null)));
+ // This must raise an exception because the default requirement for "foo" is "[^/]+" which is not met with these params.
+ // Generating path "/testing//bar" would be wrong as matching this route would fail.
+ $this->getGenerator($routes)->generate('test', array(), UrlGeneratorInterface::ABSOLUTE_PATH);
+ }
+
+ public function testRelativeUrlWithOptionalZeroParameter()
+ {
+ $routes = $this->getRoutes('test', new Route('/testing/{page}'));
+ $url = $this->getGenerator($routes)->generate('test', array('page' => 0), UrlGeneratorInterface::ABSOLUTE_PATH);
+
+ $this->assertEquals('/app.php/testing/0', $url);
+ }
+
+ public function testNotPassedOptionalParameterInBetween()
+ {
+ $routes = $this->getRoutes('test', new Route('/{slug}/{page}', array('slug' => 'index', 'page' => 0)));
+ $this->assertSame('/app.php/index/1', $this->getGenerator($routes)->generate('test', array('page' => 1)));
+ $this->assertSame('/app.php/', $this->getGenerator($routes)->generate('test'));
+ }
+
+ public function testRelativeUrlWithExtraParameters()
+ {
+ $routes = $this->getRoutes('test', new Route('/testing'));
+ $url = $this->getGenerator($routes)->generate('test', array('foo' => 'bar'), UrlGeneratorInterface::ABSOLUTE_PATH);
+
+ $this->assertEquals('/app.php/testing?foo=bar', $url);
+ }
+
+ public function testAbsoluteUrlWithExtraParameters()
+ {
+ $routes = $this->getRoutes('test', new Route('/testing'));
+ $url = $this->getGenerator($routes)->generate('test', array('foo' => 'bar'), UrlGeneratorInterface::ABSOLUTE_URL);
+
+ $this->assertEquals('http://localhost/app.php/testing?foo=bar', $url);
+ }
+
+ public function testUrlWithNullExtraParameters()
+ {
+ $routes = $this->getRoutes('test', new Route('/testing'));
+ $url = $this->getGenerator($routes)->generate('test', array('foo' => null), UrlGeneratorInterface::ABSOLUTE_URL);
+
+ $this->assertEquals('http://localhost/app.php/testing', $url);
+ }
+
+ public function testUrlWithExtraParametersFromGlobals()
+ {
+ $routes = $this->getRoutes('test', new Route('/testing'));
+ $generator = $this->getGenerator($routes);
+ $context = new RequestContext('/app.php');
+ $context->setParameter('bar', 'bar');
+ $generator->setContext($context);
+ $url = $generator->generate('test', array('foo' => 'bar'));
+
+ $this->assertEquals('/app.php/testing?foo=bar', $url);
+ }
+
+ public function testUrlWithGlobalParameter()
+ {
+ $routes = $this->getRoutes('test', new Route('/testing/{foo}'));
+ $generator = $this->getGenerator($routes);
+ $context = new RequestContext('/app.php');
+ $context->setParameter('foo', 'bar');
+ $generator->setContext($context);
+ $url = $generator->generate('test', array());
+
+ $this->assertEquals('/app.php/testing/bar', $url);
+ }
+
+ public function testGlobalParameterHasHigherPriorityThanDefault()
+ {
+ $routes = $this->getRoutes('test', new Route('/{_locale}', array('_locale' => 'en')));
+ $generator = $this->getGenerator($routes);
+ $context = new RequestContext('/app.php');
+ $context->setParameter('_locale', 'de');
+ $generator->setContext($context);
+ $url = $generator->generate('test', array());
+
+ $this->assertSame('/app.php/de', $url);
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Routing\Exception\RouteNotFoundException
+ */
+ public function testGenerateWithoutRoutes()
+ {
+ $routes = $this->getRoutes('foo', new Route('/testing/{foo}'));
+ $this->getGenerator($routes)->generate('test', array(), UrlGeneratorInterface::ABSOLUTE_URL);
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Routing\Exception\MissingMandatoryParametersException
+ */
+ public function testGenerateForRouteWithoutMandatoryParameter()
+ {
+ $routes = $this->getRoutes('test', new Route('/testing/{foo}'));
+ $this->getGenerator($routes)->generate('test', array(), UrlGeneratorInterface::ABSOLUTE_URL);
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Routing\Exception\InvalidParameterException
+ */
+ public function testGenerateForRouteWithInvalidOptionalParameter()
+ {
+ $routes = $this->getRoutes('test', new Route('/testing/{foo}', array('foo' => '1'), array('foo' => 'd+')));
+ $this->getGenerator($routes)->generate('test', array('foo' => 'bar'), UrlGeneratorInterface::ABSOLUTE_URL);
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Routing\Exception\InvalidParameterException
+ */
+ public function testGenerateForRouteWithInvalidParameter()
+ {
+ $routes = $this->getRoutes('test', new Route('/testing/{foo}', array(), array('foo' => '1|2')));
+ $this->getGenerator($routes)->generate('test', array('foo' => '0'), UrlGeneratorInterface::ABSOLUTE_URL);
+ }
+
+ public function testGenerateForRouteWithInvalidOptionalParameterNonStrict()
+ {
+ $routes = $this->getRoutes('test', new Route('/testing/{foo}', array('foo' => '1'), array('foo' => 'd+')));
+ $generator = $this->getGenerator($routes);
+ $generator->setStrictRequirements(false);
+ $this->assertNull($generator->generate('test', array('foo' => 'bar'), UrlGeneratorInterface::ABSOLUTE_URL));
+ }
+
+ public function testGenerateForRouteWithInvalidOptionalParameterNonStrictWithLogger()
+ {
+ $routes = $this->getRoutes('test', new Route('/testing/{foo}', array('foo' => '1'), array('foo' => 'd+')));
+ $logger = $this->getMockBuilder('Psr\Log\LoggerInterface')->getMock();
+ $logger->expects($this->once())
+ ->method('error');
+ $generator = $this->getGenerator($routes, array(), $logger);
+ $generator->setStrictRequirements(false);
+ $this->assertNull($generator->generate('test', array('foo' => 'bar'), UrlGeneratorInterface::ABSOLUTE_URL));
+ }
+
+ public function testGenerateForRouteWithInvalidParameterButDisabledRequirementsCheck()
+ {
+ $routes = $this->getRoutes('test', new Route('/testing/{foo}', array('foo' => '1'), array('foo' => 'd+')));
+ $generator = $this->getGenerator($routes);
+ $generator->setStrictRequirements(null);
+ $this->assertSame('/app.php/testing/bar', $generator->generate('test', array('foo' => 'bar')));
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Routing\Exception\InvalidParameterException
+ */
+ public function testGenerateForRouteWithInvalidMandatoryParameter()
+ {
+ $routes = $this->getRoutes('test', new Route('/testing/{foo}', array(), array('foo' => 'd+')));
+ $this->getGenerator($routes)->generate('test', array('foo' => 'bar'), UrlGeneratorInterface::ABSOLUTE_URL);
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Routing\Exception\InvalidParameterException
+ */
+ public function testGenerateForRouteWithInvalidUtf8Parameter()
+ {
+ $routes = $this->getRoutes('test', new Route('/testing/{foo}', array(), array('foo' => '\pL+'), array('utf8' => true)));
+ $this->getGenerator($routes)->generate('test', array('foo' => 'abc123'), UrlGeneratorInterface::ABSOLUTE_URL);
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Routing\Exception\InvalidParameterException
+ */
+ public function testRequiredParamAndEmptyPassed()
+ {
+ $routes = $this->getRoutes('test', new Route('/{slug}', array(), array('slug' => '.+')));
+ $this->getGenerator($routes)->generate('test', array('slug' => ''));
+ }
+
+ public function testSchemeRequirementDoesNothingIfSameCurrentScheme()
+ {
+ $routes = $this->getRoutes('test', new Route('/', array(), array(), array(), '', array('http')));
+ $this->assertEquals('/app.php/', $this->getGenerator($routes)->generate('test'));
+
+ $routes = $this->getRoutes('test', new Route('/', array(), array(), array(), '', array('https')));
+ $this->assertEquals('/app.php/', $this->getGenerator($routes, array('scheme' => 'https'))->generate('test'));
+ }
+
+ public function testSchemeRequirementForcesAbsoluteUrl()
+ {
+ $routes = $this->getRoutes('test', new Route('/', array(), array(), array(), '', array('https')));
+ $this->assertEquals('https://localhost/app.php/', $this->getGenerator($routes)->generate('test'));
+
+ $routes = $this->getRoutes('test', new Route('/', array(), array(), array(), '', array('http')));
+ $this->assertEquals('http://localhost/app.php/', $this->getGenerator($routes, array('scheme' => 'https'))->generate('test'));
+ }
+
+ public function testSchemeRequirementCreatesUrlForFirstRequiredScheme()
+ {
+ $routes = $this->getRoutes('test', new Route('/', array(), array(), array(), '', array('Ftp', 'https')));
+ $this->assertEquals('ftp://localhost/app.php/', $this->getGenerator($routes)->generate('test'));
+ }
+
+ public function testPathWithTwoStartingSlashes()
+ {
+ $routes = $this->getRoutes('test', new Route('//path-and-not-domain'));
+
+ // this must not generate '//path-and-not-domain' because that would be a network path
+ $this->assertSame('/path-and-not-domain', $this->getGenerator($routes, array('BaseUrl' => ''))->generate('test'));
+ }
+
+ public function testNoTrailingSlashForMultipleOptionalParameters()
+ {
+ $routes = $this->getRoutes('test', new Route('/category/{slug1}/{slug2}/{slug3}', array('slug2' => null, 'slug3' => null)));
+
+ $this->assertEquals('/app.php/category/foo', $this->getGenerator($routes)->generate('test', array('slug1' => 'foo')));
+ }
+
+ public function testWithAnIntegerAsADefaultValue()
+ {
+ $routes = $this->getRoutes('test', new Route('/{default}', array('default' => 0)));
+
+ $this->assertEquals('/app.php/foo', $this->getGenerator($routes)->generate('test', array('default' => 'foo')));
+ }
+
+ public function testNullForOptionalParameterIsIgnored()
+ {
+ $routes = $this->getRoutes('test', new Route('/test/{default}', array('default' => 0)));
+
+ $this->assertEquals('/app.php/test', $this->getGenerator($routes)->generate('test', array('default' => null)));
+ }
+
+ public function testQueryParamSameAsDefault()
+ {
+ $routes = $this->getRoutes('test', new Route('/test', array('page' => 1)));
+
+ $this->assertSame('/app.php/test?page=2', $this->getGenerator($routes)->generate('test', array('page' => 2)));
+ $this->assertSame('/app.php/test', $this->getGenerator($routes)->generate('test', array('page' => 1)));
+ $this->assertSame('/app.php/test', $this->getGenerator($routes)->generate('test', array('page' => '1')));
+ $this->assertSame('/app.php/test', $this->getGenerator($routes)->generate('test'));
+ }
+
+ public function testArrayQueryParamSameAsDefault()
+ {
+ $routes = $this->getRoutes('test', new Route('/test', array('array' => array('foo', 'bar'))));
+
+ $this->assertSame('/app.php/test?array%5B0%5D=bar&array%5B1%5D=foo', $this->getGenerator($routes)->generate('test', array('array' => array('bar', 'foo'))));
+ $this->assertSame('/app.php/test?array%5Ba%5D=foo&array%5Bb%5D=bar', $this->getGenerator($routes)->generate('test', array('array' => array('a' => 'foo', 'b' => 'bar'))));
+ $this->assertSame('/app.php/test', $this->getGenerator($routes)->generate('test', array('array' => array('foo', 'bar'))));
+ $this->assertSame('/app.php/test', $this->getGenerator($routes)->generate('test', array('array' => array(1 => 'bar', 0 => 'foo'))));
+ $this->assertSame('/app.php/test', $this->getGenerator($routes)->generate('test'));
+ }
+
+ public function testGenerateWithSpecialRouteName()
+ {
+ $routes = $this->getRoutes('$péß^a|', new Route('/bar'));
+
+ $this->assertSame('/app.php/bar', $this->getGenerator($routes)->generate('$péß^a|'));
+ }
+
+ public function testUrlEncoding()
+ {
+ $expectedPath = '/app.php/@:%5B%5D/%28%29*%27%22%20+,;-._~%26%24%3C%3E|%7B%7D%25%5C%5E%60!%3Ffoo=bar%23id'
+ .'/@:%5B%5D/%28%29*%27%22%20+,;-._~%26%24%3C%3E|%7B%7D%25%5C%5E%60!%3Ffoo=bar%23id'
+ .'?query=%40%3A%5B%5D/%28%29%2A%27%22%20%2B%2C%3B-._~%26%24%3C%3E%7C%7B%7D%25%5C%5E%60%21%3Ffoo%3Dbar%23id';
+
+ // This tests the encoding of reserved characters that are used for delimiting of URI components (defined in RFC 3986)
+ // and other special ASCII chars. These chars are tested as static text path, variable path and query param.
+ $chars = '@:[]/()*\'" +,;-._~&$<>|{}%\\^`!?foo=bar#id';
+ $routes = $this->getRoutes('test', new Route("/$chars/{varpath}", array(), array('varpath' => '.+')));
+ $this->assertSame($expectedPath, $this->getGenerator($routes)->generate('test', array(
+ 'varpath' => $chars,
+ 'query' => $chars,
+ )));
+ }
+
+ public function testEncodingOfRelativePathSegments()
+ {
+ $routes = $this->getRoutes('test', new Route('/dir/../dir/..'));
+ $this->assertSame('/app.php/dir/%2E%2E/dir/%2E%2E', $this->getGenerator($routes)->generate('test'));
+ $routes = $this->getRoutes('test', new Route('/dir/./dir/.'));
+ $this->assertSame('/app.php/dir/%2E/dir/%2E', $this->getGenerator($routes)->generate('test'));
+ $routes = $this->getRoutes('test', new Route('/a./.a/a../..a/...'));
+ $this->assertSame('/app.php/a./.a/a../..a/...', $this->getGenerator($routes)->generate('test'));
+ }
+
+ public function testAdjacentVariables()
+ {
+ $routes = $this->getRoutes('test', new Route('/{x}{y}{z}.{_format}', array('z' => 'default-z', '_format' => 'html'), array('y' => '\d+')));
+ $generator = $this->getGenerator($routes);
+ $this->assertSame('/app.php/foo123', $generator->generate('test', array('x' => 'foo', 'y' => '123')));
+ $this->assertSame('/app.php/foo123bar.xml', $generator->generate('test', array('x' => 'foo', 'y' => '123', 'z' => 'bar', '_format' => 'xml')));
+
+ // The default requirement for 'x' should not allow the separator '.' in this case because it would otherwise match everything
+ // and following optional variables like _format could never match.
+ $this->{method_exists($this, $_ = 'expectException') ? $_ : 'setExpectedException'}('Symfony\Component\Routing\Exception\InvalidParameterException');
+ $generator->generate('test', array('x' => 'do.t', 'y' => '123', 'z' => 'bar', '_format' => 'xml'));
+ }
+
+ public function testOptionalVariableWithNoRealSeparator()
+ {
+ $routes = $this->getRoutes('test', new Route('/get{what}', array('what' => 'All')));
+ $generator = $this->getGenerator($routes);
+
+ $this->assertSame('/app.php/get', $generator->generate('test'));
+ $this->assertSame('/app.php/getSites', $generator->generate('test', array('what' => 'Sites')));
+ }
+
+ public function testRequiredVariableWithNoRealSeparator()
+ {
+ $routes = $this->getRoutes('test', new Route('/get{what}Suffix'));
+ $generator = $this->getGenerator($routes);
+
+ $this->assertSame('/app.php/getSitesSuffix', $generator->generate('test', array('what' => 'Sites')));
+ }
+
+ public function testDefaultRequirementOfVariable()
+ {
+ $routes = $this->getRoutes('test', new Route('/{page}.{_format}'));
+ $generator = $this->getGenerator($routes);
+
+ $this->assertSame('/app.php/index.mobile.html', $generator->generate('test', array('page' => 'index', '_format' => 'mobile.html')));
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Routing\Exception\InvalidParameterException
+ */
+ public function testDefaultRequirementOfVariableDisallowsSlash()
+ {
+ $routes = $this->getRoutes('test', new Route('/{page}.{_format}'));
+ $this->getGenerator($routes)->generate('test', array('page' => 'index', '_format' => 'sl/ash'));
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Routing\Exception\InvalidParameterException
+ */
+ public function testDefaultRequirementOfVariableDisallowsNextSeparator()
+ {
+ $routes = $this->getRoutes('test', new Route('/{page}.{_format}'));
+ $this->getGenerator($routes)->generate('test', array('page' => 'do.t', '_format' => 'html'));
+ }
+
+ public function testWithHostDifferentFromContext()
+ {
+ $routes = $this->getRoutes('test', new Route('/{name}', array(), array(), array(), '{locale}.example.com'));
+
+ $this->assertEquals('//fr.example.com/app.php/Fabien', $this->getGenerator($routes)->generate('test', array('name' => 'Fabien', 'locale' => 'fr')));
+ }
+
+ public function testWithHostSameAsContext()
+ {
+ $routes = $this->getRoutes('test', new Route('/{name}', array(), array(), array(), '{locale}.example.com'));
+
+ $this->assertEquals('/app.php/Fabien', $this->getGenerator($routes, array('host' => 'fr.example.com'))->generate('test', array('name' => 'Fabien', 'locale' => 'fr')));
+ }
+
+ public function testWithHostSameAsContextAndAbsolute()
+ {
+ $routes = $this->getRoutes('test', new Route('/{name}', array(), array(), array(), '{locale}.example.com'));
+
+ $this->assertEquals('http://fr.example.com/app.php/Fabien', $this->getGenerator($routes, array('host' => 'fr.example.com'))->generate('test', array('name' => 'Fabien', 'locale' => 'fr'), UrlGeneratorInterface::ABSOLUTE_URL));
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Routing\Exception\InvalidParameterException
+ */
+ public function testUrlWithInvalidParameterInHost()
+ {
+ $routes = $this->getRoutes('test', new Route('/', array(), array('foo' => 'bar'), array(), '{foo}.example.com'));
+ $this->getGenerator($routes)->generate('test', array('foo' => 'baz'), UrlGeneratorInterface::ABSOLUTE_PATH);
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Routing\Exception\InvalidParameterException
+ */
+ public function testUrlWithInvalidParameterInHostWhenParamHasADefaultValue()
+ {
+ $routes = $this->getRoutes('test', new Route('/', array('foo' => 'bar'), array('foo' => 'bar'), array(), '{foo}.example.com'));
+ $this->getGenerator($routes)->generate('test', array('foo' => 'baz'), UrlGeneratorInterface::ABSOLUTE_PATH);
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Routing\Exception\InvalidParameterException
+ */
+ public function testUrlWithInvalidParameterEqualsDefaultValueInHost()
+ {
+ $routes = $this->getRoutes('test', new Route('/', array('foo' => 'baz'), array('foo' => 'bar'), array(), '{foo}.example.com'));
+ $this->getGenerator($routes)->generate('test', array('foo' => 'baz'), UrlGeneratorInterface::ABSOLUTE_PATH);
+ }
+
+ public function testUrlWithInvalidParameterInHostInNonStrictMode()
+ {
+ $routes = $this->getRoutes('test', new Route('/', array(), array('foo' => 'bar'), array(), '{foo}.example.com'));
+ $generator = $this->getGenerator($routes);
+ $generator->setStrictRequirements(false);
+ $this->assertNull($generator->generate('test', array('foo' => 'baz'), UrlGeneratorInterface::ABSOLUTE_PATH));
+ }
+
+ public function testHostIsCaseInsensitive()
+ {
+ $routes = $this->getRoutes('test', new Route('/', array(), array('locale' => 'en|de|fr'), array(), '{locale}.FooBar.com'));
+ $generator = $this->getGenerator($routes);
+ $this->assertSame('//EN.FooBar.com/app.php/', $generator->generate('test', array('locale' => 'EN'), UrlGeneratorInterface::NETWORK_PATH));
+ }
+
+ public function testDefaultHostIsUsedWhenContextHostIsEmpty()
+ {
+ $routes = $this->getRoutes('test', new Route('/route', array('domain' => 'my.fallback.host'), array('domain' => '.+'), array(), '{domain}', array('http')));
+
+ $generator = $this->getGenerator($routes);
+ $generator->getContext()->setHost('');
+
+ $this->assertSame('http://my.fallback.host/app.php/route', $generator->generate('test', array(), UrlGeneratorInterface::ABSOLUTE_URL));
+ }
+
+ public function testDefaultHostIsUsedWhenContextHostIsEmptyAndSchemeIsNot()
+ {
+ $routes = $this->getRoutes('test', new Route('/route', array('domain' => 'my.fallback.host'), array('domain' => '.+'), array(), '{domain}', array('http', 'https')));
+
+ $generator = $this->getGenerator($routes);
+ $generator->getContext()->setHost('');
+ $generator->getContext()->setScheme('https');
+
+ $this->assertSame('https://my.fallback.host/app.php/route', $generator->generate('test', array(), UrlGeneratorInterface::ABSOLUTE_URL));
+ }
+
+ public function testAbsoluteUrlFallbackToRelativeIfHostIsEmptyAndSchemeIsNot()
+ {
+ $routes = $this->getRoutes('test', new Route('/route', array(), array(), array(), '', array('http', 'https')));
+
+ $generator = $this->getGenerator($routes);
+ $generator->getContext()->setHost('');
+ $generator->getContext()->setScheme('https');
+
+ $this->assertSame('/app.php/route', $generator->generate('test', array(), UrlGeneratorInterface::ABSOLUTE_URL));
+ }
+
+ public function testGenerateNetworkPath()
+ {
+ $routes = $this->getRoutes('test', new Route('/{name}', array(), array(), array(), '{locale}.example.com', array('http')));
+
+ $this->assertSame('//fr.example.com/app.php/Fabien', $this->getGenerator($routes)->generate('test',
+ array('name' => 'Fabien', 'locale' => 'fr'), UrlGeneratorInterface::NETWORK_PATH), 'network path with different host'
+ );
+ $this->assertSame('//fr.example.com/app.php/Fabien?query=string', $this->getGenerator($routes, array('host' => 'fr.example.com'))->generate('test',
+ array('name' => 'Fabien', 'locale' => 'fr', 'query' => 'string'), UrlGeneratorInterface::NETWORK_PATH), 'network path although host same as context'
+ );
+ $this->assertSame('http://fr.example.com/app.php/Fabien', $this->getGenerator($routes, array('scheme' => 'https'))->generate('test',
+ array('name' => 'Fabien', 'locale' => 'fr'), UrlGeneratorInterface::NETWORK_PATH), 'absolute URL because scheme requirement does not match context'
+ );
+ $this->assertSame('http://fr.example.com/app.php/Fabien', $this->getGenerator($routes)->generate('test',
+ array('name' => 'Fabien', 'locale' => 'fr'), UrlGeneratorInterface::ABSOLUTE_URL), 'absolute URL with same scheme because it is requested'
+ );
+ }
+
+ public function testGenerateRelativePath()
+ {
+ $routes = new RouteCollection();
+ $routes->add('article', new Route('/{author}/{article}/'));
+ $routes->add('comments', new Route('/{author}/{article}/comments'));
+ $routes->add('host', new Route('/{article}', array(), array(), array(), '{author}.example.com'));
+ $routes->add('scheme', new Route('/{author}/blog', array(), array(), array(), '', array('https')));
+ $routes->add('unrelated', new Route('/about'));
+
+ $generator = $this->getGenerator($routes, array('host' => 'example.com', 'pathInfo' => '/fabien/symfony-is-great/'));
+
+ $this->assertSame('comments', $generator->generate('comments',
+ array('author' => 'fabien', 'article' => 'symfony-is-great'), UrlGeneratorInterface::RELATIVE_PATH)
+ );
+ $this->assertSame('comments?page=2', $generator->generate('comments',
+ array('author' => 'fabien', 'article' => 'symfony-is-great', 'page' => 2), UrlGeneratorInterface::RELATIVE_PATH)
+ );
+ $this->assertSame('../twig-is-great/', $generator->generate('article',
+ array('author' => 'fabien', 'article' => 'twig-is-great'), UrlGeneratorInterface::RELATIVE_PATH)
+ );
+ $this->assertSame('../../bernhard/forms-are-great/', $generator->generate('article',
+ array('author' => 'bernhard', 'article' => 'forms-are-great'), UrlGeneratorInterface::RELATIVE_PATH)
+ );
+ $this->assertSame('//bernhard.example.com/app.php/forms-are-great', $generator->generate('host',
+ array('author' => 'bernhard', 'article' => 'forms-are-great'), UrlGeneratorInterface::RELATIVE_PATH)
+ );
+ $this->assertSame('https://example.com/app.php/bernhard/blog', $generator->generate('scheme',
+ array('author' => 'bernhard'), UrlGeneratorInterface::RELATIVE_PATH)
+ );
+ $this->assertSame('../../about', $generator->generate('unrelated',
+ array(), UrlGeneratorInterface::RELATIVE_PATH)
+ );
+ }
+
+ /**
+ * @dataProvider provideRelativePaths
+ */
+ public function testGetRelativePath($sourcePath, $targetPath, $expectedPath)
+ {
+ $this->assertSame($expectedPath, UrlGenerator::getRelativePath($sourcePath, $targetPath));
+ }
+
+ public function provideRelativePaths()
+ {
+ return array(
+ array(
+ '/same/dir/',
+ '/same/dir/',
+ '',
+ ),
+ array(
+ '/same/file',
+ '/same/file',
+ '',
+ ),
+ array(
+ '/',
+ '/file',
+ 'file',
+ ),
+ array(
+ '/',
+ '/dir/file',
+ 'dir/file',
+ ),
+ array(
+ '/dir/file.html',
+ '/dir/different-file.html',
+ 'different-file.html',
+ ),
+ array(
+ '/same/dir/extra-file',
+ '/same/dir/',
+ './',
+ ),
+ array(
+ '/parent/dir/',
+ '/parent/',
+ '../',
+ ),
+ array(
+ '/parent/dir/extra-file',
+ '/parent/',
+ '../',
+ ),
+ array(
+ '/a/b/',
+ '/x/y/z/',
+ '../../x/y/z/',
+ ),
+ array(
+ '/a/b/c/d/e',
+ '/a/c/d',
+ '../../../c/d',
+ ),
+ array(
+ '/a/b/c//',
+ '/a/b/c/',
+ '../',
+ ),
+ array(
+ '/a/b/c/',
+ '/a/b/c//',
+ './/',
+ ),
+ array(
+ '/root/a/b/c/',
+ '/root/x/b/c/',
+ '../../../x/b/c/',
+ ),
+ array(
+ '/a/b/c/d/',
+ '/a',
+ '../../../../a',
+ ),
+ array(
+ '/special-chars/sp%20ce/1€/mäh/e=mc²',
+ '/special-chars/sp%20ce/1€/<µ>/e=mc²',
+ '../<µ>/e=mc²',
+ ),
+ array(
+ 'not-rooted',
+ 'dir/file',
+ 'dir/file',
+ ),
+ array(
+ '//dir/',
+ '',
+ '../../',
+ ),
+ array(
+ '/dir/',
+ '/dir/file:with-colon',
+ './file:with-colon',
+ ),
+ array(
+ '/dir/',
+ '/dir/subdir/file:with-colon',
+ 'subdir/file:with-colon',
+ ),
+ array(
+ '/dir/',
+ '/dir/:subdir/',
+ './:subdir/',
+ ),
+ );
+ }
+
+ public function testFragmentsCanBeAppendedToUrls()
+ {
+ $routes = $this->getRoutes('test', new Route('/testing'));
+
+ $url = $this->getGenerator($routes)->generate('test', array('_fragment' => 'frag ment'), UrlGeneratorInterface::ABSOLUTE_PATH);
+ $this->assertEquals('/app.php/testing#frag%20ment', $url);
+
+ $url = $this->getGenerator($routes)->generate('test', array('_fragment' => '0'), UrlGeneratorInterface::ABSOLUTE_PATH);
+ $this->assertEquals('/app.php/testing#0', $url);
+ }
+
+ public function testFragmentsDoNotEscapeValidCharacters()
+ {
+ $routes = $this->getRoutes('test', new Route('/testing'));
+ $url = $this->getGenerator($routes)->generate('test', array('_fragment' => '?/'), UrlGeneratorInterface::ABSOLUTE_PATH);
+
+ $this->assertEquals('/app.php/testing#?/', $url);
+ }
+
+ public function testFragmentsCanBeDefinedAsDefaults()
+ {
+ $routes = $this->getRoutes('test', new Route('/testing', array('_fragment' => 'fragment')));
+ $url = $this->getGenerator($routes)->generate('test', array(), UrlGeneratorInterface::ABSOLUTE_PATH);
+
+ $this->assertEquals('/app.php/testing#fragment', $url);
+ }
+
+ protected function getGenerator(RouteCollection $routes, array $parameters = array(), $logger = null)
+ {
+ $context = new RequestContext('/app.php');
+ foreach ($parameters as $key => $value) {
+ $method = 'set'.$key;
+ $context->$method($value);
+ }
+
+ return new UrlGenerator($routes, $context, $logger);
+ }
+
+ protected function getRoutes($name, Route $route)
+ {
+ $routes = new RouteCollection();
+ $routes->add($name, $route);
+
+ return $routes;
+ }
+}
diff --git a/assets/php/vendor/symfony/routing/Tests/Loader/AbstractAnnotationLoaderTest.php b/assets/php/vendor/symfony/routing/Tests/Loader/AbstractAnnotationLoaderTest.php
new file mode 100644
index 0000000..e8bbe8f
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Tests/Loader/AbstractAnnotationLoaderTest.php
@@ -0,0 +1,33 @@
+<?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\Tests\Loader;
+
+use PHPUnit\Framework\TestCase;
+
+abstract class AbstractAnnotationLoaderTest extends TestCase
+{
+ public function getReader()
+ {
+ return $this->getMockBuilder('Doctrine\Common\Annotations\Reader')
+ ->disableOriginalConstructor()
+ ->getMock()
+ ;
+ }
+
+ public function getClassLoader($reader)
+ {
+ return $this->getMockBuilder('Symfony\Component\Routing\Loader\AnnotationClassLoader')
+ ->setConstructorArgs(array($reader))
+ ->getMockForAbstractClass()
+ ;
+ }
+}
diff --git a/assets/php/vendor/symfony/routing/Tests/Loader/AnnotationClassLoaderTest.php b/assets/php/vendor/symfony/routing/Tests/Loader/AnnotationClassLoaderTest.php
new file mode 100644
index 0000000..70db1cc
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Tests/Loader/AnnotationClassLoaderTest.php
@@ -0,0 +1,255 @@
+<?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\Tests\Loader;
+
+use Symfony\Component\Routing\Annotation\Route;
+
+class AnnotationClassLoaderTest extends AbstractAnnotationLoaderTest
+{
+ protected $loader;
+ private $reader;
+
+ protected function setUp()
+ {
+ parent::setUp();
+
+ $this->reader = $this->getReader();
+ $this->loader = $this->getClassLoader($this->reader);
+ }
+
+ /**
+ * @expectedException \InvalidArgumentException
+ */
+ public function testLoadMissingClass()
+ {
+ $this->loader->load('MissingClass');
+ }
+
+ /**
+ * @expectedException \InvalidArgumentException
+ */
+ public function testLoadAbstractClass()
+ {
+ $this->loader->load('Symfony\Component\Routing\Tests\Fixtures\AnnotatedClasses\AbstractClass');
+ }
+
+ /**
+ * @dataProvider provideTestSupportsChecksResource
+ */
+ public function testSupportsChecksResource($resource, $expectedSupports)
+ {
+ $this->assertSame($expectedSupports, $this->loader->supports($resource), '->supports() returns true if the resource is loadable');
+ }
+
+ public function provideTestSupportsChecksResource()
+ {
+ return array(
+ array('class', true),
+ array('\fully\qualified\class\name', true),
+ array('namespaced\class\without\leading\slash', true),
+ array('ÿClassWithLegalSpecialCharacters', true),
+ array('5', false),
+ array('foo.foo', false),
+ array(null, false),
+ );
+ }
+
+ public function testSupportsChecksTypeIfSpecified()
+ {
+ $this->assertTrue($this->loader->supports('class', 'annotation'), '->supports() checks the resource type if specified');
+ $this->assertFalse($this->loader->supports('class', 'foo'), '->supports() checks the resource type if specified');
+ }
+
+ public function getLoadTests()
+ {
+ return array(
+ array(
+ 'Symfony\Component\Routing\Tests\Fixtures\AnnotatedClasses\BarClass',
+ array('name' => 'route1', 'path' => '/path'),
+ array('arg2' => 'defaultValue2', 'arg3' => 'defaultValue3'),
+ ),
+ array(
+ 'Symfony\Component\Routing\Tests\Fixtures\AnnotatedClasses\BarClass',
+ array('defaults' => array('arg2' => 'foo'), 'requirements' => array('arg3' => '\w+')),
+ array('arg2' => 'defaultValue2', 'arg3' => 'defaultValue3'),
+ ),
+ array(
+ 'Symfony\Component\Routing\Tests\Fixtures\AnnotatedClasses\BarClass',
+ array('options' => array('foo' => 'bar')),
+ array('arg2' => 'defaultValue2', 'arg3' => 'defaultValue3'),
+ ),
+ array(
+ 'Symfony\Component\Routing\Tests\Fixtures\AnnotatedClasses\BarClass',
+ array('schemes' => array('https'), 'methods' => array('GET')),
+ array('arg2' => 'defaultValue2', 'arg3' => 'defaultValue3'),
+ ),
+ array(
+ 'Symfony\Component\Routing\Tests\Fixtures\AnnotatedClasses\BarClass',
+ array('condition' => 'context.getMethod() == "GET"'),
+ array('arg2' => 'defaultValue2', 'arg3' => 'defaultValue3'),
+ ),
+ );
+ }
+
+ /**
+ * @dataProvider getLoadTests
+ */
+ public function testLoad($className, $routeData = array(), $methodArgs = array())
+ {
+ $routeData = array_replace(array(
+ 'name' => 'route',
+ 'path' => '/',
+ 'requirements' => array(),
+ 'options' => array(),
+ 'defaults' => array(),
+ 'schemes' => array(),
+ 'methods' => array(),
+ 'condition' => '',
+ ), $routeData);
+
+ $this->reader
+ ->expects($this->once())
+ ->method('getMethodAnnotations')
+ ->will($this->returnValue(array($this->getAnnotatedRoute($routeData))))
+ ;
+
+ $routeCollection = $this->loader->load($className);
+ $route = $routeCollection->get($routeData['name']);
+
+ $this->assertSame($routeData['path'], $route->getPath(), '->load preserves path annotation');
+ $this->assertCount(
+ count($routeData['requirements']),
+ array_intersect_assoc($routeData['requirements'], $route->getRequirements()),
+ '->load preserves requirements annotation'
+ );
+ $this->assertCount(
+ count($routeData['options']),
+ array_intersect_assoc($routeData['options'], $route->getOptions()),
+ '->load preserves options annotation'
+ );
+ $this->assertCount(
+ count($routeData['defaults']),
+ $route->getDefaults(),
+ '->load preserves defaults annotation'
+ );
+ $this->assertEquals($routeData['schemes'], $route->getSchemes(), '->load preserves schemes annotation');
+ $this->assertEquals($routeData['methods'], $route->getMethods(), '->load preserves methods annotation');
+ $this->assertSame($routeData['condition'], $route->getCondition(), '->load preserves condition annotation');
+ }
+
+ public function testClassRouteLoad()
+ {
+ $classRouteData = array(
+ 'name' => 'prefix_',
+ 'path' => '/prefix',
+ 'schemes' => array('https'),
+ 'methods' => array('GET'),
+ );
+
+ $methodRouteData = array(
+ 'name' => 'route1',
+ 'path' => '/path',
+ 'schemes' => array('http'),
+ 'methods' => array('POST', 'PUT'),
+ );
+
+ $this->reader
+ ->expects($this->once())
+ ->method('getClassAnnotation')
+ ->will($this->returnValue($this->getAnnotatedRoute($classRouteData)))
+ ;
+ $this->reader
+ ->expects($this->once())
+ ->method('getMethodAnnotations')
+ ->will($this->returnValue(array($this->getAnnotatedRoute($methodRouteData))))
+ ;
+
+ $routeCollection = $this->loader->load('Symfony\Component\Routing\Tests\Fixtures\AnnotatedClasses\BarClass');
+ $route = $routeCollection->get($classRouteData['name'].$methodRouteData['name']);
+
+ $this->assertSame($classRouteData['path'].$methodRouteData['path'], $route->getPath(), '->load concatenates class and method route path');
+ $this->assertEquals(array_merge($classRouteData['schemes'], $methodRouteData['schemes']), $route->getSchemes(), '->load merges class and method route schemes');
+ $this->assertEquals(array_merge($classRouteData['methods'], $methodRouteData['methods']), $route->getMethods(), '->load merges class and method route methods');
+ }
+
+ public function testInvokableClassRouteLoad()
+ {
+ $classRouteData = array(
+ 'name' => 'route1',
+ 'path' => '/',
+ 'schemes' => array('https'),
+ 'methods' => array('GET'),
+ );
+
+ $this->reader
+ ->expects($this->exactly(2))
+ ->method('getClassAnnotation')
+ ->will($this->returnValue($this->getAnnotatedRoute($classRouteData)))
+ ;
+ $this->reader
+ ->expects($this->once())
+ ->method('getMethodAnnotations')
+ ->will($this->returnValue(array()))
+ ;
+
+ $routeCollection = $this->loader->load('Symfony\Component\Routing\Tests\Fixtures\AnnotatedClasses\BazClass');
+ $route = $routeCollection->get($classRouteData['name']);
+
+ $this->assertSame($classRouteData['path'], $route->getPath(), '->load preserves class route path');
+ $this->assertEquals(array_merge($classRouteData['schemes'], $classRouteData['schemes']), $route->getSchemes(), '->load preserves class route schemes');
+ $this->assertEquals(array_merge($classRouteData['methods'], $classRouteData['methods']), $route->getMethods(), '->load preserves class route methods');
+ }
+
+ public function testInvokableClassWithMethodRouteLoad()
+ {
+ $classRouteData = array(
+ 'name' => 'route1',
+ 'path' => '/prefix',
+ 'schemes' => array('https'),
+ 'methods' => array('GET'),
+ );
+
+ $methodRouteData = array(
+ 'name' => 'route2',
+ 'path' => '/path',
+ 'schemes' => array('http'),
+ 'methods' => array('POST', 'PUT'),
+ );
+
+ $this->reader
+ ->expects($this->once())
+ ->method('getClassAnnotation')
+ ->will($this->returnValue($this->getAnnotatedRoute($classRouteData)))
+ ;
+ $this->reader
+ ->expects($this->once())
+ ->method('getMethodAnnotations')
+ ->will($this->returnValue(array($this->getAnnotatedRoute($methodRouteData))))
+ ;
+
+ $routeCollection = $this->loader->load('Symfony\Component\Routing\Tests\Fixtures\AnnotatedClasses\BazClass');
+ $route = $routeCollection->get($classRouteData['name']);
+
+ $this->assertNull($route, '->load ignores class route');
+
+ $route = $routeCollection->get($classRouteData['name'].$methodRouteData['name']);
+
+ $this->assertSame($classRouteData['path'].$methodRouteData['path'], $route->getPath(), '->load concatenates class and method route path');
+ $this->assertEquals(array_merge($classRouteData['schemes'], $methodRouteData['schemes']), $route->getSchemes(), '->load merges class and method route schemes');
+ $this->assertEquals(array_merge($classRouteData['methods'], $methodRouteData['methods']), $route->getMethods(), '->load merges class and method route methods');
+ }
+
+ private function getAnnotatedRoute($data)
+ {
+ return new Route($data);
+ }
+}
diff --git a/assets/php/vendor/symfony/routing/Tests/Loader/AnnotationDirectoryLoaderTest.php b/assets/php/vendor/symfony/routing/Tests/Loader/AnnotationDirectoryLoaderTest.php
new file mode 100644
index 0000000..1e8ee39
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Tests/Loader/AnnotationDirectoryLoaderTest.php
@@ -0,0 +1,98 @@
+<?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\Tests\Loader;
+
+use Symfony\Component\Routing\Loader\AnnotationDirectoryLoader;
+use Symfony\Component\Config\FileLocator;
+
+class AnnotationDirectoryLoaderTest extends AbstractAnnotationLoaderTest
+{
+ protected $loader;
+ protected $reader;
+
+ protected function setUp()
+ {
+ parent::setUp();
+
+ $this->reader = $this->getReader();
+ $this->loader = new AnnotationDirectoryLoader(new FileLocator(), $this->getClassLoader($this->reader));
+ }
+
+ public function testLoad()
+ {
+ $this->reader->expects($this->exactly(4))->method('getClassAnnotation');
+
+ $this->reader
+ ->expects($this->any())
+ ->method('getMethodAnnotations')
+ ->will($this->returnValue(array()))
+ ;
+
+ $this->loader->load(__DIR__.'/../Fixtures/AnnotatedClasses');
+ }
+
+ public function testLoadIgnoresHiddenDirectories()
+ {
+ $this->expectAnnotationsToBeReadFrom(array(
+ 'Symfony\Component\Routing\Tests\Fixtures\AnnotatedClasses\BarClass',
+ 'Symfony\Component\Routing\Tests\Fixtures\AnnotatedClasses\BazClass',
+ 'Symfony\Component\Routing\Tests\Fixtures\AnnotatedClasses\BazClass',
+ 'Symfony\Component\Routing\Tests\Fixtures\AnnotatedClasses\FooClass',
+ ));
+
+ $this->reader
+ ->expects($this->any())
+ ->method('getMethodAnnotations')
+ ->will($this->returnValue(array()))
+ ;
+
+ $this->loader->load(__DIR__.'/../Fixtures/AnnotatedClasses');
+ }
+
+ public function testSupports()
+ {
+ $fixturesDir = __DIR__.'/../Fixtures';
+
+ $this->assertTrue($this->loader->supports($fixturesDir), '->supports() returns true if the resource is loadable');
+ $this->assertFalse($this->loader->supports('foo.foo'), '->supports() returns true if the resource is loadable');
+
+ $this->assertTrue($this->loader->supports($fixturesDir, 'annotation'), '->supports() checks the resource type if specified');
+ $this->assertFalse($this->loader->supports($fixturesDir, 'foo'), '->supports() checks the resource type if specified');
+ }
+
+ public function testItSupportsAnyAnnotation()
+ {
+ $this->assertTrue($this->loader->supports(__DIR__.'/../Fixtures/even-with-not-existing-folder', 'annotation'));
+ }
+
+ public function testLoadFileIfLocatedResourceIsFile()
+ {
+ $this->reader->expects($this->exactly(1))->method('getClassAnnotation');
+
+ $this->reader
+ ->expects($this->any())
+ ->method('getMethodAnnotations')
+ ->will($this->returnValue(array()))
+ ;
+
+ $this->loader->load(__DIR__.'/../Fixtures/AnnotatedClasses/FooClass.php');
+ }
+
+ private function expectAnnotationsToBeReadFrom(array $classes)
+ {
+ $this->reader->expects($this->exactly(count($classes)))
+ ->method('getClassAnnotation')
+ ->with($this->callback(function (\ReflectionClass $class) use ($classes) {
+ return in_array($class->getName(), $classes);
+ }));
+ }
+}
diff --git a/assets/php/vendor/symfony/routing/Tests/Loader/AnnotationFileLoaderTest.php b/assets/php/vendor/symfony/routing/Tests/Loader/AnnotationFileLoaderTest.php
new file mode 100644
index 0000000..7f1d576
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Tests/Loader/AnnotationFileLoaderTest.php
@@ -0,0 +1,91 @@
+<?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\Tests\Loader;
+
+use Symfony\Component\Routing\Loader\AnnotationFileLoader;
+use Symfony\Component\Config\FileLocator;
+use Symfony\Component\Routing\Annotation\Route;
+
+class AnnotationFileLoaderTest extends AbstractAnnotationLoaderTest
+{
+ protected $loader;
+ protected $reader;
+
+ protected function setUp()
+ {
+ parent::setUp();
+
+ $this->reader = $this->getReader();
+ $this->loader = new AnnotationFileLoader(new FileLocator(), $this->getClassLoader($this->reader));
+ }
+
+ public function testLoad()
+ {
+ $this->reader->expects($this->once())->method('getClassAnnotation');
+
+ $this->loader->load(__DIR__.'/../Fixtures/AnnotatedClasses/FooClass.php');
+ }
+
+ /**
+ * @requires PHP 5.4
+ */
+ public function testLoadTraitWithClassConstant()
+ {
+ $this->reader->expects($this->never())->method('getClassAnnotation');
+
+ $this->loader->load(__DIR__.'/../Fixtures/AnnotatedClasses/FooTrait.php');
+ }
+
+ /**
+ * @expectedException \InvalidArgumentException
+ * @expectedExceptionMessage Did you forgot to add the "<?php" start tag at the beginning of the file?
+ */
+ public function testLoadFileWithoutStartTag()
+ {
+ $this->loader->load(__DIR__.'/../Fixtures/OtherAnnotatedClasses/NoStartTagClass.php');
+ }
+
+ /**
+ * @requires PHP 5.6
+ */
+ public function testLoadVariadic()
+ {
+ $route = new Route(array('path' => '/path/to/{id}'));
+ $this->reader->expects($this->once())->method('getClassAnnotation');
+ $this->reader->expects($this->once())->method('getMethodAnnotations')
+ ->will($this->returnValue(array($route)));
+
+ $this->loader->load(__DIR__.'/../Fixtures/OtherAnnotatedClasses/VariadicClass.php');
+ }
+
+ /**
+ * @requires PHP 7.0
+ */
+ public function testLoadAnonymousClass()
+ {
+ $this->reader->expects($this->never())->method('getClassAnnotation');
+ $this->reader->expects($this->never())->method('getMethodAnnotations');
+
+ $this->loader->load(__DIR__.'/../Fixtures/OtherAnnotatedClasses/AnonymousClassInTrait.php');
+ }
+
+ public function testSupports()
+ {
+ $fixture = __DIR__.'/../Fixtures/annotated.php';
+
+ $this->assertTrue($this->loader->supports($fixture), '->supports() returns true if the resource is loadable');
+ $this->assertFalse($this->loader->supports('foo.foo'), '->supports() returns true if the resource is loadable');
+
+ $this->assertTrue($this->loader->supports($fixture, 'annotation'), '->supports() checks the resource type if specified');
+ $this->assertFalse($this->loader->supports($fixture, 'foo'), '->supports() checks the resource type if specified');
+ }
+}
diff --git a/assets/php/vendor/symfony/routing/Tests/Loader/ClosureLoaderTest.php b/assets/php/vendor/symfony/routing/Tests/Loader/ClosureLoaderTest.php
new file mode 100644
index 0000000..5d963f8
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Tests/Loader/ClosureLoaderTest.php
@@ -0,0 +1,49 @@
+<?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\Tests\Loader;
+
+use PHPUnit\Framework\TestCase;
+use Symfony\Component\Routing\Loader\ClosureLoader;
+use Symfony\Component\Routing\Route;
+use Symfony\Component\Routing\RouteCollection;
+
+class ClosureLoaderTest extends TestCase
+{
+ public function testSupports()
+ {
+ $loader = new ClosureLoader();
+
+ $closure = function () {};
+
+ $this->assertTrue($loader->supports($closure), '->supports() returns true if the resource is loadable');
+ $this->assertFalse($loader->supports('foo.foo'), '->supports() returns true if the resource is loadable');
+
+ $this->assertTrue($loader->supports($closure, 'closure'), '->supports() checks the resource type if specified');
+ $this->assertFalse($loader->supports($closure, 'foo'), '->supports() checks the resource type if specified');
+ }
+
+ public function testLoad()
+ {
+ $loader = new ClosureLoader();
+
+ $route = new Route('/');
+ $routes = $loader->load(function () use ($route) {
+ $routes = new RouteCollection();
+
+ $routes->add('foo', $route);
+
+ return $routes;
+ });
+
+ $this->assertEquals($route, $routes->get('foo'), '->load() loads a \Closure resource');
+ }
+}
diff --git a/assets/php/vendor/symfony/routing/Tests/Loader/DirectoryLoaderTest.php b/assets/php/vendor/symfony/routing/Tests/Loader/DirectoryLoaderTest.php
new file mode 100644
index 0000000..fc29d37
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Tests/Loader/DirectoryLoaderTest.php
@@ -0,0 +1,74 @@
+<?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\Tests\Loader;
+
+use Symfony\Component\Routing\Loader\DirectoryLoader;
+use Symfony\Component\Routing\Loader\YamlFileLoader;
+use Symfony\Component\Routing\Loader\AnnotationFileLoader;
+use Symfony\Component\Config\Loader\LoaderResolver;
+use Symfony\Component\Config\FileLocator;
+use Symfony\Component\Routing\RouteCollection;
+
+class DirectoryLoaderTest extends AbstractAnnotationLoaderTest
+{
+ private $loader;
+ private $reader;
+
+ protected function setUp()
+ {
+ parent::setUp();
+
+ $locator = new FileLocator();
+ $this->reader = $this->getReader();
+ $this->loader = new DirectoryLoader($locator);
+ $resolver = new LoaderResolver(array(
+ new YamlFileLoader($locator),
+ new AnnotationFileLoader($locator, $this->getClassLoader($this->reader)),
+ $this->loader,
+ ));
+ $this->loader->setResolver($resolver);
+ }
+
+ public function testLoadDirectory()
+ {
+ $collection = $this->loader->load(__DIR__.'/../Fixtures/directory', 'directory');
+ $this->verifyCollection($collection);
+ }
+
+ public function testImportDirectory()
+ {
+ $collection = $this->loader->load(__DIR__.'/../Fixtures/directory_import', 'directory');
+ $this->verifyCollection($collection);
+ }
+
+ private function verifyCollection(RouteCollection $collection)
+ {
+ $routes = $collection->all();
+
+ $this->assertCount(3, $routes, 'Three routes are loaded');
+ $this->assertContainsOnly('Symfony\Component\Routing\Route', $routes);
+
+ for ($i = 1; $i <= 3; ++$i) {
+ $this->assertSame('/route/'.$i, $routes['route'.$i]->getPath());
+ }
+ }
+
+ public function testSupports()
+ {
+ $fixturesDir = __DIR__.'/../Fixtures';
+
+ $this->assertFalse($this->loader->supports($fixturesDir), '->supports(*) returns false');
+
+ $this->assertTrue($this->loader->supports($fixturesDir, 'directory'), '->supports(*, "directory") returns true');
+ $this->assertFalse($this->loader->supports($fixturesDir, 'foo'), '->supports(*, "foo") returns false');
+ }
+}
diff --git a/assets/php/vendor/symfony/routing/Tests/Loader/GlobFileLoaderTest.php b/assets/php/vendor/symfony/routing/Tests/Loader/GlobFileLoaderTest.php
new file mode 100644
index 0000000..08d806a
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Tests/Loader/GlobFileLoaderTest.php
@@ -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\Tests\Loader;
+
+use PHPUnit\Framework\TestCase;
+use Symfony\Component\Config\Resource\GlobResource;
+use Symfony\Component\Config\FileLocator;
+use Symfony\Component\Routing\Loader\GlobFileLoader;
+use Symfony\Component\Routing\RouteCollection;
+
+class GlobFileLoaderTest extends TestCase
+{
+ public function testSupports()
+ {
+ $loader = new GlobFileLoader(new FileLocator());
+
+ $this->assertTrue($loader->supports('any-path', 'glob'), '->supports() returns true if the resource has the glob type');
+ $this->assertFalse($loader->supports('any-path'), '->supports() returns false if the resource is not of glob type');
+ }
+
+ public function testLoadAddsTheGlobResourceToTheContainer()
+ {
+ $loader = new GlobFileLoaderWithoutImport(new FileLocator());
+ $collection = $loader->load(__DIR__.'/../Fixtures/directory/*.yml');
+
+ $this->assertEquals(new GlobResource(__DIR__.'/../Fixtures/directory', '/*.yml', false), $collection->getResources()[0]);
+ }
+}
+
+class GlobFileLoaderWithoutImport extends GlobFileLoader
+{
+ public function import($resource, $type = null, $ignoreErrors = false, $sourceResource = null)
+ {
+ return new RouteCollection();
+ }
+}
diff --git a/assets/php/vendor/symfony/routing/Tests/Loader/ObjectRouteLoaderTest.php b/assets/php/vendor/symfony/routing/Tests/Loader/ObjectRouteLoaderTest.php
new file mode 100644
index 0000000..408fa0b
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Tests/Loader/ObjectRouteLoaderTest.php
@@ -0,0 +1,123 @@
+<?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\Tests\Loader;
+
+use PHPUnit\Framework\TestCase;
+use Symfony\Component\Routing\Loader\ObjectRouteLoader;
+use Symfony\Component\Routing\Route;
+use Symfony\Component\Routing\RouteCollection;
+
+class ObjectRouteLoaderTest extends TestCase
+{
+ public function testLoadCallsServiceAndReturnsCollection()
+ {
+ $loader = new ObjectRouteLoaderForTest();
+
+ // create a basic collection that will be returned
+ $collection = new RouteCollection();
+ $collection->add('foo', new Route('/foo'));
+
+ $loader->loaderMap = array(
+ 'my_route_provider_service' => new RouteService($collection),
+ );
+
+ $actualRoutes = $loader->load(
+ 'my_route_provider_service:loadRoutes',
+ 'service'
+ );
+
+ $this->assertSame($collection, $actualRoutes);
+ // the service file should be listed as a resource
+ $this->assertNotEmpty($actualRoutes->getResources());
+ }
+
+ /**
+ * @expectedException \InvalidArgumentException
+ * @dataProvider getBadResourceStrings
+ */
+ public function testExceptionWithoutSyntax($resourceString)
+ {
+ $loader = new ObjectRouteLoaderForTest();
+ $loader->load($resourceString);
+ }
+
+ public function getBadResourceStrings()
+ {
+ return array(
+ array('Foo'),
+ array('Bar::baz'),
+ array('Foo:Bar:baz'),
+ );
+ }
+
+ /**
+ * @expectedException \LogicException
+ */
+ public function testExceptionOnNoObjectReturned()
+ {
+ $loader = new ObjectRouteLoaderForTest();
+ $loader->loaderMap = array('my_service' => 'NOT_AN_OBJECT');
+ $loader->load('my_service:method');
+ }
+
+ /**
+ * @expectedException \BadMethodCallException
+ */
+ public function testExceptionOnBadMethod()
+ {
+ $loader = new ObjectRouteLoaderForTest();
+ $loader->loaderMap = array('my_service' => new \stdClass());
+ $loader->load('my_service:method');
+ }
+
+ /**
+ * @expectedException \LogicException
+ */
+ public function testExceptionOnMethodNotReturningCollection()
+ {
+ $service = $this->getMockBuilder('stdClass')
+ ->setMethods(array('loadRoutes'))
+ ->getMock();
+ $service->expects($this->once())
+ ->method('loadRoutes')
+ ->will($this->returnValue('NOT_A_COLLECTION'));
+
+ $loader = new ObjectRouteLoaderForTest();
+ $loader->loaderMap = array('my_service' => $service);
+ $loader->load('my_service:loadRoutes');
+ }
+}
+
+class ObjectRouteLoaderForTest extends ObjectRouteLoader
+{
+ public $loaderMap = array();
+
+ protected function getServiceObject($id)
+ {
+ return isset($this->loaderMap[$id]) ? $this->loaderMap[$id] : null;
+ }
+}
+
+class RouteService
+{
+ private $collection;
+
+ public function __construct($collection)
+ {
+ $this->collection = $collection;
+ }
+
+ public function loadRoutes()
+ {
+ return $this->collection;
+ }
+}
diff --git a/assets/php/vendor/symfony/routing/Tests/Loader/PhpFileLoaderTest.php b/assets/php/vendor/symfony/routing/Tests/Loader/PhpFileLoaderTest.php
new file mode 100644
index 0000000..0dcf5d4
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Tests/Loader/PhpFileLoaderTest.php
@@ -0,0 +1,133 @@
+<?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\Tests\Loader;
+
+use PHPUnit\Framework\TestCase;
+use Symfony\Component\Config\FileLocator;
+use Symfony\Component\Config\Resource\FileResource;
+use Symfony\Component\Routing\Loader\PhpFileLoader;
+use Symfony\Component\Routing\Route;
+use Symfony\Component\Routing\RouteCollection;
+
+class PhpFileLoaderTest extends TestCase
+{
+ public function testSupports()
+ {
+ $loader = new PhpFileLoader($this->getMockBuilder('Symfony\Component\Config\FileLocator')->getMock());
+
+ $this->assertTrue($loader->supports('foo.php'), '->supports() returns true if the resource is loadable');
+ $this->assertFalse($loader->supports('foo.foo'), '->supports() returns true if the resource is loadable');
+
+ $this->assertTrue($loader->supports('foo.php', 'php'), '->supports() checks the resource type if specified');
+ $this->assertFalse($loader->supports('foo.php', 'foo'), '->supports() checks the resource type if specified');
+ }
+
+ public function testLoadWithRoute()
+ {
+ $loader = new PhpFileLoader(new FileLocator(array(__DIR__.'/../Fixtures')));
+ $routeCollection = $loader->load('validpattern.php');
+ $routes = $routeCollection->all();
+
+ $this->assertCount(1, $routes, 'One route is loaded');
+ $this->assertContainsOnly('Symfony\Component\Routing\Route', $routes);
+
+ foreach ($routes as $route) {
+ $this->assertSame('/blog/{slug}', $route->getPath());
+ $this->assertSame('MyBlogBundle:Blog:show', $route->getDefault('_controller'));
+ $this->assertSame('{locale}.example.com', $route->getHost());
+ $this->assertSame('RouteCompiler', $route->getOption('compiler_class'));
+ $this->assertEquals(array('GET', 'POST', 'PUT', 'OPTIONS'), $route->getMethods());
+ $this->assertEquals(array('https'), $route->getSchemes());
+ }
+ }
+
+ public function testLoadWithImport()
+ {
+ $loader = new PhpFileLoader(new FileLocator(array(__DIR__.'/../Fixtures')));
+ $routeCollection = $loader->load('validresource.php');
+ $routes = $routeCollection->all();
+
+ $this->assertCount(1, $routes, 'One route is loaded');
+ $this->assertContainsOnly('Symfony\Component\Routing\Route', $routes);
+
+ foreach ($routes as $route) {
+ $this->assertSame('/prefix/blog/{slug}', $route->getPath());
+ $this->assertSame('MyBlogBundle:Blog:show', $route->getDefault('_controller'));
+ $this->assertSame('{locale}.example.com', $route->getHost());
+ $this->assertSame('RouteCompiler', $route->getOption('compiler_class'));
+ $this->assertEquals(array('GET', 'POST', 'PUT', 'OPTIONS'), $route->getMethods());
+ $this->assertEquals(array('https'), $route->getSchemes());
+ }
+ }
+
+ public function testThatDefiningVariableInConfigFileHasNoSideEffects()
+ {
+ $locator = new FileLocator(array(__DIR__.'/../Fixtures'));
+ $loader = new PhpFileLoader($locator);
+ $routeCollection = $loader->load('with_define_path_variable.php');
+ $resources = $routeCollection->getResources();
+ $this->assertCount(1, $resources);
+ $this->assertContainsOnly('Symfony\Component\Config\Resource\ResourceInterface', $resources);
+ $fileResource = reset($resources);
+ $this->assertSame(
+ realpath($locator->locate('with_define_path_variable.php')),
+ (string) $fileResource
+ );
+ }
+
+ public function testRoutingConfigurator()
+ {
+ $locator = new FileLocator(array(__DIR__.'/../Fixtures'));
+ $loader = new PhpFileLoader($locator);
+ $routeCollection = $loader->load('php_dsl.php');
+
+ $expectedCollection = new RouteCollection();
+
+ $expectedCollection->add('foo', (new Route('/foo'))
+ ->setOptions(array('utf8' => true))
+ ->setCondition('abc')
+ );
+ $expectedCollection->add('buz', (new Route('/zub'))
+ ->setDefaults(array('_controller' => 'foo:act'))
+ );
+ $expectedCollection->add('c_bar', (new Route('/sub/pub/bar'))
+ ->setRequirements(array('id' => '\d+'))
+ );
+ $expectedCollection->add('c_pub_buz', (new Route('/sub/pub/buz'))
+ ->setHost('host')
+ ->setRequirements(array('id' => '\d+'))
+ );
+ $expectedCollection->add('ouf', (new Route('/ouf'))
+ ->setSchemes(array('https'))
+ ->setMethods(array('GET'))
+ ->setDefaults(array('id' => 0))
+ );
+
+ $expectedCollection->addResource(new FileResource(realpath(__DIR__.'/../Fixtures/php_dsl_sub.php')));
+ $expectedCollection->addResource(new FileResource(realpath(__DIR__.'/../Fixtures/php_dsl.php')));
+
+ $this->assertEquals($expectedCollection, $routeCollection);
+ }
+
+ public function testRoutingConfiguratorCanImportGlobPatterns()
+ {
+ $locator = new FileLocator(array(__DIR__.'/../Fixtures/glob'));
+ $loader = new PhpFileLoader($locator);
+ $routeCollection = $loader->load('php_dsl.php');
+
+ $route = $routeCollection->get('bar_route');
+ $this->assertSame('AppBundle:Bar:view', $route->getDefault('_controller'));
+
+ $route = $routeCollection->get('baz_route');
+ $this->assertSame('AppBundle:Baz:view', $route->getDefault('_controller'));
+ }
+}
diff --git a/assets/php/vendor/symfony/routing/Tests/Loader/XmlFileLoaderTest.php b/assets/php/vendor/symfony/routing/Tests/Loader/XmlFileLoaderTest.php
new file mode 100644
index 0000000..21fc340
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Tests/Loader/XmlFileLoaderTest.php
@@ -0,0 +1,385 @@
+<?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\Tests\Loader;
+
+use PHPUnit\Framework\TestCase;
+use Symfony\Component\Config\FileLocator;
+use Symfony\Component\Routing\Loader\XmlFileLoader;
+use Symfony\Component\Routing\Tests\Fixtures\CustomXmlFileLoader;
+
+class XmlFileLoaderTest extends TestCase
+{
+ public function testSupports()
+ {
+ $loader = new XmlFileLoader($this->getMockBuilder('Symfony\Component\Config\FileLocator')->getMock());
+
+ $this->assertTrue($loader->supports('foo.xml'), '->supports() returns true if the resource is loadable');
+ $this->assertFalse($loader->supports('foo.foo'), '->supports() returns true if the resource is loadable');
+
+ $this->assertTrue($loader->supports('foo.xml', 'xml'), '->supports() checks the resource type if specified');
+ $this->assertFalse($loader->supports('foo.xml', 'foo'), '->supports() checks the resource type if specified');
+ }
+
+ public function testLoadWithRoute()
+ {
+ $loader = new XmlFileLoader(new FileLocator(array(__DIR__.'/../Fixtures')));
+ $routeCollection = $loader->load('validpattern.xml');
+ $route = $routeCollection->get('blog_show');
+
+ $this->assertInstanceOf('Symfony\Component\Routing\Route', $route);
+ $this->assertSame('/blog/{slug}', $route->getPath());
+ $this->assertSame('{locale}.example.com', $route->getHost());
+ $this->assertSame('MyBundle:Blog:show', $route->getDefault('_controller'));
+ $this->assertSame('\w+', $route->getRequirement('locale'));
+ $this->assertSame('RouteCompiler', $route->getOption('compiler_class'));
+ $this->assertEquals(array('GET', 'POST', 'PUT', 'OPTIONS'), $route->getMethods());
+ $this->assertEquals(array('https'), $route->getSchemes());
+ $this->assertEquals('context.getMethod() == "GET"', $route->getCondition());
+ }
+
+ public function testLoadWithNamespacePrefix()
+ {
+ $loader = new XmlFileLoader(new FileLocator(array(__DIR__.'/../Fixtures')));
+ $routeCollection = $loader->load('namespaceprefix.xml');
+
+ $this->assertCount(1, $routeCollection->all(), 'One route is loaded');
+
+ $route = $routeCollection->get('blog_show');
+ $this->assertSame('/blog/{slug}', $route->getPath());
+ $this->assertSame('{_locale}.example.com', $route->getHost());
+ $this->assertSame('MyBundle:Blog:show', $route->getDefault('_controller'));
+ $this->assertSame('\w+', $route->getRequirement('slug'));
+ $this->assertSame('en|fr|de', $route->getRequirement('_locale'));
+ $this->assertNull($route->getDefault('slug'));
+ $this->assertSame('RouteCompiler', $route->getOption('compiler_class'));
+ $this->assertSame(1, $route->getDefault('page'));
+ }
+
+ public function testLoadWithImport()
+ {
+ $loader = new XmlFileLoader(new FileLocator(array(__DIR__.'/../Fixtures')));
+ $routeCollection = $loader->load('validresource.xml');
+ $routes = $routeCollection->all();
+
+ $this->assertCount(2, $routes, 'Two routes are loaded');
+ $this->assertContainsOnly('Symfony\Component\Routing\Route', $routes);
+
+ foreach ($routes as $route) {
+ $this->assertSame('/{foo}/blog/{slug}', $route->getPath());
+ $this->assertSame('123', $route->getDefault('foo'));
+ $this->assertSame('\d+', $route->getRequirement('foo'));
+ $this->assertSame('bar', $route->getOption('foo'));
+ $this->assertSame('', $route->getHost());
+ $this->assertSame('context.getMethod() == "POST"', $route->getCondition());
+ }
+ }
+
+ /**
+ * @expectedException \InvalidArgumentException
+ * @dataProvider getPathsToInvalidFiles
+ */
+ public function testLoadThrowsExceptionWithInvalidFile($filePath)
+ {
+ $loader = new XmlFileLoader(new FileLocator(array(__DIR__.'/../Fixtures')));
+ $loader->load($filePath);
+ }
+
+ /**
+ * @expectedException \InvalidArgumentException
+ * @dataProvider getPathsToInvalidFiles
+ */
+ public function testLoadThrowsExceptionWithInvalidFileEvenWithoutSchemaValidation($filePath)
+ {
+ $loader = new CustomXmlFileLoader(new FileLocator(array(__DIR__.'/../Fixtures')));
+ $loader->load($filePath);
+ }
+
+ public function getPathsToInvalidFiles()
+ {
+ return array(array('nonvalidnode.xml'), array('nonvalidroute.xml'), array('nonvalid.xml'), array('missing_id.xml'), array('missing_path.xml'));
+ }
+
+ /**
+ * @expectedException \InvalidArgumentException
+ * @expectedExceptionMessage Document types are not allowed.
+ */
+ public function testDocTypeIsNotAllowed()
+ {
+ $loader = new XmlFileLoader(new FileLocator(array(__DIR__.'/../Fixtures')));
+ $loader->load('withdoctype.xml');
+ }
+
+ public function testNullValues()
+ {
+ $loader = new XmlFileLoader(new FileLocator(array(__DIR__.'/../Fixtures')));
+ $routeCollection = $loader->load('null_values.xml');
+ $route = $routeCollection->get('blog_show');
+
+ $this->assertTrue($route->hasDefault('foo'));
+ $this->assertNull($route->getDefault('foo'));
+ $this->assertTrue($route->hasDefault('bar'));
+ $this->assertNull($route->getDefault('bar'));
+ $this->assertEquals('foo', $route->getDefault('foobar'));
+ $this->assertEquals('bar', $route->getDefault('baz'));
+ }
+
+ public function testScalarDataTypeDefaults()
+ {
+ $loader = new XmlFileLoader(new FileLocator(array(__DIR__.'/../Fixtures')));
+ $routeCollection = $loader->load('scalar_defaults.xml');
+ $route = $routeCollection->get('blog');
+
+ $this->assertSame(
+ array(
+ '_controller' => 'AcmeBlogBundle:Blog:index',
+ 'slug' => null,
+ 'published' => true,
+ 'page' => 1,
+ 'price' => 3.5,
+ 'archived' => false,
+ 'free' => true,
+ 'locked' => false,
+ 'foo' => null,
+ 'bar' => null,
+ ),
+ $route->getDefaults()
+ );
+ }
+
+ public function testListDefaults()
+ {
+ $loader = new XmlFileLoader(new FileLocator(array(__DIR__.'/../Fixtures')));
+ $routeCollection = $loader->load('list_defaults.xml');
+ $route = $routeCollection->get('blog');
+
+ $this->assertSame(
+ array(
+ '_controller' => 'AcmeBlogBundle:Blog:index',
+ 'values' => array(true, 1, 3.5, 'foo'),
+ ),
+ $route->getDefaults()
+ );
+ }
+
+ public function testListInListDefaults()
+ {
+ $loader = new XmlFileLoader(new FileLocator(array(__DIR__.'/../Fixtures')));
+ $routeCollection = $loader->load('list_in_list_defaults.xml');
+ $route = $routeCollection->get('blog');
+
+ $this->assertSame(
+ array(
+ '_controller' => 'AcmeBlogBundle:Blog:index',
+ 'values' => array(array(true, 1, 3.5, 'foo')),
+ ),
+ $route->getDefaults()
+ );
+ }
+
+ public function testListInMapDefaults()
+ {
+ $loader = new XmlFileLoader(new FileLocator(array(__DIR__.'/../Fixtures')));
+ $routeCollection = $loader->load('list_in_map_defaults.xml');
+ $route = $routeCollection->get('blog');
+
+ $this->assertSame(
+ array(
+ '_controller' => 'AcmeBlogBundle:Blog:index',
+ 'values' => array('list' => array(true, 1, 3.5, 'foo')),
+ ),
+ $route->getDefaults()
+ );
+ }
+
+ public function testMapDefaults()
+ {
+ $loader = new XmlFileLoader(new FileLocator(array(__DIR__.'/../Fixtures')));
+ $routeCollection = $loader->load('map_defaults.xml');
+ $route = $routeCollection->get('blog');
+
+ $this->assertSame(
+ array(
+ '_controller' => 'AcmeBlogBundle:Blog:index',
+ 'values' => array(
+ 'public' => true,
+ 'page' => 1,
+ 'price' => 3.5,
+ 'title' => 'foo',
+ ),
+ ),
+ $route->getDefaults()
+ );
+ }
+
+ public function testMapInListDefaults()
+ {
+ $loader = new XmlFileLoader(new FileLocator(array(__DIR__.'/../Fixtures')));
+ $routeCollection = $loader->load('map_in_list_defaults.xml');
+ $route = $routeCollection->get('blog');
+
+ $this->assertSame(
+ array(
+ '_controller' => 'AcmeBlogBundle:Blog:index',
+ 'values' => array(array(
+ 'public' => true,
+ 'page' => 1,
+ 'price' => 3.5,
+ 'title' => 'foo',
+ )),
+ ),
+ $route->getDefaults()
+ );
+ }
+
+ public function testMapInMapDefaults()
+ {
+ $loader = new XmlFileLoader(new FileLocator(array(__DIR__.'/../Fixtures')));
+ $routeCollection = $loader->load('map_in_map_defaults.xml');
+ $route = $routeCollection->get('blog');
+
+ $this->assertSame(
+ array(
+ '_controller' => 'AcmeBlogBundle:Blog:index',
+ 'values' => array('map' => array(
+ 'public' => true,
+ 'page' => 1,
+ 'price' => 3.5,
+ 'title' => 'foo',
+ )),
+ ),
+ $route->getDefaults()
+ );
+ }
+
+ public function testNullValuesInList()
+ {
+ $loader = new XmlFileLoader(new FileLocator(array(__DIR__.'/../Fixtures')));
+ $routeCollection = $loader->load('list_null_values.xml');
+ $route = $routeCollection->get('blog');
+
+ $this->assertSame(array(null, null, null, null, null, null), $route->getDefault('list'));
+ }
+
+ public function testNullValuesInMap()
+ {
+ $loader = new XmlFileLoader(new FileLocator(array(__DIR__.'/../Fixtures')));
+ $routeCollection = $loader->load('map_null_values.xml');
+ $route = $routeCollection->get('blog');
+
+ $this->assertSame(
+ array(
+ 'boolean' => null,
+ 'integer' => null,
+ 'float' => null,
+ 'string' => null,
+ 'list' => null,
+ 'map' => null,
+ ),
+ $route->getDefault('map')
+ );
+ }
+
+ public function testLoadRouteWithControllerAttribute()
+ {
+ $loader = new XmlFileLoader(new FileLocator(array(__DIR__.'/../Fixtures/controller')));
+ $routeCollection = $loader->load('routing.xml');
+
+ $route = $routeCollection->get('app_homepage');
+
+ $this->assertSame('AppBundle:Homepage:show', $route->getDefault('_controller'));
+ }
+
+ public function testLoadRouteWithoutControllerAttribute()
+ {
+ $loader = new XmlFileLoader(new FileLocator(array(__DIR__.'/../Fixtures/controller')));
+ $routeCollection = $loader->load('routing.xml');
+
+ $route = $routeCollection->get('app_logout');
+
+ $this->assertNull($route->getDefault('_controller'));
+ }
+
+ public function testLoadRouteWithControllerSetInDefaults()
+ {
+ $loader = new XmlFileLoader(new FileLocator(array(__DIR__.'/../Fixtures/controller')));
+ $routeCollection = $loader->load('routing.xml');
+
+ $route = $routeCollection->get('app_blog');
+
+ $this->assertSame('AppBundle:Blog:list', $route->getDefault('_controller'));
+ }
+
+ /**
+ * @expectedException \InvalidArgumentException
+ * @expectedExceptionMessageRegExp /The routing file "[^"]*" must not specify both the "controller" attribute and the defaults key "_controller" for "app_blog"/
+ */
+ public function testOverrideControllerInDefaults()
+ {
+ $loader = new XmlFileLoader(new FileLocator(array(__DIR__.'/../Fixtures/controller')));
+ $loader->load('override_defaults.xml');
+ }
+
+ /**
+ * @dataProvider provideFilesImportingRoutesWithControllers
+ */
+ public function testImportRouteWithController($file)
+ {
+ $loader = new XmlFileLoader(new FileLocator(array(__DIR__.'/../Fixtures/controller')));
+ $routeCollection = $loader->load($file);
+
+ $route = $routeCollection->get('app_homepage');
+ $this->assertSame('FrameworkBundle:Template:template', $route->getDefault('_controller'));
+
+ $route = $routeCollection->get('app_blog');
+ $this->assertSame('FrameworkBundle:Template:template', $route->getDefault('_controller'));
+
+ $route = $routeCollection->get('app_logout');
+ $this->assertSame('FrameworkBundle:Template:template', $route->getDefault('_controller'));
+ }
+
+ public function provideFilesImportingRoutesWithControllers()
+ {
+ yield array('import_controller.xml');
+ yield array('import__controller.xml');
+ }
+
+ /**
+ * @expectedException \InvalidArgumentException
+ * @expectedExceptionMessageRegExp /The routing file "[^"]*" must not specify both the "controller" attribute and the defaults key "_controller" for the "import" tag/
+ */
+ public function testImportWithOverriddenController()
+ {
+ $loader = new XmlFileLoader(new FileLocator(array(__DIR__.'/../Fixtures/controller')));
+ $loader->load('import_override_defaults.xml');
+ }
+
+ public function testImportRouteWithGlobMatchingSingleFile()
+ {
+ $loader = new XmlFileLoader(new FileLocator(array(__DIR__.'/../Fixtures/glob')));
+ $routeCollection = $loader->load('import_single.xml');
+
+ $route = $routeCollection->get('bar_route');
+ $this->assertSame('AppBundle:Bar:view', $route->getDefault('_controller'));
+ }
+
+ public function testImportRouteWithGlobMatchingMultipleFiles()
+ {
+ $loader = new XmlFileLoader(new FileLocator(array(__DIR__.'/../Fixtures/glob')));
+ $routeCollection = $loader->load('import_multiple.xml');
+
+ $route = $routeCollection->get('bar_route');
+ $this->assertSame('AppBundle:Bar:view', $route->getDefault('_controller'));
+
+ $route = $routeCollection->get('baz_route');
+ $this->assertSame('AppBundle:Baz:view', $route->getDefault('_controller'));
+ }
+}
diff --git a/assets/php/vendor/symfony/routing/Tests/Loader/YamlFileLoaderTest.php b/assets/php/vendor/symfony/routing/Tests/Loader/YamlFileLoaderTest.php
new file mode 100644
index 0000000..822bddf
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Tests/Loader/YamlFileLoaderTest.php
@@ -0,0 +1,206 @@
+<?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\Tests\Loader;
+
+use PHPUnit\Framework\TestCase;
+use Symfony\Component\Config\FileLocator;
+use Symfony\Component\Routing\Loader\YamlFileLoader;
+use Symfony\Component\Config\Resource\FileResource;
+
+class YamlFileLoaderTest extends TestCase
+{
+ public function testSupports()
+ {
+ $loader = new YamlFileLoader($this->getMockBuilder('Symfony\Component\Config\FileLocator')->getMock());
+
+ $this->assertTrue($loader->supports('foo.yml'), '->supports() returns true if the resource is loadable');
+ $this->assertTrue($loader->supports('foo.yaml'), '->supports() returns true if the resource is loadable');
+ $this->assertFalse($loader->supports('foo.foo'), '->supports() returns true if the resource is loadable');
+
+ $this->assertTrue($loader->supports('foo.yml', 'yaml'), '->supports() checks the resource type if specified');
+ $this->assertTrue($loader->supports('foo.yaml', 'yaml'), '->supports() checks the resource type if specified');
+ $this->assertFalse($loader->supports('foo.yml', 'foo'), '->supports() checks the resource type if specified');
+ }
+
+ public function testLoadDoesNothingIfEmpty()
+ {
+ $loader = new YamlFileLoader(new FileLocator(array(__DIR__.'/../Fixtures')));
+ $collection = $loader->load('empty.yml');
+
+ $this->assertEquals(array(), $collection->all());
+ $this->assertEquals(array(new FileResource(realpath(__DIR__.'/../Fixtures/empty.yml'))), $collection->getResources());
+ }
+
+ /**
+ * @expectedException \InvalidArgumentException
+ * @dataProvider getPathsToInvalidFiles
+ */
+ public function testLoadThrowsExceptionWithInvalidFile($filePath)
+ {
+ $loader = new YamlFileLoader(new FileLocator(array(__DIR__.'/../Fixtures')));
+ $loader->load($filePath);
+ }
+
+ public function getPathsToInvalidFiles()
+ {
+ return array(
+ array('nonvalid.yml'),
+ array('nonvalid2.yml'),
+ array('incomplete.yml'),
+ array('nonvalidkeys.yml'),
+ array('nonesense_resource_plus_path.yml'),
+ array('nonesense_type_without_resource.yml'),
+ array('bad_format.yml'),
+ );
+ }
+
+ public function testLoadSpecialRouteName()
+ {
+ $loader = new YamlFileLoader(new FileLocator(array(__DIR__.'/../Fixtures')));
+ $routeCollection = $loader->load('special_route_name.yml');
+ $route = $routeCollection->get('#$péß^a|');
+
+ $this->assertInstanceOf('Symfony\Component\Routing\Route', $route);
+ $this->assertSame('/true', $route->getPath());
+ }
+
+ public function testLoadWithRoute()
+ {
+ $loader = new YamlFileLoader(new FileLocator(array(__DIR__.'/../Fixtures')));
+ $routeCollection = $loader->load('validpattern.yml');
+ $route = $routeCollection->get('blog_show');
+
+ $this->assertInstanceOf('Symfony\Component\Routing\Route', $route);
+ $this->assertSame('/blog/{slug}', $route->getPath());
+ $this->assertSame('{locale}.example.com', $route->getHost());
+ $this->assertSame('MyBundle:Blog:show', $route->getDefault('_controller'));
+ $this->assertSame('\w+', $route->getRequirement('locale'));
+ $this->assertSame('RouteCompiler', $route->getOption('compiler_class'));
+ $this->assertEquals(array('GET', 'POST', 'PUT', 'OPTIONS'), $route->getMethods());
+ $this->assertEquals(array('https'), $route->getSchemes());
+ $this->assertEquals('context.getMethod() == "GET"', $route->getCondition());
+ }
+
+ public function testLoadWithResource()
+ {
+ $loader = new YamlFileLoader(new FileLocator(array(__DIR__.'/../Fixtures')));
+ $routeCollection = $loader->load('validresource.yml');
+ $routes = $routeCollection->all();
+
+ $this->assertCount(2, $routes, 'Two routes are loaded');
+ $this->assertContainsOnly('Symfony\Component\Routing\Route', $routes);
+
+ foreach ($routes as $route) {
+ $this->assertSame('/{foo}/blog/{slug}', $route->getPath());
+ $this->assertSame('123', $route->getDefault('foo'));
+ $this->assertSame('\d+', $route->getRequirement('foo'));
+ $this->assertSame('bar', $route->getOption('foo'));
+ $this->assertSame('', $route->getHost());
+ $this->assertSame('context.getMethod() == "POST"', $route->getCondition());
+ }
+ }
+
+ public function testLoadRouteWithControllerAttribute()
+ {
+ $loader = new YamlFileLoader(new FileLocator(array(__DIR__.'/../Fixtures/controller')));
+ $routeCollection = $loader->load('routing.yml');
+
+ $route = $routeCollection->get('app_homepage');
+
+ $this->assertSame('AppBundle:Homepage:show', $route->getDefault('_controller'));
+ }
+
+ public function testLoadRouteWithoutControllerAttribute()
+ {
+ $loader = new YamlFileLoader(new FileLocator(array(__DIR__.'/../Fixtures/controller')));
+ $routeCollection = $loader->load('routing.yml');
+
+ $route = $routeCollection->get('app_logout');
+
+ $this->assertNull($route->getDefault('_controller'));
+ }
+
+ public function testLoadRouteWithControllerSetInDefaults()
+ {
+ $loader = new YamlFileLoader(new FileLocator(array(__DIR__.'/../Fixtures/controller')));
+ $routeCollection = $loader->load('routing.yml');
+
+ $route = $routeCollection->get('app_blog');
+
+ $this->assertSame('AppBundle:Blog:list', $route->getDefault('_controller'));
+ }
+
+ /**
+ * @expectedException \InvalidArgumentException
+ * @expectedExceptionMessageRegExp /The routing file "[^"]*" must not specify both the "controller" key and the defaults key "_controller" for "app_blog"/
+ */
+ public function testOverrideControllerInDefaults()
+ {
+ $loader = new YamlFileLoader(new FileLocator(array(__DIR__.'/../Fixtures/controller')));
+ $loader->load('override_defaults.yml');
+ }
+
+ /**
+ * @dataProvider provideFilesImportingRoutesWithControllers
+ */
+ public function testImportRouteWithController($file)
+ {
+ $loader = new YamlFileLoader(new FileLocator(array(__DIR__.'/../Fixtures/controller')));
+ $routeCollection = $loader->load($file);
+
+ $route = $routeCollection->get('app_homepage');
+ $this->assertSame('FrameworkBundle:Template:template', $route->getDefault('_controller'));
+
+ $route = $routeCollection->get('app_blog');
+ $this->assertSame('FrameworkBundle:Template:template', $route->getDefault('_controller'));
+
+ $route = $routeCollection->get('app_logout');
+ $this->assertSame('FrameworkBundle:Template:template', $route->getDefault('_controller'));
+ }
+
+ public function provideFilesImportingRoutesWithControllers()
+ {
+ yield array('import_controller.yml');
+ yield array('import__controller.yml');
+ }
+
+ /**
+ * @expectedException \InvalidArgumentException
+ * @expectedExceptionMessageRegExp /The routing file "[^"]*" must not specify both the "controller" key and the defaults key "_controller" for "_static"/
+ */
+ public function testImportWithOverriddenController()
+ {
+ $loader = new YamlFileLoader(new FileLocator(array(__DIR__.'/../Fixtures/controller')));
+ $loader->load('import_override_defaults.yml');
+ }
+
+ public function testImportRouteWithGlobMatchingSingleFile()
+ {
+ $loader = new YamlFileLoader(new FileLocator(array(__DIR__.'/../Fixtures/glob')));
+ $routeCollection = $loader->load('import_single.yml');
+
+ $route = $routeCollection->get('bar_route');
+ $this->assertSame('AppBundle:Bar:view', $route->getDefault('_controller'));
+ }
+
+ public function testImportRouteWithGlobMatchingMultipleFiles()
+ {
+ $loader = new YamlFileLoader(new FileLocator(array(__DIR__.'/../Fixtures/glob')));
+ $routeCollection = $loader->load('import_multiple.yml');
+
+ $route = $routeCollection->get('bar_route');
+ $this->assertSame('AppBundle:Bar:view', $route->getDefault('_controller'));
+
+ $route = $routeCollection->get('baz_route');
+ $this->assertSame('AppBundle:Baz:view', $route->getDefault('_controller'));
+ }
+}
diff --git a/assets/php/vendor/symfony/routing/Tests/Matcher/DumpedRedirectableUrlMatcherTest.php b/assets/php/vendor/symfony/routing/Tests/Matcher/DumpedRedirectableUrlMatcherTest.php
new file mode 100644
index 0000000..cfbb524
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Tests/Matcher/DumpedRedirectableUrlMatcherTest.php
@@ -0,0 +1,43 @@
+<?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\Tests\Matcher;
+
+use Symfony\Component\Routing\Matcher\Dumper\PhpMatcherDumper;
+use Symfony\Component\Routing\Matcher\RedirectableUrlMatcherInterface;
+use Symfony\Component\Routing\Matcher\UrlMatcher;
+use Symfony\Component\Routing\RouteCollection;
+use Symfony\Component\Routing\RequestContext;
+
+class DumpedRedirectableUrlMatcherTest extends RedirectableUrlMatcherTest
+{
+ protected function getUrlMatcher(RouteCollection $routes, RequestContext $context = null)
+ {
+ static $i = 0;
+
+ $class = 'DumpedRedirectableUrlMatcher'.++$i;
+ $dumper = new PhpMatcherDumper($routes);
+ eval('?>'.$dumper->dump(array('class' => $class, 'base_class' => 'Symfony\Component\Routing\Tests\Matcher\TestDumpedRedirectableUrlMatcher')));
+
+ return $this->getMockBuilder($class)
+ ->setConstructorArgs(array($context ?: new RequestContext()))
+ ->setMethods(array('redirect'))
+ ->getMock();
+ }
+}
+
+class TestDumpedRedirectableUrlMatcher extends UrlMatcher implements RedirectableUrlMatcherInterface
+{
+ public function redirect($path, $route, $scheme = null)
+ {
+ return array();
+ }
+}
diff --git a/assets/php/vendor/symfony/routing/Tests/Matcher/DumpedUrlMatcherTest.php b/assets/php/vendor/symfony/routing/Tests/Matcher/DumpedUrlMatcherTest.php
new file mode 100644
index 0000000..880b2b1
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Tests/Matcher/DumpedUrlMatcherTest.php
@@ -0,0 +1,48 @@
+<?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\Tests\Matcher;
+
+use Symfony\Component\Routing\Matcher\Dumper\PhpMatcherDumper;
+use Symfony\Component\Routing\RouteCollection;
+use Symfony\Component\Routing\RequestContext;
+
+class DumpedUrlMatcherTest extends UrlMatcherTest
+{
+ /**
+ * @expectedException \LogicException
+ * @expectedExceptionMessage The "schemes" requirement is only supported for URL matchers that implement RedirectableUrlMatcherInterface.
+ */
+ public function testSchemeRequirement()
+ {
+ parent::testSchemeRequirement();
+ }
+
+ /**
+ * @expectedException \LogicException
+ * @expectedExceptionMessage The "schemes" requirement is only supported for URL matchers that implement RedirectableUrlMatcherInterface.
+ */
+ public function testSchemeAndMethodMismatch()
+ {
+ parent::testSchemeRequirement();
+ }
+
+ protected function getUrlMatcher(RouteCollection $routes, RequestContext $context = null)
+ {
+ static $i = 0;
+
+ $class = 'DumpedUrlMatcher'.++$i;
+ $dumper = new PhpMatcherDumper($routes);
+ eval('?>'.$dumper->dump(array('class' => $class)));
+
+ return new $class($context ?: new RequestContext());
+ }
+}
diff --git a/assets/php/vendor/symfony/routing/Tests/Matcher/Dumper/DumperCollectionTest.php b/assets/php/vendor/symfony/routing/Tests/Matcher/Dumper/DumperCollectionTest.php
new file mode 100644
index 0000000..823efdb
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Tests/Matcher/Dumper/DumperCollectionTest.php
@@ -0,0 +1,34 @@
+<?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\Tests\Matcher\Dumper;
+
+use PHPUnit\Framework\TestCase;
+use Symfony\Component\Routing\Matcher\Dumper\DumperCollection;
+
+class DumperCollectionTest extends TestCase
+{
+ public function testGetRoot()
+ {
+ $a = new DumperCollection();
+
+ $b = new DumperCollection();
+ $a->add($b);
+
+ $c = new DumperCollection();
+ $b->add($c);
+
+ $d = new DumperCollection();
+ $c->add($d);
+
+ $this->assertSame($a, $c->getRoot());
+ }
+}
diff --git a/assets/php/vendor/symfony/routing/Tests/Matcher/Dumper/PhpMatcherDumperTest.php b/assets/php/vendor/symfony/routing/Tests/Matcher/Dumper/PhpMatcherDumperTest.php
new file mode 100644
index 0000000..f29a6d6
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Tests/Matcher/Dumper/PhpMatcherDumperTest.php
@@ -0,0 +1,459 @@
+<?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\Tests\Matcher\Dumper;
+
+use PHPUnit\Framework\TestCase;
+use Symfony\Component\Routing\Matcher\Dumper\PhpMatcherDumper;
+use Symfony\Component\Routing\Matcher\RedirectableUrlMatcherInterface;
+use Symfony\Component\Routing\Matcher\UrlMatcher;
+use Symfony\Component\Routing\RequestContext;
+use Symfony\Component\Routing\Route;
+use Symfony\Component\Routing\RouteCollection;
+
+class PhpMatcherDumperTest extends TestCase
+{
+ /**
+ * @var string
+ */
+ private $matcherClass;
+
+ /**
+ * @var string
+ */
+ private $dumpPath;
+
+ protected function setUp()
+ {
+ parent::setUp();
+
+ $this->matcherClass = uniqid('ProjectUrlMatcher');
+ $this->dumpPath = sys_get_temp_dir().DIRECTORY_SEPARATOR.'php_matcher.'.$this->matcherClass.'.php';
+ }
+
+ protected function tearDown()
+ {
+ parent::tearDown();
+
+ @unlink($this->dumpPath);
+ }
+
+ /**
+ * @expectedException \LogicException
+ */
+ public function testDumpWhenSchemeIsUsedWithoutAProperDumper()
+ {
+ $collection = new RouteCollection();
+ $collection->add('secure', new Route(
+ '/secure',
+ array(),
+ array(),
+ array(),
+ '',
+ array('https')
+ ));
+ $dumper = new PhpMatcherDumper($collection);
+ $dumper->dump();
+ }
+
+ public function testRedirectPreservesUrlEncoding()
+ {
+ $collection = new RouteCollection();
+ $collection->add('foo', new Route('/foo:bar/'));
+
+ $class = $this->generateDumpedMatcher($collection, true);
+
+ $matcher = $this->getMockBuilder($class)
+ ->setMethods(array('redirect'))
+ ->setConstructorArgs(array(new RequestContext()))
+ ->getMock();
+
+ $matcher->expects($this->once())->method('redirect')->with('/foo%3Abar/', 'foo')->willReturn(array());
+
+ $matcher->match('/foo%3Abar');
+ }
+
+ /**
+ * @dataProvider getRouteCollections
+ */
+ public function testDump(RouteCollection $collection, $fixture, $options = array())
+ {
+ $basePath = __DIR__.'/../../Fixtures/dumper/';
+
+ $dumper = new PhpMatcherDumper($collection);
+ $this->assertStringEqualsFile($basePath.$fixture, $dumper->dump($options), '->dump() correctly dumps routes as optimized PHP code.');
+ }
+
+ public function getRouteCollections()
+ {
+ /* test case 1 */
+
+ $collection = new RouteCollection();
+
+ $collection->add('overridden', new Route('/overridden'));
+
+ // defaults and requirements
+ $collection->add('foo', new Route(
+ '/foo/{bar}',
+ array('def' => 'test'),
+ array('bar' => 'baz|symfony')
+ ));
+ // method requirement
+ $collection->add('bar', new Route(
+ '/bar/{foo}',
+ array(),
+ array(),
+ array(),
+ '',
+ array(),
+ array('GET', 'head')
+ ));
+ // GET method requirement automatically adds HEAD as valid
+ $collection->add('barhead', new Route(
+ '/barhead/{foo}',
+ array(),
+ array(),
+ array(),
+ '',
+ array(),
+ array('GET')
+ ));
+ // simple
+ $collection->add('baz', new Route(
+ '/test/baz'
+ ));
+ // simple with extension
+ $collection->add('baz2', new Route(
+ '/test/baz.html'
+ ));
+ // trailing slash
+ $collection->add('baz3', new Route(
+ '/test/baz3/'
+ ));
+ // trailing slash with variable
+ $collection->add('baz4', new Route(
+ '/test/{foo}/'
+ ));
+ // trailing slash and method
+ $collection->add('baz5', new Route(
+ '/test/{foo}/',
+ array(),
+ array(),
+ array(),
+ '',
+ array(),
+ array('post')
+ ));
+ // complex name
+ $collection->add('baz.baz6', new Route(
+ '/test/{foo}/',
+ array(),
+ array(),
+ array(),
+ '',
+ array(),
+ array('put')
+ ));
+ // defaults without variable
+ $collection->add('foofoo', new Route(
+ '/foofoo',
+ array('def' => 'test')
+ ));
+ // pattern with quotes
+ $collection->add('quoter', new Route(
+ '/{quoter}',
+ array(),
+ array('quoter' => '[\']+')
+ ));
+ // space in pattern
+ $collection->add('space', new Route(
+ '/spa ce'
+ ));
+
+ // prefixes
+ $collection1 = new RouteCollection();
+ $collection1->add('overridden', new Route('/overridden1'));
+ $collection1->add('foo1', new Route('/{foo}'));
+ $collection1->add('bar1', new Route('/{bar}'));
+ $collection1->addPrefix('/b\'b');
+ $collection2 = new RouteCollection();
+ $collection2->addCollection($collection1);
+ $collection2->add('overridden', new Route('/{var}', array(), array('var' => '.*')));
+ $collection1 = new RouteCollection();
+ $collection1->add('foo2', new Route('/{foo1}'));
+ $collection1->add('bar2', new Route('/{bar1}'));
+ $collection1->addPrefix('/b\'b');
+ $collection2->addCollection($collection1);
+ $collection2->addPrefix('/a');
+ $collection->addCollection($collection2);
+
+ // overridden through addCollection() and multiple sub-collections with no own prefix
+ $collection1 = new RouteCollection();
+ $collection1->add('overridden2', new Route('/old'));
+ $collection1->add('helloWorld', new Route('/hello/{who}', array('who' => 'World!')));
+ $collection2 = new RouteCollection();
+ $collection3 = new RouteCollection();
+ $collection3->add('overridden2', new Route('/new'));
+ $collection3->add('hey', new Route('/hey/'));
+ $collection2->addCollection($collection3);
+ $collection1->addCollection($collection2);
+ $collection1->addPrefix('/multi');
+ $collection->addCollection($collection1);
+
+ // "dynamic" prefix
+ $collection1 = new RouteCollection();
+ $collection1->add('foo3', new Route('/{foo}'));
+ $collection1->add('bar3', new Route('/{bar}'));
+ $collection1->addPrefix('/b');
+ $collection1->addPrefix('{_locale}');
+ $collection->addCollection($collection1);
+
+ // route between collections
+ $collection->add('ababa', new Route('/ababa'));
+
+ // collection with static prefix but only one route
+ $collection1 = new RouteCollection();
+ $collection1->add('foo4', new Route('/{foo}'));
+ $collection1->addPrefix('/aba');
+ $collection->addCollection($collection1);
+
+ // prefix and host
+
+ $collection1 = new RouteCollection();
+
+ $route1 = new Route('/route1', array(), array(), array(), 'a.example.com');
+ $collection1->add('route1', $route1);
+
+ $route2 = new Route('/c2/route2', array(), array(), array(), 'a.example.com');
+ $collection1->add('route2', $route2);
+
+ $route3 = new Route('/c2/route3', array(), array(), array(), 'b.example.com');
+ $collection1->add('route3', $route3);
+
+ $route4 = new Route('/route4', array(), array(), array(), 'a.example.com');
+ $collection1->add('route4', $route4);
+
+ $route5 = new Route('/route5', array(), array(), array(), 'c.example.com');
+ $collection1->add('route5', $route5);
+
+ $route6 = new Route('/route6', array(), array(), array(), null);
+ $collection1->add('route6', $route6);
+
+ $collection->addCollection($collection1);
+
+ // host and variables
+
+ $collection1 = new RouteCollection();
+
+ $route11 = new Route('/route11', array(), array(), array(), '{var1}.example.com');
+ $collection1->add('route11', $route11);
+
+ $route12 = new Route('/route12', array('var1' => 'val'), array(), array(), '{var1}.example.com');
+ $collection1->add('route12', $route12);
+
+ $route13 = new Route('/route13/{name}', array(), array(), array(), '{var1}.example.com');
+ $collection1->add('route13', $route13);
+
+ $route14 = new Route('/route14/{name}', array('var1' => 'val'), array(), array(), '{var1}.example.com');
+ $collection1->add('route14', $route14);
+
+ $route15 = new Route('/route15/{name}', array(), array(), array(), 'c.example.com');
+ $collection1->add('route15', $route15);
+
+ $route16 = new Route('/route16/{name}', array('var1' => 'val'), array(), array(), null);
+ $collection1->add('route16', $route16);
+
+ $route17 = new Route('/route17', array(), array(), array(), null);
+ $collection1->add('route17', $route17);
+
+ $collection->addCollection($collection1);
+
+ // multiple sub-collections with a single route and a prefix each
+ $collection1 = new RouteCollection();
+ $collection1->add('a', new Route('/a...'));
+ $collection2 = new RouteCollection();
+ $collection2->add('b', new Route('/{var}'));
+ $collection3 = new RouteCollection();
+ $collection3->add('c', new Route('/{var}'));
+ $collection3->addPrefix('/c');
+ $collection2->addCollection($collection3);
+ $collection2->addPrefix('/b');
+ $collection1->addCollection($collection2);
+ $collection1->addPrefix('/a');
+ $collection->addCollection($collection1);
+
+ /* test case 2 */
+
+ $redirectCollection = clone $collection;
+
+ // force HTTPS redirection
+ $redirectCollection->add('secure', new Route(
+ '/secure',
+ array(),
+ array(),
+ array(),
+ '',
+ array('https')
+ ));
+
+ // force HTTP redirection
+ $redirectCollection->add('nonsecure', new Route(
+ '/nonsecure',
+ array(),
+ array(),
+ array(),
+ '',
+ array('http')
+ ));
+
+ /* test case 3 */
+
+ $rootprefixCollection = new RouteCollection();
+ $rootprefixCollection->add('static', new Route('/test'));
+ $rootprefixCollection->add('dynamic', new Route('/{var}'));
+ $rootprefixCollection->addPrefix('rootprefix');
+ $route = new Route('/with-condition');
+ $route->setCondition('context.getMethod() == "GET"');
+ $rootprefixCollection->add('with-condition', $route);
+
+ /* test case 4 */
+ $headMatchCasesCollection = new RouteCollection();
+ $headMatchCasesCollection->add('just_head', new Route(
+ '/just_head',
+ array(),
+ array(),
+ array(),
+ '',
+ array(),
+ array('HEAD')
+ ));
+ $headMatchCasesCollection->add('head_and_get', new Route(
+ '/head_and_get',
+ array(),
+ array(),
+ array(),
+ '',
+ array(),
+ array('HEAD', 'GET')
+ ));
+ $headMatchCasesCollection->add('get_and_head', new Route(
+ '/get_and_head',
+ array(),
+ array(),
+ array(),
+ '',
+ array(),
+ array('GET', 'HEAD')
+ ));
+ $headMatchCasesCollection->add('post_and_head', new Route(
+ '/post_and_head',
+ array(),
+ array(),
+ array(),
+ '',
+ array(),
+ array('POST', 'HEAD')
+ ));
+ $headMatchCasesCollection->add('put_and_post', new Route(
+ '/put_and_post',
+ array(),
+ array(),
+ array(),
+ '',
+ array(),
+ array('PUT', 'POST')
+ ));
+ $headMatchCasesCollection->add('put_and_get_and_head', new Route(
+ '/put_and_post',
+ array(),
+ array(),
+ array(),
+ '',
+ array(),
+ array('PUT', 'GET', 'HEAD')
+ ));
+
+ /* test case 5 */
+ $groupOptimisedCollection = new RouteCollection();
+ $groupOptimisedCollection->add('a_first', new Route('/a/11'));
+ $groupOptimisedCollection->add('a_second', new Route('/a/22'));
+ $groupOptimisedCollection->add('a_third', new Route('/a/333'));
+ $groupOptimisedCollection->add('a_wildcard', new Route('/{param}'));
+ $groupOptimisedCollection->add('a_fourth', new Route('/a/44/'));
+ $groupOptimisedCollection->add('a_fifth', new Route('/a/55/'));
+ $groupOptimisedCollection->add('a_sixth', new Route('/a/66/'));
+ $groupOptimisedCollection->add('nested_wildcard', new Route('/nested/{param}'));
+ $groupOptimisedCollection->add('nested_a', new Route('/nested/group/a/'));
+ $groupOptimisedCollection->add('nested_b', new Route('/nested/group/b/'));
+ $groupOptimisedCollection->add('nested_c', new Route('/nested/group/c/'));
+
+ $groupOptimisedCollection->add('slashed_a', new Route('/slashed/group/'));
+ $groupOptimisedCollection->add('slashed_b', new Route('/slashed/group/b/'));
+ $groupOptimisedCollection->add('slashed_c', new Route('/slashed/group/c/'));
+
+ $trailingSlashCollection = new RouteCollection();
+ $trailingSlashCollection->add('simple_trailing_slash_no_methods', new Route('/trailing/simple/no-methods/', array(), array(), array(), '', array(), array()));
+ $trailingSlashCollection->add('simple_trailing_slash_GET_method', new Route('/trailing/simple/get-method/', array(), array(), array(), '', array(), array('GET')));
+ $trailingSlashCollection->add('simple_trailing_slash_HEAD_method', new Route('/trailing/simple/head-method/', array(), array(), array(), '', array(), array('HEAD')));
+ $trailingSlashCollection->add('simple_trailing_slash_POST_method', new Route('/trailing/simple/post-method/', array(), array(), array(), '', array(), array('POST')));
+ $trailingSlashCollection->add('regex_trailing_slash_no_methods', new Route('/trailing/regex/no-methods/{param}/', array(), array(), array(), '', array(), array()));
+ $trailingSlashCollection->add('regex_trailing_slash_GET_method', new Route('/trailing/regex/get-method/{param}/', array(), array(), array(), '', array(), array('GET')));
+ $trailingSlashCollection->add('regex_trailing_slash_HEAD_method', new Route('/trailing/regex/head-method/{param}/', array(), array(), array(), '', array(), array('HEAD')));
+ $trailingSlashCollection->add('regex_trailing_slash_POST_method', new Route('/trailing/regex/post-method/{param}/', array(), array(), array(), '', array(), array('POST')));
+
+ $trailingSlashCollection->add('simple_not_trailing_slash_no_methods', new Route('/not-trailing/simple/no-methods', array(), array(), array(), '', array(), array()));
+ $trailingSlashCollection->add('simple_not_trailing_slash_GET_method', new Route('/not-trailing/simple/get-method', array(), array(), array(), '', array(), array('GET')));
+ $trailingSlashCollection->add('simple_not_trailing_slash_HEAD_method', new Route('/not-trailing/simple/head-method', array(), array(), array(), '', array(), array('HEAD')));
+ $trailingSlashCollection->add('simple_not_trailing_slash_POST_method', new Route('/not-trailing/simple/post-method', array(), array(), array(), '', array(), array('POST')));
+ $trailingSlashCollection->add('regex_not_trailing_slash_no_methods', new Route('/not-trailing/regex/no-methods/{param}', array(), array(), array(), '', array(), array()));
+ $trailingSlashCollection->add('regex_not_trailing_slash_GET_method', new Route('/not-trailing/regex/get-method/{param}', array(), array(), array(), '', array(), array('GET')));
+ $trailingSlashCollection->add('regex_not_trailing_slash_HEAD_method', new Route('/not-trailing/regex/head-method/{param}', array(), array(), array(), '', array(), array('HEAD')));
+ $trailingSlashCollection->add('regex_not_trailing_slash_POST_method', new Route('/not-trailing/regex/post-method/{param}', array(), array(), array(), '', array(), array('POST')));
+
+ return array(
+ array(new RouteCollection(), 'url_matcher0.php', array()),
+ array($collection, 'url_matcher1.php', array()),
+ array($redirectCollection, 'url_matcher2.php', array('base_class' => 'Symfony\Component\Routing\Tests\Fixtures\RedirectableUrlMatcher')),
+ array($rootprefixCollection, 'url_matcher3.php', array()),
+ array($headMatchCasesCollection, 'url_matcher4.php', array()),
+ array($groupOptimisedCollection, 'url_matcher5.php', array('base_class' => 'Symfony\Component\Routing\Tests\Fixtures\RedirectableUrlMatcher')),
+ array($trailingSlashCollection, 'url_matcher6.php', array()),
+ array($trailingSlashCollection, 'url_matcher7.php', array('base_class' => 'Symfony\Component\Routing\Tests\Fixtures\RedirectableUrlMatcher')),
+ );
+ }
+
+ /**
+ * @param $dumper
+ */
+ private function generateDumpedMatcher(RouteCollection $collection, $redirectableStub = false)
+ {
+ $options = array('class' => $this->matcherClass);
+
+ if ($redirectableStub) {
+ $options['base_class'] = '\Symfony\Component\Routing\Tests\Matcher\Dumper\RedirectableUrlMatcherStub';
+ }
+
+ $dumper = new PhpMatcherDumper($collection);
+ $code = $dumper->dump($options);
+
+ file_put_contents($this->dumpPath, $code);
+ include $this->dumpPath;
+
+ return $this->matcherClass;
+ }
+}
+
+abstract class RedirectableUrlMatcherStub extends UrlMatcher implements RedirectableUrlMatcherInterface
+{
+ public function redirect($path, $route, $scheme = null)
+ {
+ }
+}
diff --git a/assets/php/vendor/symfony/routing/Tests/Matcher/Dumper/StaticPrefixCollectionTest.php b/assets/php/vendor/symfony/routing/Tests/Matcher/Dumper/StaticPrefixCollectionTest.php
new file mode 100644
index 0000000..37419e7
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Tests/Matcher/Dumper/StaticPrefixCollectionTest.php
@@ -0,0 +1,175 @@
+<?php
+
+namespace Symfony\Component\Routing\Tests\Matcher\Dumper;
+
+use PHPUnit\Framework\TestCase;
+use Symfony\Component\Routing\Matcher\Dumper\StaticPrefixCollection;
+use Symfony\Component\Routing\Route;
+
+class StaticPrefixCollectionTest extends TestCase
+{
+ /**
+ * @dataProvider routeProvider
+ */
+ public function testGrouping(array $routes, $expected)
+ {
+ $collection = new StaticPrefixCollection('/');
+
+ foreach ($routes as $route) {
+ list($path, $name) = $route;
+ $staticPrefix = (new Route($path))->compile()->getStaticPrefix();
+ $collection->addRoute($staticPrefix, $name);
+ }
+
+ $collection->optimizeGroups();
+ $dumped = $this->dumpCollection($collection);
+ $this->assertEquals($expected, $dumped);
+ }
+
+ public function routeProvider()
+ {
+ return array(
+ 'Simple - not nested' => array(
+ array(
+ array('/', 'root'),
+ array('/prefix/segment/', 'prefix_segment'),
+ array('/leading/segment/', 'leading_segment'),
+ ),
+ <<<EOF
+/ root
+/prefix/segment prefix_segment
+/leading/segment leading_segment
+EOF
+ ),
+ 'Not nested - group too small' => array(
+ array(
+ array('/', 'root'),
+ array('/prefix/segment/aa', 'prefix_segment'),
+ array('/prefix/segment/bb', 'leading_segment'),
+ ),
+ <<<EOF
+/ root
+/prefix/segment/aa prefix_segment
+/prefix/segment/bb leading_segment
+EOF
+ ),
+ 'Nested - contains item at intersection' => array(
+ array(
+ array('/', 'root'),
+ array('/prefix/segment/', 'prefix_segment'),
+ array('/prefix/segment/bb', 'leading_segment'),
+ ),
+ <<<EOF
+/ root
+/prefix/segment
+-> /prefix/segment prefix_segment
+-> /prefix/segment/bb leading_segment
+EOF
+ ),
+ 'Simple one level nesting' => array(
+ array(
+ array('/', 'root'),
+ array('/group/segment/', 'nested_segment'),
+ array('/group/thing/', 'some_segment'),
+ array('/group/other/', 'other_segment'),
+ ),
+ <<<EOF
+/ root
+/group
+-> /group/segment nested_segment
+-> /group/thing some_segment
+-> /group/other other_segment
+EOF
+ ),
+ 'Retain matching order with groups' => array(
+ array(
+ array('/group/aa/', 'aa'),
+ array('/group/bb/', 'bb'),
+ array('/group/cc/', 'cc'),
+ array('/', 'root'),
+ array('/group/dd/', 'dd'),
+ array('/group/ee/', 'ee'),
+ array('/group/ff/', 'ff'),
+ ),
+ <<<EOF
+/group
+-> /group/aa aa
+-> /group/bb bb
+-> /group/cc cc
+/ root
+/group
+-> /group/dd dd
+-> /group/ee ee
+-> /group/ff ff
+EOF
+ ),
+ 'Retain complex matching order with groups at base' => array(
+ array(
+ array('/aaa/111/', 'first_aaa'),
+ array('/prefixed/group/aa/', 'aa'),
+ array('/prefixed/group/bb/', 'bb'),
+ array('/prefixed/group/cc/', 'cc'),
+ array('/prefixed/', 'root'),
+ array('/prefixed/group/dd/', 'dd'),
+ array('/prefixed/group/ee/', 'ee'),
+ array('/prefixed/group/ff/', 'ff'),
+ array('/aaa/222/', 'second_aaa'),
+ array('/aaa/333/', 'third_aaa'),
+ ),
+ <<<EOF
+/aaa
+-> /aaa/111 first_aaa
+-> /aaa/222 second_aaa
+-> /aaa/333 third_aaa
+/prefixed
+-> /prefixed/group
+-> -> /prefixed/group/aa aa
+-> -> /prefixed/group/bb bb
+-> -> /prefixed/group/cc cc
+-> /prefixed root
+-> /prefixed/group
+-> -> /prefixed/group/dd dd
+-> -> /prefixed/group/ee ee
+-> -> /prefixed/group/ff ff
+EOF
+ ),
+
+ 'Group regardless of segments' => array(
+ array(
+ array('/aaa-111/', 'a1'),
+ array('/aaa-222/', 'a2'),
+ array('/aaa-333/', 'a3'),
+ array('/group-aa/', 'g1'),
+ array('/group-bb/', 'g2'),
+ array('/group-cc/', 'g3'),
+ ),
+ <<<EOF
+/aaa-
+-> /aaa-111 a1
+-> /aaa-222 a2
+-> /aaa-333 a3
+/group-
+-> /group-aa g1
+-> /group-bb g2
+-> /group-cc g3
+EOF
+ ),
+ );
+ }
+
+ private function dumpCollection(StaticPrefixCollection $collection, $prefix = '')
+ {
+ $lines = array();
+
+ foreach ($collection->getItems() as $item) {
+ if ($item instanceof StaticPrefixCollection) {
+ $lines[] = $prefix.$item->getPrefix();
+ $lines[] = $this->dumpCollection($item, $prefix.'-> ');
+ } else {
+ $lines[] = $prefix.implode(' ', $item);
+ }
+ }
+
+ return implode("\n", $lines);
+ }
+}
diff --git a/assets/php/vendor/symfony/routing/Tests/Matcher/RedirectableUrlMatcherTest.php b/assets/php/vendor/symfony/routing/Tests/Matcher/RedirectableUrlMatcherTest.php
new file mode 100644
index 0000000..7984391
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Tests/Matcher/RedirectableUrlMatcherTest.php
@@ -0,0 +1,124 @@
+<?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\Tests\Matcher;
+
+use Symfony\Component\Routing\Route;
+use Symfony\Component\Routing\RouteCollection;
+use Symfony\Component\Routing\RequestContext;
+
+class RedirectableUrlMatcherTest extends UrlMatcherTest
+{
+ public function testMissingTrailingSlash()
+ {
+ $coll = new RouteCollection();
+ $coll->add('foo', new Route('/foo/'));
+
+ $matcher = $this->getUrlMatcher($coll);
+ $matcher->expects($this->once())->method('redirect')->will($this->returnValue(array()));
+ $matcher->match('/foo');
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Routing\Exception\ResourceNotFoundException
+ */
+ public function testRedirectWhenNoSlashForNonSafeMethod()
+ {
+ $coll = new RouteCollection();
+ $coll->add('foo', new Route('/foo/'));
+
+ $context = new RequestContext();
+ $context->setMethod('POST');
+ $matcher = $this->getUrlMatcher($coll, $context);
+ $matcher->match('/foo');
+ }
+
+ public function testSchemeRedirectRedirectsToFirstScheme()
+ {
+ $coll = new RouteCollection();
+ $coll->add('foo', new Route('/foo', array(), array(), array(), '', array('FTP', 'HTTPS')));
+
+ $matcher = $this->getUrlMatcher($coll);
+ $matcher
+ ->expects($this->once())
+ ->method('redirect')
+ ->with('/foo', 'foo', 'ftp')
+ ->will($this->returnValue(array('_route' => 'foo')))
+ ;
+ $matcher->match('/foo');
+ }
+
+ public function testNoSchemaRedirectIfOneOfMultipleSchemesMatches()
+ {
+ $coll = new RouteCollection();
+ $coll->add('foo', new Route('/foo', array(), array(), array(), '', array('https', 'http')));
+
+ $matcher = $this->getUrlMatcher($coll);
+ $matcher
+ ->expects($this->never())
+ ->method('redirect');
+ $matcher->match('/foo');
+ }
+
+ public function testSchemeRedirectWithParams()
+ {
+ $coll = new RouteCollection();
+ $coll->add('foo', new Route('/foo/{bar}', array(), array(), array(), '', array('https')));
+
+ $matcher = $this->getUrlMatcher($coll);
+ $matcher
+ ->expects($this->once())
+ ->method('redirect')
+ ->with('/foo/baz', 'foo', 'https')
+ ->will($this->returnValue(array('redirect' => 'value')))
+ ;
+ $this->assertEquals(array('_route' => 'foo', 'bar' => 'baz', 'redirect' => 'value'), $matcher->match('/foo/baz'));
+ }
+
+ public function testSlashRedirectWithParams()
+ {
+ $coll = new RouteCollection();
+ $coll->add('foo', new Route('/foo/{bar}/'));
+
+ $matcher = $this->getUrlMatcher($coll);
+ $matcher
+ ->expects($this->once())
+ ->method('redirect')
+ ->with('/foo/baz/', 'foo', null)
+ ->will($this->returnValue(array('redirect' => 'value')))
+ ;
+ $this->assertEquals(array('_route' => 'foo', 'bar' => 'baz', 'redirect' => 'value'), $matcher->match('/foo/baz'));
+ }
+
+ public function testRedirectPreservesUrlEncoding()
+ {
+ $coll = new RouteCollection();
+ $coll->add('foo', new Route('/foo:bar/'));
+
+ $matcher = $this->getUrlMatcher($coll);
+ $matcher->expects($this->once())->method('redirect')->with('/foo%3Abar/')->willReturn(array());
+ $matcher->match('/foo%3Abar');
+ }
+
+ public function testSchemeRequirement()
+ {
+ $coll = new RouteCollection();
+ $coll->add('foo', new Route('/foo', array(), array(), array(), '', array('https')));
+ $matcher = $this->getUrlMatcher($coll, new RequestContext());
+ $matcher->expects($this->once())->method('redirect')->with('/foo', 'foo', 'https')->willReturn(array());
+ $this->assertSame(array('_route' => 'foo'), $matcher->match('/foo'));
+ }
+
+ protected function getUrlMatcher(RouteCollection $routes, RequestContext $context = null)
+ {
+ return $this->getMockForAbstractClass('Symfony\Component\Routing\Matcher\RedirectableUrlMatcher', array($routes, $context ?: new RequestContext()));
+ }
+}
diff --git a/assets/php/vendor/symfony/routing/Tests/Matcher/TraceableUrlMatcherTest.php b/assets/php/vendor/symfony/routing/Tests/Matcher/TraceableUrlMatcherTest.php
new file mode 100644
index 0000000..9f0529e
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Tests/Matcher/TraceableUrlMatcherTest.php
@@ -0,0 +1,122 @@
+<?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\Tests\Matcher;
+
+use PHPUnit\Framework\TestCase;
+use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\Routing\Route;
+use Symfony\Component\Routing\RouteCollection;
+use Symfony\Component\Routing\RequestContext;
+use Symfony\Component\Routing\Matcher\TraceableUrlMatcher;
+
+class TraceableUrlMatcherTest extends TestCase
+{
+ public function test()
+ {
+ $coll = new RouteCollection();
+ $coll->add('foo', new Route('/foo', array(), array(), array(), '', array(), array('POST')));
+ $coll->add('bar', new Route('/bar/{id}', array(), array('id' => '\d+')));
+ $coll->add('bar1', new Route('/bar/{name}', array(), array('id' => '\w+'), array(), '', array(), array('POST')));
+ $coll->add('bar2', new Route('/foo', array(), array(), array(), 'baz'));
+ $coll->add('bar3', new Route('/foo1', array(), array(), array(), 'baz'));
+ $coll->add('bar4', new Route('/foo2', array(), array(), array(), 'baz', array(), array(), 'context.getMethod() == "GET"'));
+
+ $context = new RequestContext();
+ $context->setHost('baz');
+
+ $matcher = new TraceableUrlMatcher($coll, $context);
+ $traces = $matcher->getTraces('/babar');
+ $this->assertSame(array(0, 0, 0, 0, 0, 0), $this->getLevels($traces));
+
+ $traces = $matcher->getTraces('/foo');
+ $this->assertSame(array(1, 0, 0, 2), $this->getLevels($traces));
+
+ $traces = $matcher->getTraces('/bar/12');
+ $this->assertSame(array(0, 2), $this->getLevels($traces));
+
+ $traces = $matcher->getTraces('/bar/dd');
+ $this->assertSame(array(0, 1, 1, 0, 0, 0), $this->getLevels($traces));
+
+ $traces = $matcher->getTraces('/foo1');
+ $this->assertSame(array(0, 0, 0, 0, 2), $this->getLevels($traces));
+
+ $context->setMethod('POST');
+ $traces = $matcher->getTraces('/foo');
+ $this->assertSame(array(2), $this->getLevels($traces));
+
+ $traces = $matcher->getTraces('/bar/dd');
+ $this->assertSame(array(0, 1, 2), $this->getLevels($traces));
+
+ $traces = $matcher->getTraces('/foo2');
+ $this->assertSame(array(0, 0, 0, 0, 0, 1), $this->getLevels($traces));
+ }
+
+ public function testMatchRouteOnMultipleHosts()
+ {
+ $routes = new RouteCollection();
+ $routes->add('first', new Route(
+ '/mypath/',
+ array('_controller' => 'MainBundle:Info:first'),
+ array(),
+ array(),
+ 'some.example.com'
+ ));
+
+ $routes->add('second', new Route(
+ '/mypath/',
+ array('_controller' => 'MainBundle:Info:second'),
+ array(),
+ array(),
+ 'another.example.com'
+ ));
+
+ $context = new RequestContext();
+ $context->setHost('baz');
+
+ $matcher = new TraceableUrlMatcher($routes, $context);
+
+ $traces = $matcher->getTraces('/mypath/');
+ $this->assertSame(
+ array(TraceableUrlMatcher::ROUTE_ALMOST_MATCHES, TraceableUrlMatcher::ROUTE_ALMOST_MATCHES),
+ $this->getLevels($traces)
+ );
+ }
+
+ public function getLevels($traces)
+ {
+ $levels = array();
+ foreach ($traces as $trace) {
+ $levels[] = $trace['level'];
+ }
+
+ return $levels;
+ }
+
+ public function testRoutesWithConditions()
+ {
+ $routes = new RouteCollection();
+ $routes->add('foo', new Route('/foo', array(), array(), array(), 'baz', array(), array(), "request.headers.get('User-Agent') matches '/firefox/i'"));
+
+ $context = new RequestContext();
+ $context->setHost('baz');
+
+ $matcher = new TraceableUrlMatcher($routes, $context);
+
+ $notMatchingRequest = Request::create('/foo', 'GET');
+ $traces = $matcher->getTracesForRequest($notMatchingRequest);
+ $this->assertEquals("Condition \"request.headers.get('User-Agent') matches '/firefox/i'\" does not evaluate to \"true\"", $traces[0]['log']);
+
+ $matchingRequest = Request::create('/foo', 'GET', array(), array(), array(), array('HTTP_USER_AGENT' => 'Firefox'));
+ $traces = $matcher->getTracesForRequest($matchingRequest);
+ $this->assertEquals('Route matches!', $traces[0]['log']);
+ }
+}
diff --git a/assets/php/vendor/symfony/routing/Tests/Matcher/UrlMatcherTest.php b/assets/php/vendor/symfony/routing/Tests/Matcher/UrlMatcherTest.php
new file mode 100644
index 0000000..e8d31e2
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Tests/Matcher/UrlMatcherTest.php
@@ -0,0 +1,509 @@
+<?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\Tests\Matcher;
+
+use PHPUnit\Framework\TestCase;
+use Symfony\Component\Routing\Exception\MethodNotAllowedException;
+use Symfony\Component\Routing\Exception\ResourceNotFoundException;
+use Symfony\Component\Routing\Matcher\UrlMatcher;
+use Symfony\Component\Routing\Route;
+use Symfony\Component\Routing\RouteCollection;
+use Symfony\Component\Routing\RequestContext;
+
+class UrlMatcherTest extends TestCase
+{
+ public function testNoMethodSoAllowed()
+ {
+ $coll = new RouteCollection();
+ $coll->add('foo', new Route('/foo'));
+
+ $matcher = $this->getUrlMatcher($coll);
+ $this->assertInternalType('array', $matcher->match('/foo'));
+ }
+
+ public function testMethodNotAllowed()
+ {
+ $coll = new RouteCollection();
+ $coll->add('foo', new Route('/foo', array(), array(), array(), '', array(), array('post')));
+
+ $matcher = $this->getUrlMatcher($coll);
+
+ try {
+ $matcher->match('/foo');
+ $this->fail();
+ } catch (MethodNotAllowedException $e) {
+ $this->assertEquals(array('POST'), $e->getAllowedMethods());
+ }
+ }
+
+ public function testMethodNotAllowedOnRoot()
+ {
+ $coll = new RouteCollection();
+ $coll->add('foo', new Route('/', array(), array(), array(), '', array(), array('GET')));
+
+ $matcher = $this->getUrlMatcher($coll, new RequestContext('', 'POST'));
+
+ try {
+ $matcher->match('/');
+ $this->fail();
+ } catch (MethodNotAllowedException $e) {
+ $this->assertEquals(array('GET'), $e->getAllowedMethods());
+ }
+ }
+
+ public function testHeadAllowedWhenRequirementContainsGet()
+ {
+ $coll = new RouteCollection();
+ $coll->add('foo', new Route('/foo', array(), array(), array(), '', array(), array('get')));
+
+ $matcher = $this->getUrlMatcher($coll, new RequestContext('', 'head'));
+ $this->assertInternalType('array', $matcher->match('/foo'));
+ }
+
+ public function testMethodNotAllowedAggregatesAllowedMethods()
+ {
+ $coll = new RouteCollection();
+ $coll->add('foo1', new Route('/foo', array(), array(), array(), '', array(), array('post')));
+ $coll->add('foo2', new Route('/foo', array(), array(), array(), '', array(), array('put', 'delete')));
+
+ $matcher = $this->getUrlMatcher($coll);
+
+ try {
+ $matcher->match('/foo');
+ $this->fail();
+ } catch (MethodNotAllowedException $e) {
+ $this->assertEquals(array('POST', 'PUT', 'DELETE'), $e->getAllowedMethods());
+ }
+ }
+
+ public function testMatch()
+ {
+ // test the patterns are matched and parameters are returned
+ $collection = new RouteCollection();
+ $collection->add('foo', new Route('/foo/{bar}'));
+ $matcher = $this->getUrlMatcher($collection);
+ try {
+ $matcher->match('/no-match');
+ $this->fail();
+ } catch (ResourceNotFoundException $e) {
+ }
+ $this->assertEquals(array('_route' => 'foo', 'bar' => 'baz'), $matcher->match('/foo/baz'));
+
+ // test that defaults are merged
+ $collection = new RouteCollection();
+ $collection->add('foo', new Route('/foo/{bar}', array('def' => 'test')));
+ $matcher = $this->getUrlMatcher($collection);
+ $this->assertEquals(array('_route' => 'foo', 'bar' => 'baz', 'def' => 'test'), $matcher->match('/foo/baz'));
+
+ // test that route "method" is ignored if no method is given in the context
+ $collection = new RouteCollection();
+ $collection->add('foo', new Route('/foo', array(), array(), array(), '', array(), array('get', 'head')));
+ $matcher = $this->getUrlMatcher($collection);
+ $this->assertInternalType('array', $matcher->match('/foo'));
+
+ // route does not match with POST method context
+ $matcher = $this->getUrlMatcher($collection, new RequestContext('', 'post'));
+ try {
+ $matcher->match('/foo');
+ $this->fail();
+ } catch (MethodNotAllowedException $e) {
+ }
+
+ // route does match with GET or HEAD method context
+ $matcher = $this->getUrlMatcher($collection);
+ $this->assertInternalType('array', $matcher->match('/foo'));
+ $matcher = $this->getUrlMatcher($collection, new RequestContext('', 'head'));
+ $this->assertInternalType('array', $matcher->match('/foo'));
+
+ // route with an optional variable as the first segment
+ $collection = new RouteCollection();
+ $collection->add('bar', new Route('/{bar}/foo', array('bar' => 'bar'), array('bar' => 'foo|bar')));
+ $matcher = $this->getUrlMatcher($collection);
+ $this->assertEquals(array('_route' => 'bar', 'bar' => 'bar'), $matcher->match('/bar/foo'));
+ $this->assertEquals(array('_route' => 'bar', 'bar' => 'foo'), $matcher->match('/foo/foo'));
+
+ $collection = new RouteCollection();
+ $collection->add('bar', new Route('/{bar}', array('bar' => 'bar'), array('bar' => 'foo|bar')));
+ $matcher = $this->getUrlMatcher($collection);
+ $this->assertEquals(array('_route' => 'bar', 'bar' => 'foo'), $matcher->match('/foo'));
+ $this->assertEquals(array('_route' => 'bar', 'bar' => 'bar'), $matcher->match('/'));
+
+ // route with only optional variables
+ $collection = new RouteCollection();
+ $collection->add('bar', new Route('/{foo}/{bar}', array('foo' => 'foo', 'bar' => 'bar'), array()));
+ $matcher = $this->getUrlMatcher($collection);
+ $this->assertEquals(array('_route' => 'bar', 'foo' => 'foo', 'bar' => 'bar'), $matcher->match('/'));
+ $this->assertEquals(array('_route' => 'bar', 'foo' => 'a', 'bar' => 'bar'), $matcher->match('/a'));
+ $this->assertEquals(array('_route' => 'bar', 'foo' => 'a', 'bar' => 'b'), $matcher->match('/a/b'));
+ }
+
+ public function testMatchWithPrefixes()
+ {
+ $collection = new RouteCollection();
+ $collection->add('foo', new Route('/{foo}'));
+ $collection->addPrefix('/b');
+ $collection->addPrefix('/a');
+
+ $matcher = $this->getUrlMatcher($collection);
+ $this->assertEquals(array('_route' => 'foo', 'foo' => 'foo'), $matcher->match('/a/b/foo'));
+ }
+
+ public function testMatchWithDynamicPrefix()
+ {
+ $collection = new RouteCollection();
+ $collection->add('foo', new Route('/{foo}'));
+ $collection->addPrefix('/b');
+ $collection->addPrefix('/{_locale}');
+
+ $matcher = $this->getUrlMatcher($collection);
+ $this->assertEquals(array('_locale' => 'fr', '_route' => 'foo', 'foo' => 'foo'), $matcher->match('/fr/b/foo'));
+ }
+
+ public function testMatchSpecialRouteName()
+ {
+ $collection = new RouteCollection();
+ $collection->add('$péß^a|', new Route('/bar'));
+
+ $matcher = $this->getUrlMatcher($collection);
+ $this->assertEquals(array('_route' => '$péß^a|'), $matcher->match('/bar'));
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Routing\Exception\ResourceNotFoundException
+ */
+ public function testTrailingEncodedNewlineIsNotOverlooked()
+ {
+ $collection = new RouteCollection();
+ $collection->add('foo', new Route('/foo'));
+
+ $matcher = $this->getUrlMatcher($collection);
+ $matcher->match('/foo%0a');
+ }
+
+ public function testMatchNonAlpha()
+ {
+ $collection = new RouteCollection();
+ $chars = '!"$%éà &\'()*+,./:;<=>@ABCDEFGHIJKLMNOPQRSTUVWXYZ\\[]^_`abcdefghijklmnopqrstuvwxyz{|}~-';
+ $collection->add('foo', new Route('/{foo}/bar', array(), array('foo' => '['.preg_quote($chars).']+'), array('utf8' => true)));
+
+ $matcher = $this->getUrlMatcher($collection);
+ $this->assertEquals(array('_route' => 'foo', 'foo' => $chars), $matcher->match('/'.rawurlencode($chars).'/bar'));
+ $this->assertEquals(array('_route' => 'foo', 'foo' => $chars), $matcher->match('/'.strtr($chars, array('%' => '%25')).'/bar'));
+ }
+
+ public function testMatchWithDotMetacharacterInRequirements()
+ {
+ $collection = new RouteCollection();
+ $collection->add('foo', new Route('/{foo}/bar', array(), array('foo' => '.+')));
+
+ $matcher = $this->getUrlMatcher($collection);
+ $this->assertEquals(array('_route' => 'foo', 'foo' => "\n"), $matcher->match('/'.urlencode("\n").'/bar'), 'linefeed character is matched');
+ }
+
+ public function testMatchOverriddenRoute()
+ {
+ $collection = new RouteCollection();
+ $collection->add('foo', new Route('/foo'));
+
+ $collection1 = new RouteCollection();
+ $collection1->add('foo', new Route('/foo1'));
+
+ $collection->addCollection($collection1);
+
+ $matcher = $this->getUrlMatcher($collection);
+
+ $this->assertEquals(array('_route' => 'foo'), $matcher->match('/foo1'));
+ $this->{method_exists($this, $_ = 'expectException') ? $_ : 'setExpectedException'}('Symfony\Component\Routing\Exception\ResourceNotFoundException');
+ $this->assertEquals(array(), $matcher->match('/foo'));
+ }
+
+ public function testMatchRegression()
+ {
+ $coll = new RouteCollection();
+ $coll->add('foo', new Route('/foo/{foo}'));
+ $coll->add('bar', new Route('/foo/bar/{foo}'));
+
+ $matcher = $this->getUrlMatcher($coll);
+ $this->assertEquals(array('foo' => 'bar', '_route' => 'bar'), $matcher->match('/foo/bar/bar'));
+
+ $collection = new RouteCollection();
+ $collection->add('foo', new Route('/{bar}'));
+ $matcher = $this->getUrlMatcher($collection);
+ try {
+ $matcher->match('/');
+ $this->fail();
+ } catch (ResourceNotFoundException $e) {
+ }
+ }
+
+ public function testDefaultRequirementForOptionalVariables()
+ {
+ $coll = new RouteCollection();
+ $coll->add('test', new Route('/{page}.{_format}', array('page' => 'index', '_format' => 'html')));
+
+ $matcher = $this->getUrlMatcher($coll);
+ $this->assertEquals(array('page' => 'my-page', '_format' => 'xml', '_route' => 'test'), $matcher->match('/my-page.xml'));
+ }
+
+ public function testMatchingIsEager()
+ {
+ $coll = new RouteCollection();
+ $coll->add('test', new Route('/{foo}-{bar}-', array(), array('foo' => '.+', 'bar' => '.+')));
+
+ $matcher = $this->getUrlMatcher($coll);
+ $this->assertEquals(array('foo' => 'text1-text2-text3', 'bar' => 'text4', '_route' => 'test'), $matcher->match('/text1-text2-text3-text4-'));
+ }
+
+ public function testAdjacentVariables()
+ {
+ $coll = new RouteCollection();
+ $coll->add('test', new Route('/{w}{x}{y}{z}.{_format}', array('z' => 'default-z', '_format' => 'html'), array('y' => 'y|Y')));
+
+ $matcher = $this->getUrlMatcher($coll);
+ // 'w' eagerly matches as much as possible and the other variables match the remaining chars.
+ // This also shows that the variables w-z must all exclude the separating char (the dot '.' in this case) by default requirement.
+ // Otherwise they would also consume '.xml' and _format would never match as it's an optional variable.
+ $this->assertEquals(array('w' => 'wwwww', 'x' => 'x', 'y' => 'Y', 'z' => 'Z', '_format' => 'xml', '_route' => 'test'), $matcher->match('/wwwwwxYZ.xml'));
+ // As 'y' has custom requirement and can only be of value 'y|Y', it will leave 'ZZZ' to variable z.
+ // So with carefully chosen requirements adjacent variables, can be useful.
+ $this->assertEquals(array('w' => 'wwwww', 'x' => 'x', 'y' => 'y', 'z' => 'ZZZ', '_format' => 'html', '_route' => 'test'), $matcher->match('/wwwwwxyZZZ'));
+ // z and _format are optional.
+ $this->assertEquals(array('w' => 'wwwww', 'x' => 'x', 'y' => 'y', 'z' => 'default-z', '_format' => 'html', '_route' => 'test'), $matcher->match('/wwwwwxy'));
+
+ $this->{method_exists($this, $_ = 'expectException') ? $_ : 'setExpectedException'}('Symfony\Component\Routing\Exception\ResourceNotFoundException');
+ $matcher->match('/wxy.html');
+ }
+
+ public function testOptionalVariableWithNoRealSeparator()
+ {
+ $coll = new RouteCollection();
+ $coll->add('test', new Route('/get{what}', array('what' => 'All')));
+ $matcher = $this->getUrlMatcher($coll);
+
+ $this->assertEquals(array('what' => 'All', '_route' => 'test'), $matcher->match('/get'));
+ $this->assertEquals(array('what' => 'Sites', '_route' => 'test'), $matcher->match('/getSites'));
+
+ // Usually the character in front of an optional parameter can be left out, e.g. with pattern '/get/{what}' just '/get' would match.
+ // But here the 't' in 'get' is not a separating character, so it makes no sense to match without it.
+ $this->{method_exists($this, $_ = 'expectException') ? $_ : 'setExpectedException'}('Symfony\Component\Routing\Exception\ResourceNotFoundException');
+ $matcher->match('/ge');
+ }
+
+ public function testRequiredVariableWithNoRealSeparator()
+ {
+ $coll = new RouteCollection();
+ $coll->add('test', new Route('/get{what}Suffix'));
+ $matcher = $this->getUrlMatcher($coll);
+
+ $this->assertEquals(array('what' => 'Sites', '_route' => 'test'), $matcher->match('/getSitesSuffix'));
+ }
+
+ public function testDefaultRequirementOfVariable()
+ {
+ $coll = new RouteCollection();
+ $coll->add('test', new Route('/{page}.{_format}'));
+ $matcher = $this->getUrlMatcher($coll);
+
+ $this->assertEquals(array('page' => 'index', '_format' => 'mobile.html', '_route' => 'test'), $matcher->match('/index.mobile.html'));
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Routing\Exception\ResourceNotFoundException
+ */
+ public function testDefaultRequirementOfVariableDisallowsSlash()
+ {
+ $coll = new RouteCollection();
+ $coll->add('test', new Route('/{page}.{_format}'));
+ $matcher = $this->getUrlMatcher($coll);
+
+ $matcher->match('/index.sl/ash');
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Routing\Exception\ResourceNotFoundException
+ */
+ public function testDefaultRequirementOfVariableDisallowsNextSeparator()
+ {
+ $coll = new RouteCollection();
+ $coll->add('test', new Route('/{page}.{_format}', array(), array('_format' => 'html|xml')));
+ $matcher = $this->getUrlMatcher($coll);
+
+ $matcher->match('/do.t.html');
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Routing\Exception\ResourceNotFoundException
+ */
+ public function testSchemeRequirement()
+ {
+ $coll = new RouteCollection();
+ $coll->add('foo', new Route('/foo', array(), array(), array(), '', array('https')));
+ $matcher = $this->getUrlMatcher($coll);
+ $matcher->match('/foo');
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Routing\Exception\ResourceNotFoundException
+ */
+ public function testCondition()
+ {
+ $coll = new RouteCollection();
+ $route = new Route('/foo');
+ $route->setCondition('context.getMethod() == "POST"');
+ $coll->add('foo', $route);
+ $matcher = $this->getUrlMatcher($coll);
+ $matcher->match('/foo');
+ }
+
+ public function testRequestCondition()
+ {
+ $coll = new RouteCollection();
+ $route = new Route('/foo/{bar}');
+ $route->setCondition('request.getBaseUrl() == "/sub/front.php" and request.getPathInfo() == "/foo/bar"');
+ $coll->add('foo', $route);
+ $matcher = $this->getUrlMatcher($coll, new RequestContext('/sub/front.php'));
+ $this->assertEquals(array('bar' => 'bar', '_route' => 'foo'), $matcher->match('/foo/bar'));
+ }
+
+ public function testDecodeOnce()
+ {
+ $coll = new RouteCollection();
+ $coll->add('foo', new Route('/foo/{foo}'));
+
+ $matcher = $this->getUrlMatcher($coll);
+ $this->assertEquals(array('foo' => 'bar%23', '_route' => 'foo'), $matcher->match('/foo/bar%2523'));
+ }
+
+ public function testCannotRelyOnPrefix()
+ {
+ $coll = new RouteCollection();
+
+ $subColl = new RouteCollection();
+ $subColl->add('bar', new Route('/bar'));
+ $subColl->addPrefix('/prefix');
+ // overwrite the pattern, so the prefix is not valid anymore for this route in the collection
+ $subColl->get('bar')->setPath('/new');
+
+ $coll->addCollection($subColl);
+
+ $matcher = $this->getUrlMatcher($coll);
+ $this->assertEquals(array('_route' => 'bar'), $matcher->match('/new'));
+ }
+
+ public function testWithHost()
+ {
+ $coll = new RouteCollection();
+ $coll->add('foo', new Route('/foo/{foo}', array(), array(), array(), '{locale}.example.com'));
+
+ $matcher = $this->getUrlMatcher($coll, new RequestContext('', 'GET', 'en.example.com'));
+ $this->assertEquals(array('foo' => 'bar', '_route' => 'foo', 'locale' => 'en'), $matcher->match('/foo/bar'));
+ }
+
+ public function testWithHostOnRouteCollection()
+ {
+ $coll = new RouteCollection();
+ $coll->add('foo', new Route('/foo/{foo}'));
+ $coll->add('bar', new Route('/bar/{foo}', array(), array(), array(), '{locale}.example.net'));
+ $coll->setHost('{locale}.example.com');
+
+ $matcher = $this->getUrlMatcher($coll, new RequestContext('', 'GET', 'en.example.com'));
+ $this->assertEquals(array('foo' => 'bar', '_route' => 'foo', 'locale' => 'en'), $matcher->match('/foo/bar'));
+
+ $matcher = $this->getUrlMatcher($coll, new RequestContext('', 'GET', 'en.example.com'));
+ $this->assertEquals(array('foo' => 'bar', '_route' => 'bar', 'locale' => 'en'), $matcher->match('/bar/bar'));
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Routing\Exception\ResourceNotFoundException
+ */
+ public function testWithOutHostHostDoesNotMatch()
+ {
+ $coll = new RouteCollection();
+ $coll->add('foo', new Route('/foo/{foo}', array(), array(), array(), '{locale}.example.com'));
+
+ $matcher = $this->getUrlMatcher($coll, new RequestContext('', 'GET', 'example.com'));
+ $matcher->match('/foo/bar');
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Routing\Exception\ResourceNotFoundException
+ */
+ public function testPathIsCaseSensitive()
+ {
+ $coll = new RouteCollection();
+ $coll->add('foo', new Route('/locale', array(), array('locale' => 'EN|FR|DE')));
+
+ $matcher = $this->getUrlMatcher($coll);
+ $matcher->match('/en');
+ }
+
+ public function testHostIsCaseInsensitive()
+ {
+ $coll = new RouteCollection();
+ $coll->add('foo', new Route('/', array(), array('locale' => 'EN|FR|DE'), array(), '{locale}.example.com'));
+
+ $matcher = $this->getUrlMatcher($coll, new RequestContext('', 'GET', 'en.example.com'));
+ $this->assertEquals(array('_route' => 'foo', 'locale' => 'en'), $matcher->match('/'));
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Routing\Exception\NoConfigurationException
+ */
+ public function testNoConfiguration()
+ {
+ $coll = new RouteCollection();
+
+ $matcher = $this->getUrlMatcher($coll);
+ $matcher->match('/');
+ }
+
+ public function testNestedCollections()
+ {
+ $coll = new RouteCollection();
+
+ $subColl = new RouteCollection();
+ $subColl->add('a', new Route('/a'));
+ $subColl->add('b', new Route('/b'));
+ $subColl->add('c', new Route('/c'));
+ $subColl->addPrefix('/p');
+ $coll->addCollection($subColl);
+
+ $coll->add('baz', new Route('/{baz}'));
+
+ $subColl = new RouteCollection();
+ $subColl->add('buz', new Route('/buz'));
+ $subColl->addPrefix('/prefix');
+ $coll->addCollection($subColl);
+
+ $matcher = $this->getUrlMatcher($coll);
+ $this->assertEquals(array('_route' => 'a'), $matcher->match('/p/a'));
+ $this->assertEquals(array('_route' => 'baz', 'baz' => 'p'), $matcher->match('/p'));
+ $this->assertEquals(array('_route' => 'buz'), $matcher->match('/prefix/buz'));
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Routing\Exception\ResourceNotFoundException
+ */
+ public function testSchemeAndMethodMismatch()
+ {
+ $coll = new RouteCollection();
+ $coll->add('foo', new Route('/', array(), array(), array(), null, array('https'), array('POST')));
+
+ $matcher = $this->getUrlMatcher($coll);
+ $matcher->match('/');
+ }
+
+ protected function getUrlMatcher(RouteCollection $routes, RequestContext $context = null)
+ {
+ return new UrlMatcher($routes, $context ?: new RequestContext());
+ }
+}
diff --git a/assets/php/vendor/symfony/routing/Tests/RequestContextTest.php b/assets/php/vendor/symfony/routing/Tests/RequestContextTest.php
new file mode 100644
index 0000000..ffe29d1
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Tests/RequestContextTest.php
@@ -0,0 +1,160 @@
+<?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\Tests;
+
+use PHPUnit\Framework\TestCase;
+use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\Routing\RequestContext;
+
+class RequestContextTest extends TestCase
+{
+ public function testConstruct()
+ {
+ $requestContext = new RequestContext(
+ 'foo',
+ 'post',
+ 'foo.bar',
+ 'HTTPS',
+ 8080,
+ 444,
+ '/baz',
+ 'bar=foobar'
+ );
+
+ $this->assertEquals('foo', $requestContext->getBaseUrl());
+ $this->assertEquals('POST', $requestContext->getMethod());
+ $this->assertEquals('foo.bar', $requestContext->getHost());
+ $this->assertEquals('https', $requestContext->getScheme());
+ $this->assertSame(8080, $requestContext->getHttpPort());
+ $this->assertSame(444, $requestContext->getHttpsPort());
+ $this->assertEquals('/baz', $requestContext->getPathInfo());
+ $this->assertEquals('bar=foobar', $requestContext->getQueryString());
+ }
+
+ public function testFromRequest()
+ {
+ $request = Request::create('https://test.com:444/foo?bar=baz');
+ $requestContext = new RequestContext();
+ $requestContext->setHttpPort(123);
+ $requestContext->fromRequest($request);
+
+ $this->assertEquals('', $requestContext->getBaseUrl());
+ $this->assertEquals('GET', $requestContext->getMethod());
+ $this->assertEquals('test.com', $requestContext->getHost());
+ $this->assertEquals('https', $requestContext->getScheme());
+ $this->assertEquals('/foo', $requestContext->getPathInfo());
+ $this->assertEquals('bar=baz', $requestContext->getQueryString());
+ $this->assertSame(123, $requestContext->getHttpPort());
+ $this->assertSame(444, $requestContext->getHttpsPort());
+
+ $request = Request::create('http://test.com:8080/foo?bar=baz');
+ $requestContext = new RequestContext();
+ $requestContext->setHttpsPort(567);
+ $requestContext->fromRequest($request);
+
+ $this->assertSame(8080, $requestContext->getHttpPort());
+ $this->assertSame(567, $requestContext->getHttpsPort());
+ }
+
+ public function testGetParameters()
+ {
+ $requestContext = new RequestContext();
+ $this->assertEquals(array(), $requestContext->getParameters());
+
+ $requestContext->setParameters(array('foo' => 'bar'));
+ $this->assertEquals(array('foo' => 'bar'), $requestContext->getParameters());
+ }
+
+ public function testHasParameter()
+ {
+ $requestContext = new RequestContext();
+ $requestContext->setParameters(array('foo' => 'bar'));
+
+ $this->assertTrue($requestContext->hasParameter('foo'));
+ $this->assertFalse($requestContext->hasParameter('baz'));
+ }
+
+ public function testGetParameter()
+ {
+ $requestContext = new RequestContext();
+ $requestContext->setParameters(array('foo' => 'bar'));
+
+ $this->assertEquals('bar', $requestContext->getParameter('foo'));
+ $this->assertNull($requestContext->getParameter('baz'));
+ }
+
+ public function testSetParameter()
+ {
+ $requestContext = new RequestContext();
+ $requestContext->setParameter('foo', 'bar');
+
+ $this->assertEquals('bar', $requestContext->getParameter('foo'));
+ }
+
+ public function testMethod()
+ {
+ $requestContext = new RequestContext();
+ $requestContext->setMethod('post');
+
+ $this->assertSame('POST', $requestContext->getMethod());
+ }
+
+ public function testScheme()
+ {
+ $requestContext = new RequestContext();
+ $requestContext->setScheme('HTTPS');
+
+ $this->assertSame('https', $requestContext->getScheme());
+ }
+
+ public function testHost()
+ {
+ $requestContext = new RequestContext();
+ $requestContext->setHost('eXampLe.com');
+
+ $this->assertSame('example.com', $requestContext->getHost());
+ }
+
+ public function testQueryString()
+ {
+ $requestContext = new RequestContext();
+ $requestContext->setQueryString(null);
+
+ $this->assertSame('', $requestContext->getQueryString());
+ }
+
+ public function testPort()
+ {
+ $requestContext = new RequestContext();
+ $requestContext->setHttpPort('123');
+ $requestContext->setHttpsPort('456');
+
+ $this->assertSame(123, $requestContext->getHttpPort());
+ $this->assertSame(456, $requestContext->getHttpsPort());
+ }
+
+ public function testFluentInterface()
+ {
+ $requestContext = new RequestContext();
+
+ $this->assertSame($requestContext, $requestContext->setBaseUrl('/app.php'));
+ $this->assertSame($requestContext, $requestContext->setPathInfo('/index'));
+ $this->assertSame($requestContext, $requestContext->setMethod('POST'));
+ $this->assertSame($requestContext, $requestContext->setScheme('https'));
+ $this->assertSame($requestContext, $requestContext->setHost('example.com'));
+ $this->assertSame($requestContext, $requestContext->setQueryString('foo=bar'));
+ $this->assertSame($requestContext, $requestContext->setHttpPort(80));
+ $this->assertSame($requestContext, $requestContext->setHttpsPort(443));
+ $this->assertSame($requestContext, $requestContext->setParameters(array()));
+ $this->assertSame($requestContext, $requestContext->setParameter('foo', 'bar'));
+ }
+}
diff --git a/assets/php/vendor/symfony/routing/Tests/RouteCollectionBuilderTest.php b/assets/php/vendor/symfony/routing/Tests/RouteCollectionBuilderTest.php
new file mode 100644
index 0000000..76a042d
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Tests/RouteCollectionBuilderTest.php
@@ -0,0 +1,364 @@
+<?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\Tests;
+
+use PHPUnit\Framework\TestCase;
+use Symfony\Component\Config\FileLocator;
+use Symfony\Component\Config\Resource\FileResource;
+use Symfony\Component\Routing\Loader\YamlFileLoader;
+use Symfony\Component\Routing\Route;
+use Symfony\Component\Routing\RouteCollection;
+use Symfony\Component\Routing\RouteCollectionBuilder;
+
+class RouteCollectionBuilderTest extends TestCase
+{
+ public function testImport()
+ {
+ $resolvedLoader = $this->getMockBuilder('Symfony\Component\Config\Loader\LoaderInterface')->getMock();
+ $resolver = $this->getMockBuilder('Symfony\Component\Config\Loader\LoaderResolverInterface')->getMock();
+ $resolver->expects($this->once())
+ ->method('resolve')
+ ->with('admin_routing.yml', 'yaml')
+ ->will($this->returnValue($resolvedLoader));
+
+ $originalRoute = new Route('/foo/path');
+ $expectedCollection = new RouteCollection();
+ $expectedCollection->add('one_test_route', $originalRoute);
+ $expectedCollection->addResource(new FileResource(__DIR__.'/Fixtures/file_resource.yml'));
+
+ $resolvedLoader
+ ->expects($this->once())
+ ->method('load')
+ ->with('admin_routing.yml', 'yaml')
+ ->will($this->returnValue($expectedCollection));
+
+ $loader = $this->getMockBuilder('Symfony\Component\Config\Loader\LoaderInterface')->getMock();
+ $loader->expects($this->any())
+ ->method('getResolver')
+ ->will($this->returnValue($resolver));
+
+ // import the file!
+ $routes = new RouteCollectionBuilder($loader);
+ $importedRoutes = $routes->import('admin_routing.yml', '/', 'yaml');
+
+ // we should get back a RouteCollectionBuilder
+ $this->assertInstanceOf('Symfony\Component\Routing\RouteCollectionBuilder', $importedRoutes);
+
+ // get the collection back so we can look at it
+ $addedCollection = $importedRoutes->build();
+ $route = $addedCollection->get('one_test_route');
+ $this->assertSame($originalRoute, $route);
+ // should return file_resource.yml, which is in the original collection
+ $this->assertCount(1, $addedCollection->getResources());
+
+ // make sure the routes were imported into the top-level builder
+ $routeCollection = $routes->build();
+ $this->assertCount(1, $routes->build());
+ $this->assertCount(1, $routeCollection->getResources());
+ }
+
+ public function testImportAddResources()
+ {
+ $routeCollectionBuilder = new RouteCollectionBuilder(new YamlFileLoader(new FileLocator(array(__DIR__.'/Fixtures/'))));
+ $routeCollectionBuilder->import('file_resource.yml');
+ $routeCollection = $routeCollectionBuilder->build();
+
+ $this->assertCount(1, $routeCollection->getResources());
+ }
+
+ /**
+ * @expectedException \BadMethodCallException
+ */
+ public function testImportWithoutLoaderThrowsException()
+ {
+ $collectionBuilder = new RouteCollectionBuilder();
+ $collectionBuilder->import('routing.yml');
+ }
+
+ public function testAdd()
+ {
+ $collectionBuilder = new RouteCollectionBuilder();
+
+ $addedRoute = $collectionBuilder->add('/checkout', 'AppBundle:Order:checkout');
+ $addedRoute2 = $collectionBuilder->add('/blogs', 'AppBundle:Blog:list', 'blog_list');
+ $this->assertInstanceOf('Symfony\Component\Routing\Route', $addedRoute);
+ $this->assertEquals('AppBundle:Order:checkout', $addedRoute->getDefault('_controller'));
+
+ $finalCollection = $collectionBuilder->build();
+ $this->assertSame($addedRoute2, $finalCollection->get('blog_list'));
+ }
+
+ public function testFlushOrdering()
+ {
+ $importedCollection = new RouteCollection();
+ $importedCollection->add('imported_route1', new Route('/imported/foo1'));
+ $importedCollection->add('imported_route2', new Route('/imported/foo2'));
+
+ $loader = $this->getMockBuilder('Symfony\Component\Config\Loader\LoaderInterface')->getMock();
+ // make this loader able to do the import - keeps mocking simple
+ $loader->expects($this->any())
+ ->method('supports')
+ ->will($this->returnValue(true));
+ $loader
+ ->expects($this->once())
+ ->method('load')
+ ->will($this->returnValue($importedCollection));
+
+ $routes = new RouteCollectionBuilder($loader);
+
+ // 1) Add a route
+ $routes->add('/checkout', 'AppBundle:Order:checkout', 'checkout_route');
+ // 2) Import from a file
+ $routes->mount('/', $routes->import('admin_routing.yml'));
+ // 3) Add another route
+ $routes->add('/', 'AppBundle:Default:homepage', 'homepage');
+ // 4) Add another route
+ $routes->add('/admin', 'AppBundle:Admin:dashboard', 'admin_dashboard');
+
+ // set a default value
+ $routes->setDefault('_locale', 'fr');
+
+ $actualCollection = $routes->build();
+
+ $this->assertCount(5, $actualCollection);
+ $actualRouteNames = array_keys($actualCollection->all());
+ $this->assertEquals(array(
+ 'checkout_route',
+ 'imported_route1',
+ 'imported_route2',
+ 'homepage',
+ 'admin_dashboard',
+ ), $actualRouteNames);
+
+ // make sure the defaults were set
+ $checkoutRoute = $actualCollection->get('checkout_route');
+ $defaults = $checkoutRoute->getDefaults();
+ $this->assertArrayHasKey('_locale', $defaults);
+ $this->assertEquals('fr', $defaults['_locale']);
+ }
+
+ public function testFlushSetsRouteNames()
+ {
+ $collectionBuilder = new RouteCollectionBuilder();
+
+ // add a "named" route
+ $collectionBuilder->add('/admin', 'AppBundle:Admin:dashboard', 'admin_dashboard');
+ // add an unnamed route
+ $collectionBuilder->add('/blogs', 'AppBundle:Blog:list')
+ ->setMethods(array('GET'));
+
+ // integer route names are allowed - they don't confuse things
+ $collectionBuilder->add('/products', 'AppBundle:Product:list', 100);
+
+ $actualCollection = $collectionBuilder->build();
+ $actualRouteNames = array_keys($actualCollection->all());
+ $this->assertEquals(array(
+ 'admin_dashboard',
+ 'GET_blogs',
+ '100',
+ ), $actualRouteNames);
+ }
+
+ public function testFlushSetsDetailsOnChildrenRoutes()
+ {
+ $routes = new RouteCollectionBuilder();
+
+ $routes->add('/blogs/{page}', 'listAction', 'blog_list')
+ // unique things for the route
+ ->setDefault('page', 1)
+ ->setRequirement('id', '\d+')
+ ->setOption('expose', true)
+ // things that the collection will try to override (but won't)
+ ->setDefault('_format', 'html')
+ ->setRequirement('_format', 'json|xml')
+ ->setOption('fooBar', true)
+ ->setHost('example.com')
+ ->setCondition('request.isSecure()')
+ ->setSchemes(array('https'))
+ ->setMethods(array('POST'));
+
+ // a simple route, nothing added to it
+ $routes->add('/blogs/{id}', 'editAction', 'blog_edit');
+
+ // configure the collection itself
+ $routes
+ // things that will not override the child route
+ ->setDefault('_format', 'json')
+ ->setRequirement('_format', 'xml')
+ ->setOption('fooBar', false)
+ ->setHost('symfony.com')
+ ->setCondition('request.query.get("page")==1')
+ // some unique things that should be set on the child
+ ->setDefault('_locale', 'fr')
+ ->setRequirement('_locale', 'fr|en')
+ ->setOption('niceRoute', true)
+ ->setSchemes(array('http'))
+ ->setMethods(array('GET', 'POST'));
+
+ $collection = $routes->build();
+ $actualListRoute = $collection->get('blog_list');
+
+ $this->assertEquals(1, $actualListRoute->getDefault('page'));
+ $this->assertEquals('\d+', $actualListRoute->getRequirement('id'));
+ $this->assertTrue($actualListRoute->getOption('expose'));
+ // none of these should be overridden
+ $this->assertEquals('html', $actualListRoute->getDefault('_format'));
+ $this->assertEquals('json|xml', $actualListRoute->getRequirement('_format'));
+ $this->assertTrue($actualListRoute->getOption('fooBar'));
+ $this->assertEquals('example.com', $actualListRoute->getHost());
+ $this->assertEquals('request.isSecure()', $actualListRoute->getCondition());
+ $this->assertEquals(array('https'), $actualListRoute->getSchemes());
+ $this->assertEquals(array('POST'), $actualListRoute->getMethods());
+ // inherited from the main collection
+ $this->assertEquals('fr', $actualListRoute->getDefault('_locale'));
+ $this->assertEquals('fr|en', $actualListRoute->getRequirement('_locale'));
+ $this->assertTrue($actualListRoute->getOption('niceRoute'));
+
+ $actualEditRoute = $collection->get('blog_edit');
+ // inherited from the collection
+ $this->assertEquals('symfony.com', $actualEditRoute->getHost());
+ $this->assertEquals('request.query.get("page")==1', $actualEditRoute->getCondition());
+ $this->assertEquals(array('http'), $actualEditRoute->getSchemes());
+ $this->assertEquals(array('GET', 'POST'), $actualEditRoute->getMethods());
+ }
+
+ /**
+ * @dataProvider providePrefixTests
+ */
+ public function testFlushPrefixesPaths($collectionPrefix, $routePath, $expectedPath)
+ {
+ $routes = new RouteCollectionBuilder();
+
+ $routes->add($routePath, 'someController', 'test_route');
+
+ $outerRoutes = new RouteCollectionBuilder();
+ $outerRoutes->mount($collectionPrefix, $routes);
+
+ $collection = $outerRoutes->build();
+
+ $this->assertEquals($expectedPath, $collection->get('test_route')->getPath());
+ }
+
+ public function providePrefixTests()
+ {
+ $tests = array();
+ // empty prefix is of course ok
+ $tests[] = array('', '/foo', '/foo');
+ // normal prefix - does not matter if it's a wildcard
+ $tests[] = array('/{admin}', '/foo', '/{admin}/foo');
+ // shows that a prefix will always be given the starting slash
+ $tests[] = array('0', '/foo', '/0/foo');
+
+ // spaces are ok, and double slahses at the end are cleaned
+ $tests[] = array('/ /', '/foo', '/ /foo');
+
+ return $tests;
+ }
+
+ public function testFlushSetsPrefixedWithMultipleLevels()
+ {
+ $loader = $this->getMockBuilder('Symfony\Component\Config\Loader\LoaderInterface')->getMock();
+ $routes = new RouteCollectionBuilder($loader);
+
+ $routes->add('homepage', 'MainController::homepageAction', 'homepage');
+
+ $adminRoutes = $routes->createBuilder();
+ $adminRoutes->add('/dashboard', 'AdminController::dashboardAction', 'admin_dashboard');
+
+ // embedded collection under /admin
+ $adminBlogRoutes = $routes->createBuilder();
+ $adminBlogRoutes->add('/new', 'BlogController::newAction', 'admin_blog_new');
+ // mount into admin, but before the parent collection has been mounted
+ $adminRoutes->mount('/blog', $adminBlogRoutes);
+
+ // now mount the /admin routes, above should all still be /blog/admin
+ $routes->mount('/admin', $adminRoutes);
+ // add a route after mounting
+ $adminRoutes->add('/users', 'AdminController::userAction', 'admin_users');
+
+ // add another sub-collection after the mount
+ $otherAdminRoutes = $routes->createBuilder();
+ $otherAdminRoutes->add('/sales', 'StatsController::indexAction', 'admin_stats_sales');
+ $adminRoutes->mount('/stats', $otherAdminRoutes);
+
+ // add a normal collection and see that it is also prefixed
+ $importedCollection = new RouteCollection();
+ $importedCollection->add('imported_route', new Route('/foo'));
+ // make this loader able to do the import - keeps mocking simple
+ $loader->expects($this->any())
+ ->method('supports')
+ ->will($this->returnValue(true));
+ $loader
+ ->expects($this->any())
+ ->method('load')
+ ->will($this->returnValue($importedCollection));
+ // import this from the /admin route builder
+ $adminRoutes->import('admin.yml', '/imported');
+
+ $collection = $routes->build();
+ $this->assertEquals('/admin/dashboard', $collection->get('admin_dashboard')->getPath(), 'Routes before mounting have the prefix');
+ $this->assertEquals('/admin/users', $collection->get('admin_users')->getPath(), 'Routes after mounting have the prefix');
+ $this->assertEquals('/admin/blog/new', $collection->get('admin_blog_new')->getPath(), 'Sub-collections receive prefix even if mounted before parent prefix');
+ $this->assertEquals('/admin/stats/sales', $collection->get('admin_stats_sales')->getPath(), 'Sub-collections receive prefix if mounted after parent prefix');
+ $this->assertEquals('/admin/imported/foo', $collection->get('imported_route')->getPath(), 'Normal RouteCollections are also prefixed properly');
+ }
+
+ public function testAutomaticRouteNamesDoNotConflict()
+ {
+ $routes = new RouteCollectionBuilder();
+
+ $adminRoutes = $routes->createBuilder();
+ // route 1
+ $adminRoutes->add('/dashboard', '');
+
+ $accountRoutes = $routes->createBuilder();
+ // route 2
+ $accountRoutes->add('/dashboard', '')
+ ->setMethods(array('GET'));
+ // route 3
+ $accountRoutes->add('/dashboard', '')
+ ->setMethods(array('POST'));
+
+ $routes->mount('/admin', $adminRoutes);
+ $routes->mount('/account', $accountRoutes);
+
+ $collection = $routes->build();
+ // there are 2 routes (i.e. with non-conflicting names)
+ $this->assertCount(3, $collection->all());
+ }
+
+ public function testAddsThePrefixOnlyOnceWhenLoadingMultipleCollections()
+ {
+ $firstCollection = new RouteCollection();
+ $firstCollection->add('a', new Route('/a'));
+
+ $secondCollection = new RouteCollection();
+ $secondCollection->add('b', new Route('/b'));
+
+ $loader = $this->getMockBuilder('Symfony\Component\Config\Loader\LoaderInterface')->getMock();
+ $loader->expects($this->any())
+ ->method('supports')
+ ->will($this->returnValue(true));
+ $loader
+ ->expects($this->any())
+ ->method('load')
+ ->will($this->returnValue(array($firstCollection, $secondCollection)));
+
+ $routeCollectionBuilder = new RouteCollectionBuilder($loader);
+ $routeCollectionBuilder->import('/directory/recurse/*', '/other/', 'glob');
+ $routes = $routeCollectionBuilder->build()->all();
+
+ $this->assertCount(2, $routes);
+ $this->assertEquals('/other/a', $routes['a']->getPath());
+ $this->assertEquals('/other/b', $routes['b']->getPath());
+ }
+}
diff --git a/assets/php/vendor/symfony/routing/Tests/RouteCollectionTest.php b/assets/php/vendor/symfony/routing/Tests/RouteCollectionTest.php
new file mode 100644
index 0000000..83457ff
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Tests/RouteCollectionTest.php
@@ -0,0 +1,305 @@
+<?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\Tests;
+
+use PHPUnit\Framework\TestCase;
+use Symfony\Component\Routing\RouteCollection;
+use Symfony\Component\Routing\Route;
+use Symfony\Component\Config\Resource\FileResource;
+
+class RouteCollectionTest extends TestCase
+{
+ public function testRoute()
+ {
+ $collection = new RouteCollection();
+ $route = new Route('/foo');
+ $collection->add('foo', $route);
+ $this->assertEquals(array('foo' => $route), $collection->all(), '->add() adds a route');
+ $this->assertEquals($route, $collection->get('foo'), '->get() returns a route by name');
+ $this->assertNull($collection->get('bar'), '->get() returns null if a route does not exist');
+ }
+
+ public function testOverriddenRoute()
+ {
+ $collection = new RouteCollection();
+ $collection->add('foo', new Route('/foo'));
+ $collection->add('foo', new Route('/foo1'));
+
+ $this->assertEquals('/foo1', $collection->get('foo')->getPath());
+ }
+
+ public function testDeepOverriddenRoute()
+ {
+ $collection = new RouteCollection();
+ $collection->add('foo', new Route('/foo'));
+
+ $collection1 = new RouteCollection();
+ $collection1->add('foo', new Route('/foo1'));
+
+ $collection2 = new RouteCollection();
+ $collection2->add('foo', new Route('/foo2'));
+
+ $collection1->addCollection($collection2);
+ $collection->addCollection($collection1);
+
+ $this->assertEquals('/foo2', $collection1->get('foo')->getPath());
+ $this->assertEquals('/foo2', $collection->get('foo')->getPath());
+ }
+
+ public function testIterator()
+ {
+ $collection = new RouteCollection();
+ $collection->add('foo', new Route('/foo'));
+
+ $collection1 = new RouteCollection();
+ $collection1->add('bar', $bar = new Route('/bar'));
+ $collection1->add('foo', $foo = new Route('/foo-new'));
+ $collection->addCollection($collection1);
+ $collection->add('last', $last = new Route('/last'));
+
+ $this->assertInstanceOf('\ArrayIterator', $collection->getIterator());
+ $this->assertSame(array('bar' => $bar, 'foo' => $foo, 'last' => $last), $collection->getIterator()->getArrayCopy());
+ }
+
+ public function testCount()
+ {
+ $collection = new RouteCollection();
+ $collection->add('foo', new Route('/foo'));
+
+ $collection1 = new RouteCollection();
+ $collection1->add('bar', new Route('/bar'));
+ $collection->addCollection($collection1);
+
+ $this->assertCount(2, $collection);
+ }
+
+ public function testAddCollection()
+ {
+ $collection = new RouteCollection();
+ $collection->add('foo', new Route('/foo'));
+
+ $collection1 = new RouteCollection();
+ $collection1->add('bar', $bar = new Route('/bar'));
+ $collection1->add('foo', $foo = new Route('/foo-new'));
+
+ $collection2 = new RouteCollection();
+ $collection2->add('grandchild', $grandchild = new Route('/grandchild'));
+
+ $collection1->addCollection($collection2);
+ $collection->addCollection($collection1);
+ $collection->add('last', $last = new Route('/last'));
+
+ $this->assertSame(array('bar' => $bar, 'foo' => $foo, 'grandchild' => $grandchild, 'last' => $last), $collection->all(),
+ '->addCollection() imports routes of another collection, overrides if necessary and adds them at the end');
+ }
+
+ public function testAddCollectionWithResources()
+ {
+ $collection = new RouteCollection();
+ $collection->addResource($foo = new FileResource(__DIR__.'/Fixtures/foo.xml'));
+ $collection1 = new RouteCollection();
+ $collection1->addResource($foo1 = new FileResource(__DIR__.'/Fixtures/foo1.xml'));
+ $collection->addCollection($collection1);
+ $this->assertEquals(array($foo, $foo1), $collection->getResources(), '->addCollection() merges resources');
+ }
+
+ public function testAddDefaultsAndRequirementsAndOptions()
+ {
+ $collection = new RouteCollection();
+ $collection->add('foo', new Route('/{placeholder}'));
+ $collection1 = new RouteCollection();
+ $collection1->add('bar', new Route('/{placeholder}',
+ array('_controller' => 'fixed', 'placeholder' => 'default'), array('placeholder' => '.+'), array('option' => 'value'))
+ );
+ $collection->addCollection($collection1);
+
+ $collection->addDefaults(array('placeholder' => 'new-default'));
+ $this->assertEquals(array('placeholder' => 'new-default'), $collection->get('foo')->getDefaults(), '->addDefaults() adds defaults to all routes');
+ $this->assertEquals(array('_controller' => 'fixed', 'placeholder' => 'new-default'), $collection->get('bar')->getDefaults(),
+ '->addDefaults() adds defaults to all routes and overwrites existing ones');
+
+ $collection->addRequirements(array('placeholder' => '\d+'));
+ $this->assertEquals(array('placeholder' => '\d+'), $collection->get('foo')->getRequirements(), '->addRequirements() adds requirements to all routes');
+ $this->assertEquals(array('placeholder' => '\d+'), $collection->get('bar')->getRequirements(),
+ '->addRequirements() adds requirements to all routes and overwrites existing ones');
+
+ $collection->addOptions(array('option' => 'new-value'));
+ $this->assertEquals(
+ array('option' => 'new-value', 'compiler_class' => 'Symfony\\Component\\Routing\\RouteCompiler'),
+ $collection->get('bar')->getOptions(), '->addOptions() adds options to all routes and overwrites existing ones'
+ );
+ }
+
+ public function testAddPrefix()
+ {
+ $collection = new RouteCollection();
+ $collection->add('foo', $foo = new Route('/foo'));
+ $collection2 = new RouteCollection();
+ $collection2->add('bar', $bar = new Route('/bar'));
+ $collection->addCollection($collection2);
+ $collection->addPrefix(' / ');
+ $this->assertSame('/foo', $collection->get('foo')->getPath(), '->addPrefix() trims the prefix and a single slash has no effect');
+ $collection->addPrefix('/{admin}', array('admin' => 'admin'), array('admin' => '\d+'));
+ $this->assertEquals('/{admin}/foo', $collection->get('foo')->getPath(), '->addPrefix() adds a prefix to all routes');
+ $this->assertEquals('/{admin}/bar', $collection->get('bar')->getPath(), '->addPrefix() adds a prefix to all routes');
+ $this->assertEquals(array('admin' => 'admin'), $collection->get('foo')->getDefaults(), '->addPrefix() adds defaults to all routes');
+ $this->assertEquals(array('admin' => 'admin'), $collection->get('bar')->getDefaults(), '->addPrefix() adds defaults to all routes');
+ $this->assertEquals(array('admin' => '\d+'), $collection->get('foo')->getRequirements(), '->addPrefix() adds requirements to all routes');
+ $this->assertEquals(array('admin' => '\d+'), $collection->get('bar')->getRequirements(), '->addPrefix() adds requirements to all routes');
+ $collection->addPrefix('0');
+ $this->assertEquals('/0/{admin}/foo', $collection->get('foo')->getPath(), '->addPrefix() ensures a prefix must start with a slash and must not end with a slash');
+ $collection->addPrefix('/ /');
+ $this->assertSame('/ /0/{admin}/foo', $collection->get('foo')->getPath(), '->addPrefix() can handle spaces if desired');
+ $this->assertSame('/ /0/{admin}/bar', $collection->get('bar')->getPath(), 'the route pattern of an added collection is in synch with the added prefix');
+ }
+
+ public function testAddPrefixOverridesDefaultsAndRequirements()
+ {
+ $collection = new RouteCollection();
+ $collection->add('foo', $foo = new Route('/foo.{_format}'));
+ $collection->add('bar', $bar = new Route('/bar.{_format}', array(), array('_format' => 'json')));
+ $collection->addPrefix('/admin', array(), array('_format' => 'html'));
+
+ $this->assertEquals('html', $collection->get('foo')->getRequirement('_format'), '->addPrefix() overrides existing requirements');
+ $this->assertEquals('html', $collection->get('bar')->getRequirement('_format'), '->addPrefix() overrides existing requirements');
+ }
+
+ public function testResource()
+ {
+ $collection = new RouteCollection();
+ $collection->addResource($foo = new FileResource(__DIR__.'/Fixtures/foo.xml'));
+ $collection->addResource($bar = new FileResource(__DIR__.'/Fixtures/bar.xml'));
+ $collection->addResource(new FileResource(__DIR__.'/Fixtures/foo.xml'));
+
+ $this->assertEquals(array($foo, $bar), $collection->getResources(),
+ '->addResource() adds a resource and getResources() only returns unique ones by comparing the string representation');
+ }
+
+ public function testUniqueRouteWithGivenName()
+ {
+ $collection1 = new RouteCollection();
+ $collection1->add('foo', new Route('/old'));
+ $collection2 = new RouteCollection();
+ $collection3 = new RouteCollection();
+ $collection3->add('foo', $new = new Route('/new'));
+
+ $collection2->addCollection($collection3);
+ $collection1->addCollection($collection2);
+
+ $this->assertSame($new, $collection1->get('foo'), '->get() returns new route that overrode previous one');
+ // size of 1 because collection1 contains /new but not /old anymore
+ $this->assertCount(1, $collection1->getIterator(), '->addCollection() removes previous routes when adding new routes with the same name');
+ }
+
+ public function testGet()
+ {
+ $collection1 = new RouteCollection();
+ $collection1->add('a', $a = new Route('/a'));
+ $collection2 = new RouteCollection();
+ $collection2->add('b', $b = new Route('/b'));
+ $collection1->addCollection($collection2);
+ $collection1->add('$péß^a|', $c = new Route('/special'));
+
+ $this->assertSame($b, $collection1->get('b'), '->get() returns correct route in child collection');
+ $this->assertSame($c, $collection1->get('$péß^a|'), '->get() can handle special characters');
+ $this->assertNull($collection2->get('a'), '->get() does not return the route defined in parent collection');
+ $this->assertNull($collection1->get('non-existent'), '->get() returns null when route does not exist');
+ $this->assertNull($collection1->get(0), '->get() does not disclose internal child RouteCollection');
+ }
+
+ public function testRemove()
+ {
+ $collection = new RouteCollection();
+ $collection->add('foo', $foo = new Route('/foo'));
+
+ $collection1 = new RouteCollection();
+ $collection1->add('bar', $bar = new Route('/bar'));
+ $collection->addCollection($collection1);
+ $collection->add('last', $last = new Route('/last'));
+
+ $collection->remove('foo');
+ $this->assertSame(array('bar' => $bar, 'last' => $last), $collection->all(), '->remove() can remove a single route');
+ $collection->remove(array('bar', 'last'));
+ $this->assertSame(array(), $collection->all(), '->remove() accepts an array and can remove multiple routes at once');
+ }
+
+ public function testSetHost()
+ {
+ $collection = new RouteCollection();
+ $routea = new Route('/a');
+ $routeb = new Route('/b', array(), array(), array(), '{locale}.example.net');
+ $collection->add('a', $routea);
+ $collection->add('b', $routeb);
+
+ $collection->setHost('{locale}.example.com');
+
+ $this->assertEquals('{locale}.example.com', $routea->getHost());
+ $this->assertEquals('{locale}.example.com', $routeb->getHost());
+ }
+
+ public function testSetCondition()
+ {
+ $collection = new RouteCollection();
+ $routea = new Route('/a');
+ $routeb = new Route('/b', array(), array(), array(), '{locale}.example.net', array(), array(), 'context.getMethod() == "GET"');
+ $collection->add('a', $routea);
+ $collection->add('b', $routeb);
+
+ $collection->setCondition('context.getMethod() == "POST"');
+
+ $this->assertEquals('context.getMethod() == "POST"', $routea->getCondition());
+ $this->assertEquals('context.getMethod() == "POST"', $routeb->getCondition());
+ }
+
+ public function testClone()
+ {
+ $collection = new RouteCollection();
+ $collection->add('a', new Route('/a'));
+ $collection->add('b', new Route('/b', array('placeholder' => 'default'), array('placeholder' => '.+')));
+
+ $clonedCollection = clone $collection;
+
+ $this->assertCount(2, $clonedCollection);
+ $this->assertEquals($collection->get('a'), $clonedCollection->get('a'));
+ $this->assertNotSame($collection->get('a'), $clonedCollection->get('a'));
+ $this->assertEquals($collection->get('b'), $clonedCollection->get('b'));
+ $this->assertNotSame($collection->get('b'), $clonedCollection->get('b'));
+ }
+
+ public function testSetSchemes()
+ {
+ $collection = new RouteCollection();
+ $routea = new Route('/a', array(), array(), array(), '', 'http');
+ $routeb = new Route('/b');
+ $collection->add('a', $routea);
+ $collection->add('b', $routeb);
+
+ $collection->setSchemes(array('http', 'https'));
+
+ $this->assertEquals(array('http', 'https'), $routea->getSchemes());
+ $this->assertEquals(array('http', 'https'), $routeb->getSchemes());
+ }
+
+ public function testSetMethods()
+ {
+ $collection = new RouteCollection();
+ $routea = new Route('/a', array(), array(), array(), '', array(), array('GET', 'POST'));
+ $routeb = new Route('/b');
+ $collection->add('a', $routea);
+ $collection->add('b', $routeb);
+
+ $collection->setMethods('PUT');
+
+ $this->assertEquals(array('PUT'), $routea->getMethods());
+ $this->assertEquals(array('PUT'), $routeb->getMethods());
+ }
+}
diff --git a/assets/php/vendor/symfony/routing/Tests/RouteCompilerTest.php b/assets/php/vendor/symfony/routing/Tests/RouteCompilerTest.php
new file mode 100644
index 0000000..dc304e3
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Tests/RouteCompilerTest.php
@@ -0,0 +1,389 @@
+<?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\Tests;
+
+use PHPUnit\Framework\TestCase;
+use Symfony\Component\Routing\Route;
+use Symfony\Component\Routing\RouteCompiler;
+
+class RouteCompilerTest extends TestCase
+{
+ /**
+ * @dataProvider provideCompileData
+ */
+ public function testCompile($name, $arguments, $prefix, $regex, $variables, $tokens)
+ {
+ $r = new \ReflectionClass('Symfony\\Component\\Routing\\Route');
+ $route = $r->newInstanceArgs($arguments);
+
+ $compiled = $route->compile();
+ $this->assertEquals($prefix, $compiled->getStaticPrefix(), $name.' (static prefix)');
+ $this->assertEquals($regex, $compiled->getRegex(), $name.' (regex)');
+ $this->assertEquals($variables, $compiled->getVariables(), $name.' (variables)');
+ $this->assertEquals($tokens, $compiled->getTokens(), $name.' (tokens)');
+ }
+
+ public function provideCompileData()
+ {
+ return array(
+ array(
+ 'Static route',
+ array('/foo'),
+ '/foo', '#^/foo$#sD', array(), array(
+ array('text', '/foo'),
+ ),
+ ),
+
+ array(
+ 'Route with a variable',
+ array('/foo/{bar}'),
+ '/foo', '#^/foo/(?P<bar>[^/]++)$#sD', array('bar'), array(
+ array('variable', '/', '[^/]++', 'bar'),
+ array('text', '/foo'),
+ ),
+ ),
+
+ array(
+ 'Route with a variable that has a default value',
+ array('/foo/{bar}', array('bar' => 'bar')),
+ '/foo', '#^/foo(?:/(?P<bar>[^/]++))?$#sD', array('bar'), array(
+ array('variable', '/', '[^/]++', 'bar'),
+ array('text', '/foo'),
+ ),
+ ),
+
+ array(
+ 'Route with several variables',
+ array('/foo/{bar}/{foobar}'),
+ '/foo', '#^/foo/(?P<bar>[^/]++)/(?P<foobar>[^/]++)$#sD', array('bar', 'foobar'), array(
+ array('variable', '/', '[^/]++', 'foobar'),
+ array('variable', '/', '[^/]++', 'bar'),
+ array('text', '/foo'),
+ ),
+ ),
+
+ array(
+ 'Route with several variables that have default values',
+ array('/foo/{bar}/{foobar}', array('bar' => 'bar', 'foobar' => '')),
+ '/foo', '#^/foo(?:/(?P<bar>[^/]++)(?:/(?P<foobar>[^/]++))?)?$#sD', array('bar', 'foobar'), array(
+ array('variable', '/', '[^/]++', 'foobar'),
+ array('variable', '/', '[^/]++', 'bar'),
+ array('text', '/foo'),
+ ),
+ ),
+
+ array(
+ 'Route with several variables but some of them have no default values',
+ array('/foo/{bar}/{foobar}', array('bar' => 'bar')),
+ '/foo', '#^/foo/(?P<bar>[^/]++)/(?P<foobar>[^/]++)$#sD', array('bar', 'foobar'), array(
+ array('variable', '/', '[^/]++', 'foobar'),
+ array('variable', '/', '[^/]++', 'bar'),
+ array('text', '/foo'),
+ ),
+ ),
+
+ array(
+ 'Route with an optional variable as the first segment',
+ array('/{bar}', array('bar' => 'bar')),
+ '', '#^/(?P<bar>[^/]++)?$#sD', array('bar'), array(
+ array('variable', '/', '[^/]++', 'bar'),
+ ),
+ ),
+
+ array(
+ 'Route with a requirement of 0',
+ array('/{bar}', array('bar' => null), array('bar' => '0')),
+ '', '#^/(?P<bar>0)?$#sD', array('bar'), array(
+ array('variable', '/', '0', 'bar'),
+ ),
+ ),
+
+ array(
+ 'Route with an optional variable as the first segment with requirements',
+ array('/{bar}', array('bar' => 'bar'), array('bar' => '(foo|bar)')),
+ '', '#^/(?P<bar>(foo|bar))?$#sD', array('bar'), array(
+ array('variable', '/', '(foo|bar)', 'bar'),
+ ),
+ ),
+
+ array(
+ 'Route with only optional variables',
+ array('/{foo}/{bar}', array('foo' => 'foo', 'bar' => 'bar')),
+ '', '#^/(?P<foo>[^/]++)?(?:/(?P<bar>[^/]++))?$#sD', array('foo', 'bar'), array(
+ array('variable', '/', '[^/]++', 'bar'),
+ array('variable', '/', '[^/]++', 'foo'),
+ ),
+ ),
+
+ array(
+ 'Route with a variable in last position',
+ array('/foo-{bar}'),
+ '/foo-', '#^/foo\-(?P<bar>[^/]++)$#sD', array('bar'), array(
+ array('variable', '-', '[^/]++', 'bar'),
+ array('text', '/foo'),
+ ),
+ ),
+
+ array(
+ 'Route with nested placeholders',
+ array('/{static{var}static}'),
+ '/{static', '#^/\{static(?P<var>[^/]+)static\}$#sD', array('var'), array(
+ array('text', 'static}'),
+ array('variable', '', '[^/]+', 'var'),
+ array('text', '/{static'),
+ ),
+ ),
+
+ array(
+ 'Route without separator between variables',
+ array('/{w}{x}{y}{z}.{_format}', array('z' => 'default-z', '_format' => 'html'), array('y' => '(y|Y)')),
+ '', '#^/(?P<w>[^/\.]+)(?P<x>[^/\.]+)(?P<y>(y|Y))(?:(?P<z>[^/\.]++)(?:\.(?P<_format>[^/]++))?)?$#sD', array('w', 'x', 'y', 'z', '_format'), array(
+ array('variable', '.', '[^/]++', '_format'),
+ array('variable', '', '[^/\.]++', 'z'),
+ array('variable', '', '(y|Y)', 'y'),
+ array('variable', '', '[^/\.]+', 'x'),
+ array('variable', '/', '[^/\.]+', 'w'),
+ ),
+ ),
+
+ array(
+ 'Route with a format',
+ array('/foo/{bar}.{_format}'),
+ '/foo', '#^/foo/(?P<bar>[^/\.]++)\.(?P<_format>[^/]++)$#sD', array('bar', '_format'), array(
+ array('variable', '.', '[^/]++', '_format'),
+ array('variable', '/', '[^/\.]++', 'bar'),
+ array('text', '/foo'),
+ ),
+ ),
+
+ array(
+ 'Static non UTF-8 route',
+ array("/fo\xE9"),
+ "/fo\xE9", "#^/fo\xE9$#sD", array(), array(
+ array('text', "/fo\xE9"),
+ ),
+ ),
+
+ array(
+ 'Route with an explicit UTF-8 requirement',
+ array('/{bar}', array('bar' => null), array('bar' => '.'), array('utf8' => true)),
+ '', '#^/(?P<bar>.)?$#sDu', array('bar'), array(
+ array('variable', '/', '.', 'bar', true),
+ ),
+ ),
+ );
+ }
+
+ /**
+ * @group legacy
+ * @dataProvider provideCompileImplicitUtf8Data
+ * @expectedDeprecation Using UTF-8 route %s without setting the "utf8" option is deprecated %s.
+ */
+ public function testCompileImplicitUtf8Data($name, $arguments, $prefix, $regex, $variables, $tokens, $deprecationType)
+ {
+ $r = new \ReflectionClass('Symfony\\Component\\Routing\\Route');
+ $route = $r->newInstanceArgs($arguments);
+
+ $compiled = $route->compile();
+ $this->assertEquals($prefix, $compiled->getStaticPrefix(), $name.' (static prefix)');
+ $this->assertEquals($regex, $compiled->getRegex(), $name.' (regex)');
+ $this->assertEquals($variables, $compiled->getVariables(), $name.' (variables)');
+ $this->assertEquals($tokens, $compiled->getTokens(), $name.' (tokens)');
+ }
+
+ public function provideCompileImplicitUtf8Data()
+ {
+ return array(
+ array(
+ 'Static UTF-8 route',
+ array('/foé'),
+ '/foé', '#^/foé$#sDu', array(), array(
+ array('text', '/foé'),
+ ),
+ 'patterns',
+ ),
+
+ array(
+ 'Route with an implicit UTF-8 requirement',
+ array('/{bar}', array('bar' => null), array('bar' => 'é')),
+ '', '#^/(?P<bar>é)?$#sDu', array('bar'), array(
+ array('variable', '/', 'é', 'bar', true),
+ ),
+ 'requirements',
+ ),
+
+ array(
+ 'Route with a UTF-8 class requirement',
+ array('/{bar}', array('bar' => null), array('bar' => '\pM')),
+ '', '#^/(?P<bar>\pM)?$#sDu', array('bar'), array(
+ array('variable', '/', '\pM', 'bar', true),
+ ),
+ 'requirements',
+ ),
+
+ array(
+ 'Route with a UTF-8 separator',
+ array('/foo/{bar}§{_format}', array(), array(), array('compiler_class' => Utf8RouteCompiler::class)),
+ '/foo', '#^/foo/(?P<bar>[^/§]++)§(?P<_format>[^/]++)$#sDu', array('bar', '_format'), array(
+ array('variable', '§', '[^/]++', '_format', true),
+ array('variable', '/', '[^/§]++', 'bar', true),
+ array('text', '/foo'),
+ ),
+ 'patterns',
+ ),
+ );
+ }
+
+ /**
+ * @expectedException \LogicException
+ */
+ public function testRouteWithSameVariableTwice()
+ {
+ $route = new Route('/{name}/{name}');
+
+ $compiled = $route->compile();
+ }
+
+ /**
+ * @expectedException \LogicException
+ */
+ public function testRouteCharsetMismatch()
+ {
+ $route = new Route("/\xE9/{bar}", array(), array('bar' => '.'), array('utf8' => true));
+
+ $compiled = $route->compile();
+ }
+
+ /**
+ * @expectedException \LogicException
+ */
+ public function testRequirementCharsetMismatch()
+ {
+ $route = new Route('/foo/{bar}', array(), array('bar' => "\xE9"), array('utf8' => true));
+
+ $compiled = $route->compile();
+ }
+
+ /**
+ * @expectedException \InvalidArgumentException
+ */
+ public function testRouteWithFragmentAsPathParameter()
+ {
+ $route = new Route('/{_fragment}');
+
+ $compiled = $route->compile();
+ }
+
+ /**
+ * @dataProvider getVariableNamesStartingWithADigit
+ * @expectedException \DomainException
+ */
+ public function testRouteWithVariableNameStartingWithADigit($name)
+ {
+ $route = new Route('/{'.$name.'}');
+ $route->compile();
+ }
+
+ public function getVariableNamesStartingWithADigit()
+ {
+ return array(
+ array('09'),
+ array('123'),
+ array('1e2'),
+ );
+ }
+
+ /**
+ * @dataProvider provideCompileWithHostData
+ */
+ public function testCompileWithHost($name, $arguments, $prefix, $regex, $variables, $pathVariables, $tokens, $hostRegex, $hostVariables, $hostTokens)
+ {
+ $r = new \ReflectionClass('Symfony\\Component\\Routing\\Route');
+ $route = $r->newInstanceArgs($arguments);
+
+ $compiled = $route->compile();
+ $this->assertEquals($prefix, $compiled->getStaticPrefix(), $name.' (static prefix)');
+ $this->assertEquals($regex, str_replace(array("\n", ' '), '', $compiled->getRegex()), $name.' (regex)');
+ $this->assertEquals($variables, $compiled->getVariables(), $name.' (variables)');
+ $this->assertEquals($pathVariables, $compiled->getPathVariables(), $name.' (path variables)');
+ $this->assertEquals($tokens, $compiled->getTokens(), $name.' (tokens)');
+ $this->assertEquals($hostRegex, str_replace(array("\n", ' '), '', $compiled->getHostRegex()), $name.' (host regex)');
+ $this->assertEquals($hostVariables, $compiled->getHostVariables(), $name.' (host variables)');
+ $this->assertEquals($hostTokens, $compiled->getHostTokens(), $name.' (host tokens)');
+ }
+
+ public function provideCompileWithHostData()
+ {
+ return array(
+ array(
+ 'Route with host pattern',
+ array('/hello', array(), array(), array(), 'www.example.com'),
+ '/hello', '#^/hello$#sD', array(), array(), array(
+ array('text', '/hello'),
+ ),
+ '#^www\.example\.com$#sDi', array(), array(
+ array('text', 'www.example.com'),
+ ),
+ ),
+ array(
+ 'Route with host pattern and some variables',
+ array('/hello/{name}', array(), array(), array(), 'www.example.{tld}'),
+ '/hello', '#^/hello/(?P<name>[^/]++)$#sD', array('tld', 'name'), array('name'), array(
+ array('variable', '/', '[^/]++', 'name'),
+ array('text', '/hello'),
+ ),
+ '#^www\.example\.(?P<tld>[^\.]++)$#sDi', array('tld'), array(
+ array('variable', '.', '[^\.]++', 'tld'),
+ array('text', 'www.example'),
+ ),
+ ),
+ array(
+ 'Route with variable at beginning of host',
+ array('/hello', array(), array(), array(), '{locale}.example.{tld}'),
+ '/hello', '#^/hello$#sD', array('locale', 'tld'), array(), array(
+ array('text', '/hello'),
+ ),
+ '#^(?P<locale>[^\.]++)\.example\.(?P<tld>[^\.]++)$#sDi', array('locale', 'tld'), array(
+ array('variable', '.', '[^\.]++', 'tld'),
+ array('text', '.example'),
+ array('variable', '', '[^\.]++', 'locale'),
+ ),
+ ),
+ array(
+ 'Route with host variables that has a default value',
+ array('/hello', array('locale' => 'a', 'tld' => 'b'), array(), array(), '{locale}.example.{tld}'),
+ '/hello', '#^/hello$#sD', array('locale', 'tld'), array(), array(
+ array('text', '/hello'),
+ ),
+ '#^(?P<locale>[^\.]++)\.example\.(?P<tld>[^\.]++)$#sDi', array('locale', 'tld'), array(
+ array('variable', '.', '[^\.]++', 'tld'),
+ array('text', '.example'),
+ array('variable', '', '[^\.]++', 'locale'),
+ ),
+ ),
+ );
+ }
+
+ /**
+ * @expectedException \DomainException
+ */
+ public function testRouteWithTooLongVariableName()
+ {
+ $route = new Route(sprintf('/{%s}', str_repeat('a', RouteCompiler::VARIABLE_MAXIMUM_LENGTH + 1)));
+ $route->compile();
+ }
+}
+
+class Utf8RouteCompiler extends RouteCompiler
+{
+ const SEPARATORS = '/§';
+}
diff --git a/assets/php/vendor/symfony/routing/Tests/RouteTest.php b/assets/php/vendor/symfony/routing/Tests/RouteTest.php
new file mode 100644
index 0000000..c7af058
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Tests/RouteTest.php
@@ -0,0 +1,258 @@
+<?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\Tests;
+
+use PHPUnit\Framework\TestCase;
+use Symfony\Component\Routing\Route;
+
+class RouteTest extends TestCase
+{
+ public function testConstructor()
+ {
+ $route = new Route('/{foo}', array('foo' => 'bar'), array('foo' => '\d+'), array('foo' => 'bar'), '{locale}.example.com');
+ $this->assertEquals('/{foo}', $route->getPath(), '__construct() takes a path as its first argument');
+ $this->assertEquals(array('foo' => 'bar'), $route->getDefaults(), '__construct() takes defaults as its second argument');
+ $this->assertEquals(array('foo' => '\d+'), $route->getRequirements(), '__construct() takes requirements as its third argument');
+ $this->assertEquals('bar', $route->getOption('foo'), '__construct() takes options as its fourth argument');
+ $this->assertEquals('{locale}.example.com', $route->getHost(), '__construct() takes a host pattern as its fifth argument');
+
+ $route = new Route('/', array(), array(), array(), '', array('Https'), array('POST', 'put'), 'context.getMethod() == "GET"');
+ $this->assertEquals(array('https'), $route->getSchemes(), '__construct() takes schemes as its sixth argument and lowercases it');
+ $this->assertEquals(array('POST', 'PUT'), $route->getMethods(), '__construct() takes methods as its seventh argument and uppercases it');
+ $this->assertEquals('context.getMethod() == "GET"', $route->getCondition(), '__construct() takes a condition as its eight argument');
+
+ $route = new Route('/', array(), array(), array(), '', 'Https', 'Post');
+ $this->assertEquals(array('https'), $route->getSchemes(), '__construct() takes a single scheme as its sixth argument');
+ $this->assertEquals(array('POST'), $route->getMethods(), '__construct() takes a single method as its seventh argument');
+ }
+
+ public function testPath()
+ {
+ $route = new Route('/{foo}');
+ $route->setPath('/{bar}');
+ $this->assertEquals('/{bar}', $route->getPath(), '->setPath() sets the path');
+ $route->setPath('');
+ $this->assertEquals('/', $route->getPath(), '->setPath() adds a / at the beginning of the path if needed');
+ $route->setPath('bar');
+ $this->assertEquals('/bar', $route->getPath(), '->setPath() adds a / at the beginning of the path if needed');
+ $this->assertEquals($route, $route->setPath(''), '->setPath() implements a fluent interface');
+ $route->setPath('//path');
+ $this->assertEquals('/path', $route->getPath(), '->setPath() does not allow two slashes "//" at the beginning of the path as it would be confused with a network path when generating the path from the route');
+ }
+
+ public function testOptions()
+ {
+ $route = new Route('/{foo}');
+ $route->setOptions(array('foo' => 'bar'));
+ $this->assertEquals(array_merge(array(
+ 'compiler_class' => 'Symfony\\Component\\Routing\\RouteCompiler',
+ ), array('foo' => 'bar')), $route->getOptions(), '->setOptions() sets the options');
+ $this->assertEquals($route, $route->setOptions(array()), '->setOptions() implements a fluent interface');
+
+ $route->setOptions(array('foo' => 'foo'));
+ $route->addOptions(array('bar' => 'bar'));
+ $this->assertEquals($route, $route->addOptions(array()), '->addOptions() implements a fluent interface');
+ $this->assertEquals(array('foo' => 'foo', 'bar' => 'bar', 'compiler_class' => 'Symfony\\Component\\Routing\\RouteCompiler'), $route->getOptions(), '->addDefaults() keep previous defaults');
+ }
+
+ public function testOption()
+ {
+ $route = new Route('/{foo}');
+ $this->assertFalse($route->hasOption('foo'), '->hasOption() return false if option is not set');
+ $this->assertEquals($route, $route->setOption('foo', 'bar'), '->setOption() implements a fluent interface');
+ $this->assertEquals('bar', $route->getOption('foo'), '->setOption() sets the option');
+ $this->assertTrue($route->hasOption('foo'), '->hasOption() return true if option is set');
+ }
+
+ public function testDefaults()
+ {
+ $route = new Route('/{foo}');
+ $route->setDefaults(array('foo' => 'bar'));
+ $this->assertEquals(array('foo' => 'bar'), $route->getDefaults(), '->setDefaults() sets the defaults');
+ $this->assertEquals($route, $route->setDefaults(array()), '->setDefaults() implements a fluent interface');
+
+ $route->setDefault('foo', 'bar');
+ $this->assertEquals('bar', $route->getDefault('foo'), '->setDefault() sets a default value');
+
+ $route->setDefault('foo2', 'bar2');
+ $this->assertEquals('bar2', $route->getDefault('foo2'), '->getDefault() return the default value');
+ $this->assertNull($route->getDefault('not_defined'), '->getDefault() return null if default value is not set');
+
+ $route->setDefault('_controller', $closure = function () { return 'Hello'; });
+ $this->assertEquals($closure, $route->getDefault('_controller'), '->setDefault() sets a default value');
+
+ $route->setDefaults(array('foo' => 'foo'));
+ $route->addDefaults(array('bar' => 'bar'));
+ $this->assertEquals($route, $route->addDefaults(array()), '->addDefaults() implements a fluent interface');
+ $this->assertEquals(array('foo' => 'foo', 'bar' => 'bar'), $route->getDefaults(), '->addDefaults() keep previous defaults');
+ }
+
+ public function testRequirements()
+ {
+ $route = new Route('/{foo}');
+ $route->setRequirements(array('foo' => '\d+'));
+ $this->assertEquals(array('foo' => '\d+'), $route->getRequirements(), '->setRequirements() sets the requirements');
+ $this->assertEquals('\d+', $route->getRequirement('foo'), '->getRequirement() returns a requirement');
+ $this->assertNull($route->getRequirement('bar'), '->getRequirement() returns null if a requirement is not defined');
+ $route->setRequirements(array('foo' => '^\d+$'));
+ $this->assertEquals('\d+', $route->getRequirement('foo'), '->getRequirement() removes ^ and $ from the path');
+ $this->assertEquals($route, $route->setRequirements(array()), '->setRequirements() implements a fluent interface');
+
+ $route->setRequirements(array('foo' => '\d+'));
+ $route->addRequirements(array('bar' => '\d+'));
+ $this->assertEquals($route, $route->addRequirements(array()), '->addRequirements() implements a fluent interface');
+ $this->assertEquals(array('foo' => '\d+', 'bar' => '\d+'), $route->getRequirements(), '->addRequirement() keep previous requirements');
+ }
+
+ public function testRequirement()
+ {
+ $route = new Route('/{foo}');
+ $this->assertFalse($route->hasRequirement('foo'), '->hasRequirement() return false if requirement is not set');
+ $route->setRequirement('foo', '^\d+$');
+ $this->assertEquals('\d+', $route->getRequirement('foo'), '->setRequirement() removes ^ and $ from the path');
+ $this->assertTrue($route->hasRequirement('foo'), '->hasRequirement() return true if requirement is set');
+ }
+
+ /**
+ * @dataProvider getInvalidRequirements
+ * @expectedException \InvalidArgumentException
+ */
+ public function testSetInvalidRequirement($req)
+ {
+ $route = new Route('/{foo}');
+ $route->setRequirement('foo', $req);
+ }
+
+ public function getInvalidRequirements()
+ {
+ return array(
+ array(''),
+ array(array()),
+ array('^$'),
+ array('^'),
+ array('$'),
+ );
+ }
+
+ public function testHost()
+ {
+ $route = new Route('/');
+ $route->setHost('{locale}.example.net');
+ $this->assertEquals('{locale}.example.net', $route->getHost(), '->setHost() sets the host pattern');
+ }
+
+ public function testScheme()
+ {
+ $route = new Route('/');
+ $this->assertEquals(array(), $route->getSchemes(), 'schemes is initialized with array()');
+ $this->assertFalse($route->hasScheme('http'));
+ $route->setSchemes('hTTp');
+ $this->assertEquals(array('http'), $route->getSchemes(), '->setSchemes() accepts a single scheme string and lowercases it');
+ $this->assertTrue($route->hasScheme('htTp'));
+ $this->assertFalse($route->hasScheme('httpS'));
+ $route->setSchemes(array('HttpS', 'hTTp'));
+ $this->assertEquals(array('https', 'http'), $route->getSchemes(), '->setSchemes() accepts an array of schemes and lowercases them');
+ $this->assertTrue($route->hasScheme('htTp'));
+ $this->assertTrue($route->hasScheme('httpS'));
+ }
+
+ public function testMethod()
+ {
+ $route = new Route('/');
+ $this->assertEquals(array(), $route->getMethods(), 'methods is initialized with array()');
+ $route->setMethods('gEt');
+ $this->assertEquals(array('GET'), $route->getMethods(), '->setMethods() accepts a single method string and uppercases it');
+ $route->setMethods(array('gEt', 'PosT'));
+ $this->assertEquals(array('GET', 'POST'), $route->getMethods(), '->setMethods() accepts an array of methods and uppercases them');
+ }
+
+ public function testCondition()
+ {
+ $route = new Route('/');
+ $this->assertSame('', $route->getCondition());
+ $route->setCondition('context.getMethod() == "GET"');
+ $this->assertSame('context.getMethod() == "GET"', $route->getCondition());
+ }
+
+ public function testCompile()
+ {
+ $route = new Route('/{foo}');
+ $this->assertInstanceOf('Symfony\Component\Routing\CompiledRoute', $compiled = $route->compile(), '->compile() returns a compiled route');
+ $this->assertSame($compiled, $route->compile(), '->compile() only compiled the route once if unchanged');
+ $route->setRequirement('foo', '.*');
+ $this->assertNotSame($compiled, $route->compile(), '->compile() recompiles if the route was modified');
+ }
+
+ public function testSerialize()
+ {
+ $route = new Route('/prefix/{foo}', array('foo' => 'default'), array('foo' => '\d+'));
+
+ $serialized = serialize($route);
+ $unserialized = unserialize($serialized);
+
+ $this->assertEquals($route, $unserialized);
+ $this->assertNotSame($route, $unserialized);
+ }
+
+ /**
+ * Tests that the compiled version is also serialized to prevent the overhead
+ * of compiling it again after unserialize.
+ */
+ public function testSerializeWhenCompiled()
+ {
+ $route = new Route('/prefix/{foo}', array('foo' => 'default'), array('foo' => '\d+'));
+ $route->setHost('{locale}.example.net');
+ $route->compile();
+
+ $serialized = serialize($route);
+ $unserialized = unserialize($serialized);
+
+ $this->assertEquals($route, $unserialized);
+ $this->assertNotSame($route, $unserialized);
+ }
+
+ /**
+ * Tests that unserialization does not fail when the compiled Route is of a
+ * class other than CompiledRoute, such as a subclass of it.
+ */
+ public function testSerializeWhenCompiledWithClass()
+ {
+ $route = new Route('/', array(), array(), array('compiler_class' => '\Symfony\Component\Routing\Tests\Fixtures\CustomRouteCompiler'));
+ $this->assertInstanceOf('\Symfony\Component\Routing\Tests\Fixtures\CustomCompiledRoute', $route->compile(), '->compile() returned a proper route');
+
+ $serialized = serialize($route);
+ try {
+ $unserialized = unserialize($serialized);
+ $this->assertInstanceOf('\Symfony\Component\Routing\Tests\Fixtures\CustomCompiledRoute', $unserialized->compile(), 'the unserialized route compiled successfully');
+ } catch (\Exception $e) {
+ $this->fail('unserializing a route which uses a custom compiled route class');
+ }
+ }
+
+ /**
+ * Tests that the serialized representation of a route in one symfony version
+ * also works in later symfony versions, i.e. the unserialized route is in the
+ * same state as another, semantically equivalent, route.
+ */
+ public function testSerializedRepresentationKeepsWorking()
+ {
+ $serialized = 'C:31:"Symfony\Component\Routing\Route":936:{a:8:{s:4:"path";s:13:"/prefix/{foo}";s:4:"host";s:20:"{locale}.example.net";s:8:"defaults";a:1:{s:3:"foo";s:7:"default";}s:12:"requirements";a:1:{s:3:"foo";s:3:"\d+";}s:7:"options";a:1:{s:14:"compiler_class";s:39:"Symfony\Component\Routing\RouteCompiler";}s:7:"schemes";a:0:{}s:7:"methods";a:0:{}s:8:"compiled";C:39:"Symfony\Component\Routing\CompiledRoute":571:{a:8:{s:4:"vars";a:2:{i:0;s:6:"locale";i:1;s:3:"foo";}s:11:"path_prefix";s:7:"/prefix";s:10:"path_regex";s:31:"#^/prefix(?:/(?P<foo>\d+))?$#sD";s:11:"path_tokens";a:2:{i:0;a:4:{i:0;s:8:"variable";i:1;s:1:"/";i:2;s:3:"\d+";i:3;s:3:"foo";}i:1;a:2:{i:0;s:4:"text";i:1;s:7:"/prefix";}}s:9:"path_vars";a:1:{i:0;s:3:"foo";}s:10:"host_regex";s:40:"#^(?P<locale>[^\.]++)\.example\.net$#sDi";s:11:"host_tokens";a:2:{i:0;a:2:{i:0;s:4:"text";i:1;s:12:".example.net";}i:1;a:4:{i:0;s:8:"variable";i:1;s:0:"";i:2;s:7:"[^\.]++";i:3;s:6:"locale";}}s:9:"host_vars";a:1:{i:0;s:6:"locale";}}}}}';
+ $unserialized = unserialize($serialized);
+
+ $route = new Route('/prefix/{foo}', array('foo' => 'default'), array('foo' => '\d+'));
+ $route->setHost('{locale}.example.net');
+ $route->compile();
+
+ $this->assertEquals($route, $unserialized);
+ $this->assertNotSame($route, $unserialized);
+ }
+}
diff --git a/assets/php/vendor/symfony/routing/Tests/RouterTest.php b/assets/php/vendor/symfony/routing/Tests/RouterTest.php
new file mode 100644
index 0000000..3e3d43f
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Tests/RouterTest.php
@@ -0,0 +1,163 @@
+<?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\Tests;
+
+use PHPUnit\Framework\TestCase;
+use Symfony\Component\Routing\RouteCollection;
+use Symfony\Component\Routing\Router;
+use Symfony\Component\HttpFoundation\Request;
+
+class RouterTest extends TestCase
+{
+ private $router = null;
+
+ private $loader = null;
+
+ protected function setUp()
+ {
+ $this->loader = $this->getMockBuilder('Symfony\Component\Config\Loader\LoaderInterface')->getMock();
+ $this->router = new Router($this->loader, 'routing.yml');
+ }
+
+ public function testSetOptionsWithSupportedOptions()
+ {
+ $this->router->setOptions(array(
+ 'cache_dir' => './cache',
+ 'debug' => true,
+ 'resource_type' => 'ResourceType',
+ ));
+
+ $this->assertSame('./cache', $this->router->getOption('cache_dir'));
+ $this->assertTrue($this->router->getOption('debug'));
+ $this->assertSame('ResourceType', $this->router->getOption('resource_type'));
+ }
+
+ /**
+ * @expectedException \InvalidArgumentException
+ * @expectedExceptionMessage The Router does not support the following options: "option_foo", "option_bar"
+ */
+ public function testSetOptionsWithUnsupportedOptions()
+ {
+ $this->router->setOptions(array(
+ 'cache_dir' => './cache',
+ 'option_foo' => true,
+ 'option_bar' => 'baz',
+ 'resource_type' => 'ResourceType',
+ ));
+ }
+
+ public function testSetOptionWithSupportedOption()
+ {
+ $this->router->setOption('cache_dir', './cache');
+
+ $this->assertSame('./cache', $this->router->getOption('cache_dir'));
+ }
+
+ /**
+ * @expectedException \InvalidArgumentException
+ * @expectedExceptionMessage The Router does not support the "option_foo" option
+ */
+ public function testSetOptionWithUnsupportedOption()
+ {
+ $this->router->setOption('option_foo', true);
+ }
+
+ /**
+ * @expectedException \InvalidArgumentException
+ * @expectedExceptionMessage The Router does not support the "option_foo" option
+ */
+ public function testGetOptionWithUnsupportedOption()
+ {
+ $this->router->getOption('option_foo', true);
+ }
+
+ public function testThatRouteCollectionIsLoaded()
+ {
+ $this->router->setOption('resource_type', 'ResourceType');
+
+ $routeCollection = new RouteCollection();
+
+ $this->loader->expects($this->once())
+ ->method('load')->with('routing.yml', 'ResourceType')
+ ->will($this->returnValue($routeCollection));
+
+ $this->assertSame($routeCollection, $this->router->getRouteCollection());
+ }
+
+ /**
+ * @dataProvider provideMatcherOptionsPreventingCaching
+ */
+ public function testMatcherIsCreatedIfCacheIsNotConfigured($option)
+ {
+ $this->router->setOption($option, null);
+
+ $this->loader->expects($this->once())
+ ->method('load')->with('routing.yml', null)
+ ->will($this->returnValue(new RouteCollection()));
+
+ $this->assertInstanceOf('Symfony\\Component\\Routing\\Matcher\\UrlMatcher', $this->router->getMatcher());
+ }
+
+ public function provideMatcherOptionsPreventingCaching()
+ {
+ return array(
+ array('cache_dir'),
+ array('matcher_cache_class'),
+ );
+ }
+
+ /**
+ * @dataProvider provideGeneratorOptionsPreventingCaching
+ */
+ public function testGeneratorIsCreatedIfCacheIsNotConfigured($option)
+ {
+ $this->router->setOption($option, null);
+
+ $this->loader->expects($this->once())
+ ->method('load')->with('routing.yml', null)
+ ->will($this->returnValue(new RouteCollection()));
+
+ $this->assertInstanceOf('Symfony\\Component\\Routing\\Generator\\UrlGenerator', $this->router->getGenerator());
+ }
+
+ public function provideGeneratorOptionsPreventingCaching()
+ {
+ return array(
+ array('cache_dir'),
+ array('generator_cache_class'),
+ );
+ }
+
+ public function testMatchRequestWithUrlMatcherInterface()
+ {
+ $matcher = $this->getMockBuilder('Symfony\Component\Routing\Matcher\UrlMatcherInterface')->getMock();
+ $matcher->expects($this->once())->method('match');
+
+ $p = new \ReflectionProperty($this->router, 'matcher');
+ $p->setAccessible(true);
+ $p->setValue($this->router, $matcher);
+
+ $this->router->matchRequest(Request::create('/'));
+ }
+
+ public function testMatchRequestWithRequestMatcherInterface()
+ {
+ $matcher = $this->getMockBuilder('Symfony\Component\Routing\Matcher\RequestMatcherInterface')->getMock();
+ $matcher->expects($this->once())->method('matchRequest');
+
+ $p = new \ReflectionProperty($this->router, 'matcher');
+ $p->setAccessible(true);
+ $p->setValue($this->router, $matcher);
+
+ $this->router->matchRequest(Request::create('/'));
+ }
+}
diff --git a/assets/php/vendor/symfony/routing/composer.json b/assets/php/vendor/symfony/routing/composer.json
new file mode 100644
index 0000000..4d820cc
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/composer.json
@@ -0,0 +1,56 @@
+{
+ "name": "symfony/routing",
+ "type": "library",
+ "description": "Symfony Routing Component",
+ "keywords": ["routing", "router", "URL", "URI"],
+ "homepage": "https://symfony.com",
+ "license": "MIT",
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "require": {
+ "php": "^5.5.9|>=7.0.8"
+ },
+ "require-dev": {
+ "symfony/config": "^3.3.1|~4.0",
+ "symfony/http-foundation": "~2.8|~3.0|~4.0",
+ "symfony/yaml": "~3.4|~4.0",
+ "symfony/expression-language": "~2.8|~3.0|~4.0",
+ "symfony/dependency-injection": "~3.3|~4.0",
+ "doctrine/annotations": "~1.0",
+ "doctrine/common": "~2.2",
+ "psr/log": "~1.0"
+ },
+ "conflict": {
+ "symfony/config": "<3.3.1",
+ "symfony/dependency-injection": "<3.3",
+ "symfony/yaml": "<3.4"
+ },
+ "suggest": {
+ "symfony/http-foundation": "For using a Symfony Request object",
+ "symfony/config": "For using the all-in-one router or any loader",
+ "symfony/yaml": "For using the YAML loader",
+ "symfony/expression-language": "For using expression matching",
+ "doctrine/annotations": "For using the annotation loader",
+ "symfony/dependency-injection": "For loading routes from a service"
+ },
+ "autoload": {
+ "psr-4": { "Symfony\\Component\\Routing\\": "" },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
+ },
+ "minimum-stability": "dev",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.4-dev"
+ }
+ }
+}
diff --git a/assets/php/vendor/symfony/routing/phpunit.xml.dist b/assets/php/vendor/symfony/routing/phpunit.xml.dist
new file mode 100644
index 0000000..bcc0959
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/phpunit.xml.dist
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/4.1/phpunit.xsd"
+ backupGlobals="false"
+ colors="true"
+ bootstrap="vendor/autoload.php"
+ failOnRisky="true"
+ failOnWarning="true"
+>
+ <php>
+ <ini name="error_reporting" value="-1" />
+ </php>
+
+ <testsuites>
+ <testsuite name="Symfony Routing Component Test Suite">
+ <directory>./Tests/</directory>
+ </testsuite>
+ </testsuites>
+
+ <filter>
+ <whitelist>
+ <directory>./</directory>
+ <exclude>
+ <directory>./Tests</directory>
+ <directory>./vendor</directory>
+ </exclude>
+ </whitelist>
+ </filter>
+</phpunit>