From b726e4342fca5ea24d9b496904eaafeca389dd81 Mon Sep 17 00:00:00 2001 From: catch <catch@35733.no-reply.drupal.org> Date: Wed, 6 Feb 2013 11:54:22 +0000 Subject: [PATCH] Issue #1894002 by scor, msonnabaum, effulgentsia: Update vendor libraries and pin them to specific versions in composer.json. --- core/composer.json | 26 +- core/composer.lock | 183 ++-- core/lib/Drupal/Core/CoreBundle.php | 3 +- .../lib/Drupal/Core/Routing/CompiledRoute.php | 18 +- .../lib/Drupal/Core/Routing/RouteCompiler.php | 20 +- core/vendor/autoload.php | 2 +- core/vendor/composer/autoload_namespaces.php | 1 + core/vendor/composer/autoload_real.php | 6 +- core/vendor/composer/installed.json | 922 +++++++++--------- core/vendor/easyrdf/easyrdf/.gitignore | 9 - core/vendor/easyrdf/easyrdf/Makefile | 136 --- core/vendor/easyrdf/easyrdf/README.md | 25 - core/vendor/easyrdf/easyrdf/composer.json | 2 +- core/vendor/easyrdf/easyrdf/doap.php | 5 +- core/vendor/psr/log/.gitignore | 1 + core/vendor/psr/log/LICENSE | 19 + .../vendor/psr/log/Psr/Log/AbstractLogger.php | 120 +++ .../log/Psr/Log/InvalidArgumentException.php | 7 + core/vendor/psr/log/Psr/Log/LogLevel.php | 18 + .../psr/log/Psr/Log/LoggerAwareInterface.php | 17 + .../psr/log/Psr/Log/LoggerAwareTrait.php | 22 + .../psr/log/Psr/Log/LoggerInterface.php | 114 +++ core/vendor/psr/log/Psr/Log/LoggerTrait.php | 131 +++ core/vendor/psr/log/Psr/Log/NullLogger.php | 27 + .../log/Psr/Log/Test/LoggerInterfaceTest.php | 116 +++ core/vendor/psr/log/README.md | 45 + core/vendor/psr/log/composer.json | 17 + .../Component/ClassLoader/.gitattributes | 2 - .../ClassLoader/DebugClassLoader.php | 4 + .../DependencyInjection/.gitattributes | 2 - .../MergeExtensionConfigurationPass.php | 1 + .../ReplaceAliasByActualDefinitionPass.php | 9 +- .../Compiler/ResolveInvalidReferencesPass.php | 2 +- .../DependencyInjection/ContainerBuilder.php | 9 +- .../DependencyInjection/Dumper/PhpDumper.php | 102 +- .../DependencyInjection/Dumper/YamlDumper.php | 12 +- .../PrependExtensionInterface.php | 2 +- ...tionOnInvalidReferenceBehaviorPassTest.php | 4 +- ...ReplaceAliasByActualDefinitionPassTest.php | 10 + .../ResolveInvalidReferencesPassTest.php | 14 + .../Tests/ContainerBuilderTest.php | 11 + .../Tests/DefinitionTest.php | 2 +- .../Tests/Dumper/PhpDumperTest.php | 7 + .../Tests/Fixtures/containers/container9.php | 25 +- .../Tests/Fixtures/graphviz/services9.dot | 12 +- .../Tests/Fixtures/includes/classes.php | 13 + .../Tests/Fixtures/php/services9.php | 68 +- .../Tests/Fixtures/php/services9_compiled.php | 241 +++++ .../Tests/Fixtures/xml/services9.xml | 24 +- .../Tests/Fixtures/yaml/services9.yml | 21 +- .../Component/EventDispatcher/.gitattributes | 2 - .../Tests/GenericEventTest.php | 2 +- .../Component/HttpFoundation/.gitattributes | 2 - .../Component/HttpFoundation/CHANGELOG.md | 4 + .../MimeType/FileBinaryMimeTypeGuesser.php | 2 +- .../Component/HttpFoundation/JsonResponse.php | 12 +- .../Component/HttpFoundation/Request.php | 24 +- .../HttpFoundation/Session/Flash/FlashBag.php | 7 + .../Tests/File/UploadedFileTest.php | 2 +- .../HttpFoundation/Tests/RequestTest.php | 52 +- .../Tests/Session/Flash/FlashBagTest.php | 3 +- .../Handler/MemcachedSessionHandlerTest.php | 2 +- .../Handler/NativeFileSessionHandlerTest.php | 6 +- .../Component/HttpKernel/.gitattributes | 2 - .../Symfony/Component/HttpKernel/CHANGELOG.md | 6 + .../Controller/ControllerReference.php | 45 + .../Controller/ControllerResolver.php | 4 +- .../DataCollector/ConfigDataCollector.php | 11 + .../DataCollector/RequestDataCollector.php | 2 +- .../HttpKernel/Debug/ErrorHandler.php | 15 +- .../Debug/TraceableEventDispatcher.php | 2 +- .../ContainerAwareHttpKernel.php | 68 ++ .../DeprecationLoggerListener.php | 2 +- .../EventListener/ExceptionListener.php | 8 +- .../EventListener/RouterListener.php | 2 +- .../EventListener/RouterProxyListener.php | 106 ++ .../HttpKernel/HttpContentRenderer.php | 176 ++++ .../Symfony/Component/HttpKernel/Kernel.php | 4 +- .../HttpKernel/Log/LoggerInterface.php | 29 +- .../Component/HttpKernel/Log/NullLogger.php | 36 +- .../Profiler/FileProfilerStorage.php | 53 +- .../HttpKernel/Profiler/Profiler.php | 4 +- .../Profiler/RedisProfilerStorage.php | 32 +- .../DefaultRenderingStrategy.php | 100 ++ .../EsiRenderingStrategy.php | 85 ++ .../HIncludeRenderingStrategy.php | 105 ++ .../ProxyAwareRenderingStrategy.php | 59 ++ .../RenderingStrategyInterface.php | 43 + .../Controller/ControllerResolverTest.php | 2 +- .../Tests/Debug/ErrorHandlerTest.php | 8 +- .../Debug/TraceableEventDispatcherTest.php | 4 +- .../ContainerAwareHttpKernelTest.php | 141 +++ .../EventListener/ExceptionListenerTest.php | 4 +- .../EventListener/RouterProxyListenerTest.php | 101 ++ .../Tests/HttpContentRendererTest.php | 124 +++ .../HttpKernel/Tests/HttpKernelTest.php | 2 +- .../Component/HttpKernel/Tests/Logger.php | 82 +- .../Profiler/FileProfilerStorageTest.php | 15 + .../DefaultRenderingStrategyTest.php | 117 +++ .../EsiRenderingStrategyTest.php | 63 ++ .../HIncludeRenderingStrategyTest.php | 67 ++ .../ProxyAwareRenderingStrategyTest.php | 63 ++ .../HttpKernel/Tests/UriSignerTest.php | 37 + .../Component/HttpKernel/UriSigner.php | 75 ++ .../Component/HttpKernel/composer.json | 3 +- .../Symfony/Component/Process/.gitattributes | 2 - .../Exception/ProcessFailedException.php | 6 +- .../Component/Process/ExecutableFinder.php | 21 +- .../process/Symfony/Component/Process/LICENSE | 2 +- .../Symfony/Component/Process/PhpProcess.php | 13 +- .../Symfony/Component/Process/Process.php | 51 +- .../Process/Tests/AbstractProcessTest.php | 21 +- .../Process/Tests/PhpExecutableFinderTest.php | 2 +- .../Process/Tests/PhpProcessTest.php | 21 + .../Tests/SigchildDisabledProcessTest.php | 20 +- .../Tests/SigchildEnabledProcessTest.php | 19 +- .../Process/Tests/SimpleProcessTest.php | 27 +- .../Symfony/Component/Routing/.gitattributes | 2 - .../Component/Routing/Annotation/Route.php | 58 +- .../Symfony/Component/Routing/CHANGELOG.md | 51 + .../Component/Routing/CompiledRoute.php | 42 +- .../Generator/Dumper/PhpGeneratorDumper.php | 10 +- .../Routing/Generator/UrlGenerator.php | 121 ++- .../Generator/UrlGeneratorInterface.php | 62 +- .../routing/Symfony/Component/Routing/LICENSE | 2 +- .../Routing/Loader/AnnotationClassLoader.php | 48 +- .../Routing/Loader/XmlFileLoader.php | 32 +- .../Routing/Loader/YamlFileLoader.php | 39 +- .../Loader/schema/routing/routing-1.0.xsd | 21 +- .../Matcher/Dumper/ApacheMatcherDumper.php | 42 +- .../Matcher/Dumper/PhpMatcherDumper.php | 42 +- .../Routing/Matcher/TraceableUrlMatcher.php | 14 +- .../Component/Routing/Matcher/UrlMatcher.php | 6 +- .../Component/Routing/RequestContext.php | 26 +- .../Symfony/Component/Routing/Route.php | 203 +++- .../Component/Routing/RouteCollection.php | 32 +- .../Component/Routing/RouteCompiler.php | 44 +- .../Routing/RouteCompilerInterface.php | 5 +- .../Symfony/Component/Routing/Router.php | 6 +- .../Routing/Tests/Annotation/RouteTest.php | 5 +- .../Tests/Fixtures/dumper/url_matcher1.apache | 40 +- .../Tests/Fixtures/dumper/url_matcher1.php | 22 +- .../Tests/Fixtures/dumper/url_matcher2.php | 22 +- .../Tests/Fixtures/namespaceprefix.xml | 2 +- .../Routing/Tests/Fixtures/validpattern.xml | 2 +- .../Routing/Tests/Fixtures/validpattern.yml | 8 +- .../Routing/Tests/Fixtures/validresource.xml | 2 +- .../Routing/Tests/Fixtures/validresource.yml | 12 +- .../Dumper/PhpGeneratorDumperTest.php | 2 +- .../Tests/Generator/UrlGeneratorTest.php | 216 +++- .../Loader/AnnotationClassLoaderTest.php | 6 +- .../Tests/Loader/PhpFileLoaderTest.php | 4 +- .../Tests/Loader/XmlFileLoaderTest.php | 12 +- .../Tests/Loader/YamlFileLoaderTest.php | 10 +- .../Dumper/ApacheMatcherDumperTest.php | 2 +- .../Dumper/DumperPrefixCollectionTest.php | 2 +- .../Matcher/Dumper/PhpMatcherDumperTest.php | 4 +- .../Matcher/RedirectableUrlMatcherTest.php | 2 +- .../Routing/Tests/Matcher/UrlMatcherTest.php | 16 +- .../Routing/Tests/RouteCollectionTest.php | 26 +- .../Routing/Tests/RouteCompilerTest.php | 20 +- .../Component/Routing/Tests/RouteTest.php | 86 +- .../Symfony/Component/Routing/composer.json | 3 +- .../Validator/Constraints/AllValidator.php | 4 +- .../Constraints/CollectionValidator.php | 8 +- .../Validator/Mapping/ClassMetadata.php | 2 +- .../Tests/Constraints/AllValidatorTest.php | 62 +- .../Constraints/CollectionValidatorTest.php | 190 ++-- .../Constraints/MaxLengthValidatorTest.php | 13 - .../Tests/Constraints/MaxValidatorTest.php | 13 - .../Constraints/MinLengthValidatorTest.php | 13 - .../Tests/Constraints/MinValidatorTest.php | 16 - .../Validator/Tests/ExecutionContextTest.php | 27 - .../Validator/Tests/Fixtures/Entity.php | 10 +- .../Validator/Tests/GraphWalkerTest.php | 13 - .../Tests/Mapping/GetterMetadataTest.php | 4 +- .../Mapping/Loader/AnnotationLoaderTest.php | 22 +- .../Mapping/Loader/XmlFileLoaderTest.php | 12 +- .../Mapping/Loader/YamlFileLoaderTest.php | 12 +- .../Mapping/Loader/constraint-mapping.xml | 21 +- .../Mapping/Loader/constraint-mapping.yml | 15 +- .../Tests/Mapping/PropertyMetadataTest.php | 4 +- .../Validator/Tests/ValidatorBuilderTest.php | 11 - .../Validator/Tests/ValidatorContextTest.php | 13 - .../Validator/Tests/ValidatorFactoryTest.php | 13 - .../Symfony/Component/Yaml/.gitattributes | 2 - .../yaml/Symfony/Component/Yaml/Dumper.php | 16 +- .../yaml/Symfony/Component/Yaml/Inline.php | 77 +- .../yaml/Symfony/Component/Yaml/LICENSE | 2 +- .../yaml/Symfony/Component/Yaml/Parser.php | 35 +- .../Component/Yaml/Tests/DumperTest.php | 21 +- .../Component/Yaml/Tests/InlineTest.php | 21 +- .../Component/Yaml/Tests/ParserTest.php | 229 ++++- .../yaml/Symfony/Component/Yaml/Yaml.php | 60 +- core/vendor/twig/twig/.editorconfig | 18 + core/vendor/twig/twig/CHANGELOG | 22 + core/vendor/twig/twig/LICENSE | 2 +- .../twig/twig/bin/create_pear_package.php | 42 - core/vendor/twig/twig/composer.json | 2 +- core/vendor/twig/twig/doc/advanced.rst | 386 +++----- core/vendor/twig/twig/doc/advanced_legacy.rst | 887 +++++++++++++++++ core/vendor/twig/twig/doc/api.rst | 7 +- core/vendor/twig/twig/doc/deprecated.rst | 98 ++ .../twig/doc/filters/convert_encoding.rst | 6 + core/vendor/twig/twig/doc/filters/date.rst | 6 + .../twig/twig/doc/filters/date_modify.rst | 5 + core/vendor/twig/twig/doc/filters/default.rst | 5 + core/vendor/twig/twig/doc/filters/escape.rst | 8 +- core/vendor/twig/twig/doc/filters/join.rst | 5 + .../twig/twig/doc/filters/json_encode.rst | 5 + .../twig/twig/doc/filters/number_format.rst | 7 + core/vendor/twig/twig/doc/filters/replace.rst | 5 + core/vendor/twig/twig/doc/filters/slice.rst | 13 + core/vendor/twig/twig/doc/filters/split.rst | 12 +- core/vendor/twig/twig/doc/filters/trim.rst | 5 + .../twig/twig/doc/functions/constant.rst | 9 + core/vendor/twig/twig/doc/functions/cycle.rst | 5 + core/vendor/twig/twig/doc/functions/date.rst | 6 + core/vendor/twig/twig/doc/functions/dump.rst | 5 + .../twig/twig/doc/functions/include.rst | 80 ++ core/vendor/twig/twig/doc/functions/index.rst | 1 + .../vendor/twig/twig/doc/functions/random.rst | 5 + core/vendor/twig/twig/doc/functions/range.rst | 7 + .../doc/functions/template_from_string.rst | 5 + core/vendor/twig/twig/doc/index.rst | 1 + core/vendor/twig/twig/doc/tags/include.rst | 18 +- core/vendor/twig/twig/doc/tags/index.rst | 2 +- core/vendor/twig/twig/doc/tags/raw.rst | 16 - core/vendor/twig/twig/doc/tags/verbatim.rst | 24 + core/vendor/twig/twig/doc/templates.rst | 80 +- core/vendor/twig/twig/ext/twig/php_twig.h | 2 +- core/vendor/twig/twig/ext/twig/twig.c | 2 +- core/vendor/twig/twig/lib/Twig/Compiler.php | 2 +- .../twig/twig/lib/Twig/CompilerInterface.php | 1 + .../vendor/twig/twig/lib/Twig/Environment.php | 344 ++++--- .../twig/lib/Twig/ExistsLoaderInterface.php | 1 + .../twig/twig/lib/Twig/ExpressionParser.php | 170 +++- .../twig/twig/lib/Twig/Extension/Core.php | 186 ++-- .../twig/twig/lib/Twig/Extension/Debug.php | 2 +- .../twig/twig/lib/Twig/Extension/Escaper.php | 2 +- .../twig/twig/lib/Twig/Extension/Staging.php | 114 +++ .../twig/lib/Twig/Extension/StringLoader.php | 2 +- core/vendor/twig/twig/lib/Twig/Filter.php | 11 +- .../twig/twig/lib/Twig/Filter/Function.php | 5 + .../twig/twig/lib/Twig/Filter/Method.php | 5 + .../vendor/twig/twig/lib/Twig/Filter/Node.php | 3 + .../twig/lib/Twig/FilterCallableInterface.php | 24 + .../twig/twig/lib/Twig/FilterInterface.php | 3 + core/vendor/twig/twig/lib/Twig/Function.php | 11 +- .../twig/twig/lib/Twig/Function/Function.php | 5 + .../twig/twig/lib/Twig/Function/Method.php | 5 + .../twig/twig/lib/Twig/Function/Node.php | 3 + .../lib/Twig/FunctionCallableInterface.php | 24 + .../twig/twig/lib/Twig/FunctionInterface.php | 3 + core/vendor/twig/twig/lib/Twig/Lexer.php | 12 +- .../twig/twig/lib/Twig/LexerInterface.php | 1 + .../twig/lib/Twig/Node/Expression/Call.php | 171 ++++ .../twig/lib/Twig/Node/Expression/Filter.php | 49 +- .../Twig/Node/Expression/Filter/Default.php | 2 +- .../lib/Twig/Node/Expression/Function.php | 55 +- .../twig/lib/Twig/Node/Expression/Test.php | 38 +- core/vendor/twig/twig/lib/Twig/Node/Macro.php | 29 +- .../twig/twig/lib/Twig/NodeInterface.php | 1 + .../twig/lib/Twig/NodeVisitor/Escaper.php | 20 +- .../twig/twig/lib/Twig/ParserInterface.php | 5 +- .../twig/twig/lib/Twig/SimpleFilter.php | 97 ++ .../twig/twig/lib/Twig/SimpleFunction.php | 85 ++ core/vendor/twig/twig/lib/Twig/SimpleTest.php | 47 + .../twig/twig/lib/Twig/TemplateInterface.php | 5 +- core/vendor/twig/twig/lib/Twig/Test.php | 35 + .../twig/twig/lib/Twig/Test/Function.php | 9 +- .../vendor/twig/twig/lib/Twig/Test/Method.php | 9 +- core/vendor/twig/twig/lib/Twig/Test/Node.php | 7 +- .../twig/lib/Twig/TestCallableInterface.php | 22 + .../twig/twig/lib/Twig/TestInterface.php | 1 + .../twig/twig/lib/Twig/TokenParser/For.php | 61 +- .../twig/twig/lib/Twig/TokenParser/Macro.php | 2 +- .../twig/twig/lib/Twig/TokenParserBroker.php | 30 +- .../lib/Twig/TokenParserBrokerInterface.php | 5 +- .../vendor/twig/twig/lib/Twig/TokenStream.php | 4 +- core/vendor/twig/twig/package.xml.tpl | 64 -- .../twig/test/Twig/Tests/EnvironmentTest.php | 237 +++++ .../test/Twig/Tests/ExpressionParserTest.php | 115 +++ .../expressions/ternary_operator_noelse.test | 10 + .../expressions/ternary_operator_nothen.test | 10 + .../Fixtures/filters/date_namedargs.test | 15 + .../Twig/Tests/Fixtures/filters/reverse.test | 6 + .../Twig/Tests/Fixtures/filters/slice.test | 2 + .../Tests/Fixtures/functions/constant.test | 10 +- .../Fixtures/functions/date_namedargs.test | 11 + .../Fixtures/functions/include/basic.test | 17 + .../functions/include/expression.test | 17 + .../functions/include/ignore_missing.test | 10 + .../Fixtures/functions/include/missing.test | 8 + .../functions/include/missing_nested.test | 16 + .../Fixtures/functions/include/sandbox.test | 10 + .../functions/include/template_instance.test | 10 + .../functions/include/templates_as_array.test | 12 + .../functions/include/with_context.test | 16 + .../functions/include/with_variables.test | 12 + .../Twig/Tests/Fixtures/functions/range.test | 8 + .../Tests/Fixtures/macros/default_values.test | 16 + .../Tests/Fixtures/tags/for/condition.test | 10 +- .../Fixtures/tags/for/loop_not_defined.test | 10 + .../tags/for/loop_not_defined_cond.test | 9 + .../tags/raw/mixed_usage_with_raw.test | 10 + .../Tests/Fixtures/tags/verbatim/basic.test | 10 + .../tags/verbatim/mixed_usage_with_raw.test | 10 + .../tags/verbatim/whitespace_control.test | 56 ++ .../Twig/Tests/Node/Expression/FilterTest.php | 83 +- .../Tests/Node/Expression/FunctionTest.php | 33 +- .../Node/Expression/PHP53/FilterInclude.php | 6 + .../Node/Expression/PHP53/FunctionInclude.php | 6 + .../Node/Expression/PHP53/TestInclude.php | 6 + .../Twig/Tests/Node/Expression/TestTest.php | 25 +- .../twig/test/Twig/Tests/Node/MacroTest.php | 8 +- .../Twig/Tests/NodeVisitor/OptimizerTest.php | 4 - .../twig/test/Twig/Tests/TemplateTest.php | 108 ++ .../twig/test/Twig/Tests/TokenStreamTest.php | 29 + 319 files changed, 9186 insertions(+), 2647 deletions(-) delete mode 100644 core/vendor/easyrdf/easyrdf/.gitignore delete mode 100644 core/vendor/easyrdf/easyrdf/Makefile create mode 100644 core/vendor/psr/log/.gitignore create mode 100644 core/vendor/psr/log/LICENSE create mode 100644 core/vendor/psr/log/Psr/Log/AbstractLogger.php create mode 100644 core/vendor/psr/log/Psr/Log/InvalidArgumentException.php create mode 100644 core/vendor/psr/log/Psr/Log/LogLevel.php create mode 100644 core/vendor/psr/log/Psr/Log/LoggerAwareInterface.php create mode 100644 core/vendor/psr/log/Psr/Log/LoggerAwareTrait.php create mode 100644 core/vendor/psr/log/Psr/Log/LoggerInterface.php create mode 100644 core/vendor/psr/log/Psr/Log/LoggerTrait.php create mode 100644 core/vendor/psr/log/Psr/Log/NullLogger.php create mode 100644 core/vendor/psr/log/Psr/Log/Test/LoggerInterfaceTest.php create mode 100644 core/vendor/psr/log/README.md create mode 100644 core/vendor/psr/log/composer.json delete mode 100644 core/vendor/symfony/class-loader/Symfony/Component/ClassLoader/.gitattributes delete mode 100644 core/vendor/symfony/dependency-injection/Symfony/Component/DependencyInjection/.gitattributes rename core/vendor/symfony/dependency-injection/Symfony/Component/DependencyInjection/{Compiler => Extension}/PrependExtensionInterface.php (89%) create mode 100644 core/vendor/symfony/dependency-injection/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services9_compiled.php delete mode 100644 core/vendor/symfony/event-dispatcher/Symfony/Component/EventDispatcher/.gitattributes delete mode 100644 core/vendor/symfony/http-foundation/Symfony/Component/HttpFoundation/.gitattributes delete mode 100644 core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/.gitattributes create mode 100644 core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Controller/ControllerReference.php create mode 100644 core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/DependencyInjection/ContainerAwareHttpKernel.php create mode 100644 core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/EventListener/RouterProxyListener.php create mode 100644 core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/HttpContentRenderer.php create mode 100644 core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/RenderingStrategy/DefaultRenderingStrategy.php create mode 100644 core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/RenderingStrategy/EsiRenderingStrategy.php create mode 100644 core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/RenderingStrategy/HIncludeRenderingStrategy.php create mode 100644 core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/RenderingStrategy/ProxyAwareRenderingStrategy.php create mode 100644 core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/RenderingStrategy/RenderingStrategyInterface.php create mode 100644 core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Tests/DependencyInjection/ContainerAwareHttpKernelTest.php create mode 100644 core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Tests/EventListener/RouterProxyListenerTest.php create mode 100644 core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Tests/HttpContentRendererTest.php create mode 100644 core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Tests/RenderingStrategy/DefaultRenderingStrategyTest.php create mode 100644 core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Tests/RenderingStrategy/EsiRenderingStrategyTest.php create mode 100644 core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Tests/RenderingStrategy/HIncludeRenderingStrategyTest.php create mode 100644 core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Tests/RenderingStrategy/ProxyAwareRenderingStrategyTest.php create mode 100644 core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Tests/UriSignerTest.php create mode 100644 core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/UriSigner.php delete mode 100644 core/vendor/symfony/process/Symfony/Component/Process/.gitattributes create mode 100644 core/vendor/symfony/process/Symfony/Component/Process/Tests/PhpProcessTest.php delete mode 100644 core/vendor/symfony/routing/Symfony/Component/Routing/.gitattributes delete mode 100644 core/vendor/symfony/yaml/Symfony/Component/Yaml/.gitattributes create mode 100644 core/vendor/twig/twig/.editorconfig delete mode 100644 core/vendor/twig/twig/bin/create_pear_package.php create mode 100644 core/vendor/twig/twig/doc/advanced_legacy.rst create mode 100644 core/vendor/twig/twig/doc/deprecated.rst create mode 100644 core/vendor/twig/twig/doc/functions/include.rst delete mode 100644 core/vendor/twig/twig/doc/tags/raw.rst create mode 100644 core/vendor/twig/twig/doc/tags/verbatim.rst create mode 100644 core/vendor/twig/twig/lib/Twig/Extension/Staging.php create mode 100644 core/vendor/twig/twig/lib/Twig/FilterCallableInterface.php create mode 100644 core/vendor/twig/twig/lib/Twig/FunctionCallableInterface.php create mode 100644 core/vendor/twig/twig/lib/Twig/Node/Expression/Call.php create mode 100644 core/vendor/twig/twig/lib/Twig/SimpleFilter.php create mode 100644 core/vendor/twig/twig/lib/Twig/SimpleFunction.php create mode 100644 core/vendor/twig/twig/lib/Twig/SimpleTest.php create mode 100644 core/vendor/twig/twig/lib/Twig/Test.php create mode 100644 core/vendor/twig/twig/lib/Twig/TestCallableInterface.php delete mode 100644 core/vendor/twig/twig/package.xml.tpl create mode 100644 core/vendor/twig/twig/test/Twig/Tests/Fixtures/expressions/ternary_operator_noelse.test create mode 100644 core/vendor/twig/twig/test/Twig/Tests/Fixtures/expressions/ternary_operator_nothen.test create mode 100644 core/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/date_namedargs.test create mode 100644 core/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/date_namedargs.test create mode 100644 core/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/include/basic.test create mode 100644 core/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/include/expression.test create mode 100644 core/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/include/ignore_missing.test create mode 100644 core/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/include/missing.test create mode 100644 core/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/include/missing_nested.test create mode 100644 core/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/include/sandbox.test create mode 100644 core/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/include/template_instance.test create mode 100644 core/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/include/templates_as_array.test create mode 100644 core/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/include/with_context.test create mode 100644 core/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/include/with_variables.test create mode 100644 core/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/range.test create mode 100644 core/vendor/twig/twig/test/Twig/Tests/Fixtures/macros/default_values.test create mode 100644 core/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/for/loop_not_defined.test create mode 100644 core/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/for/loop_not_defined_cond.test create mode 100644 core/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/raw/mixed_usage_with_raw.test create mode 100644 core/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/verbatim/basic.test create mode 100644 core/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/verbatim/mixed_usage_with_raw.test create mode 100644 core/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/verbatim/whitespace_control.test create mode 100644 core/vendor/twig/twig/test/Twig/Tests/Node/Expression/PHP53/FilterInclude.php create mode 100644 core/vendor/twig/twig/test/Twig/Tests/Node/Expression/PHP53/FunctionInclude.php create mode 100644 core/vendor/twig/twig/test/Twig/Tests/Node/Expression/PHP53/TestInclude.php diff --git a/core/composer.json b/core/composer.json index 459c00c328ce..ac9048000103 100644 --- a/core/composer.json +++ b/core/composer.json @@ -3,21 +3,21 @@ "description": "Drupal is an open source content management platform powering millions of websites and applications.", "license": "GPL-2.0+", "require": { - "symfony/class-loader": "<2.4", - "symfony/dependency-injection": "<2.4", - "symfony/event-dispatcher": "<2.4", - "symfony/http-foundation": "<2.4", - "symfony/http-kernel": "<2.4", - "symfony/routing": "<2.4", + "symfony/class-loader": "2.2.0-BETA2", + "symfony/dependency-injection": "2.2.0-BETA2", + "symfony/event-dispatcher": "2.2.0-BETA2", + "symfony/http-foundation": "2.2.0-BETA2", + "symfony/http-kernel": "2.2.0-BETA2", + "symfony/routing": "2.2.0-BETA2", "symfony/serializer": "2.2.0-BETA2", - "symfony/validator": "<2.4", - "symfony/yaml": "<2.4", - "twig/twig": "1.*@stable", - "doctrine/common": "2.3.*@stable", - "guzzle/http": "3.1.*@stable", - "kriswallsmith/assetic": "1.1.*@alpha", + "symfony/validator": "2.2.0-BETA2", + "symfony/yaml": "2.2.0-BETA2", + "twig/twig": "1.12.1", + "doctrine/common": "2.3.0", + "guzzle/http": "3.1.0", + "kriswallsmith/assetic": "1.1.0-alpha1", "symfony-cmf/routing": "dev-master#ea4a10", - "easyrdf/easyrdf": "dev-master" + "easyrdf/easyrdf": "0.8.0-beta.1" }, "minimum-stability": "dev" } diff --git a/core/composer.lock b/core/composer.lock index 6eb40a1e3e47..6709d12ebb0e 100644 --- a/core/composer.lock +++ b/core/composer.lock @@ -1,5 +1,5 @@ { - "hash": "c087560024f328e26e2ed57c9b2aa703", + "hash": "ab5b183002f04155958ac5b57ed29032", "packages": [ { "name": "doctrine/common", @@ -56,7 +56,7 @@ { "name": "Johannes Schmitt", "email": "schmittjoh@gmail.com", - "homepage": "http://jmsyst.com", + "homepage": "https://github.com/schmittjoh", "role": "Developer of wrapped JMSSerializerBundle" } ], @@ -72,16 +72,16 @@ }, { "name": "easyrdf/easyrdf", - "version": "dev-master", + "version": "0.8.0-beta.1", "source": { "type": "git", "url": "git://github.com/njh/easyrdf.git", - "reference": "d1c363bd04cd55169fbefe52328e86031c6db3a2" + "reference": "0.8.0-beta.1" }, "dist": { "type": "zip", - "url": "https://github.com/njh/easyrdf/archive/d1c363bd04cd55169fbefe52328e86031c6db3a2.zip", - "reference": "d1c363bd04cd55169fbefe52328e86031c6db3a2", + "url": "https://github.com/njh/easyrdf/archive/0.8.0-beta.1.zip", + "reference": "0.8.0-beta.1", "shasum": "" }, "require": { @@ -95,7 +95,7 @@ "squizlabs/php_codesniffer": ">=1.4.3", "sami/sami": "dev-master" }, - "time": "2013-01-13 01:20:04", + "time": "2013-01-18 15:54:28", "type": "library", "autoload": { "psr-0": { @@ -378,6 +378,44 @@ "minification" ] }, + { + "name": "psr/log", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/log", + "reference": "1.0.0" + }, + "dist": { + "type": "zip", + "url": "https://github.com/php-fig/log/archive/1.0.0.zip", + "reference": "1.0.0", + "shasum": "" + }, + "time": "2012-12-21 11:40:51", + "type": "library", + "autoload": { + "psr-0": { + "Psr\\Log\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interface for logging libraries", + "keywords": [ + "log", + "psr", + "psr-3" + ] + }, { "name": "symfony-cmf/routing", "version": "dev-master", @@ -389,7 +427,7 @@ }, "dist": { "type": "zip", - "url": "https://github.com/symfony-cmf/Routing/archive/ea4a10dd971580a9a57a69397f165e25233ba667.zip", + "url": "https://api.github.com/repos/symfony-cmf/Routing/zipball/72df1da07b3c4edf16df169fb7987f504070fe0d", "reference": "ea4a10", "shasum": "" }, @@ -429,17 +467,17 @@ }, { "name": "symfony/class-loader", - "version": "dev-master", + "version": "v2.2.0-BETA2", "target-dir": "Symfony/Component/ClassLoader", "source": { "type": "git", "url": "https://github.com/symfony/ClassLoader", - "reference": "0730d0f8f99cfeafbc23271f1e87f54da15f1e06" + "reference": "v2.2.0-BETA2" }, "dist": { "type": "zip", - "url": "https://github.com/symfony/ClassLoader/archive/0730d0f8f99cfeafbc23271f1e87f54da15f1e06.zip", - "reference": "0730d0f8f99cfeafbc23271f1e87f54da15f1e06", + "url": "https://github.com/symfony/ClassLoader/archive/v2.2.0-BETA2.zip", + "reference": "v2.2.0-BETA2", "shasum": "" }, "require": { @@ -448,7 +486,7 @@ "require-dev": { "symfony/finder": "2.2.*" }, - "time": "2013-01-04 16:58:00", + "time": "2013-01-23 20:21:00", "type": "library", "extra": { "branch-alias": { @@ -479,17 +517,17 @@ }, { "name": "symfony/dependency-injection", - "version": "dev-master", + "version": "v2.2.0-BETA2", "target-dir": "Symfony/Component/DependencyInjection", "source": { "type": "git", "url": "https://github.com/symfony/DependencyInjection", - "reference": "13b47742e1ef22aed78132e5e0930d28571142a4" + "reference": "v2.2.0-BETA2" }, "dist": { "type": "zip", - "url": "https://github.com/symfony/DependencyInjection/archive/13b47742e1ef22aed78132e5e0930d28571142a4.zip", - "reference": "13b47742e1ef22aed78132e5e0930d28571142a4", + "url": "https://github.com/symfony/DependencyInjection/archive/v2.2.0-BETA2.zip", + "reference": "v2.2.0-BETA2", "shasum": "" }, "require": { @@ -503,7 +541,7 @@ "symfony/yaml": "2.2.*", "symfony/config": "2.2.*" }, - "time": "2013-01-04 16:58:00", + "time": "2013-01-23 20:21:00", "type": "library", "extra": { "branch-alias": { @@ -534,17 +572,17 @@ }, { "name": "symfony/event-dispatcher", - "version": "dev-master", + "version": "v2.2.0-BETA2", "target-dir": "Symfony/Component/EventDispatcher", "source": { "type": "git", "url": "https://github.com/symfony/EventDispatcher", - "reference": "0fcc9fa82fa3ea7ec2605af2e8137698fbaca3dc" + "reference": "v2.2.0-BETA2" }, "dist": { "type": "zip", - "url": "https://github.com/symfony/EventDispatcher/archive/0fcc9fa82fa3ea7ec2605af2e8137698fbaca3dc.zip", - "reference": "0fcc9fa82fa3ea7ec2605af2e8137698fbaca3dc", + "url": "https://github.com/symfony/EventDispatcher/archive/v2.2.0-BETA2.zip", + "reference": "v2.2.0-BETA2", "shasum": "" }, "require": { @@ -557,7 +595,7 @@ "symfony/dependency-injection": "2.2.*", "symfony/http-kernel": "2.2.*" }, - "time": "2013-01-04 17:02:19", + "time": "2013-01-17 15:25:59", "type": "library", "extra": { "branch-alias": { @@ -588,23 +626,23 @@ }, { "name": "symfony/http-foundation", - "version": "dev-master", + "version": "v2.2.0-BETA2", "target-dir": "Symfony/Component/HttpFoundation", "source": { "type": "git", "url": "https://github.com/symfony/HttpFoundation", - "reference": "5aa0119417f1fc8de7513d9432dd2f43f9d9e97b" + "reference": "v2.2.0-BETA2" }, "dist": { "type": "zip", - "url": "https://github.com/symfony/HttpFoundation/archive/5aa0119417f1fc8de7513d9432dd2f43f9d9e97b.zip", - "reference": "5aa0119417f1fc8de7513d9432dd2f43f9d9e97b", + "url": "https://github.com/symfony/HttpFoundation/archive/v2.2.0-BETA2.zip", + "reference": "v2.2.0-BETA2", "shasum": "" }, "require": { "php": ">=5.3.3" }, - "time": "2013-01-04 17:02:19", + "time": "2013-01-21 16:56:55", "type": "library", "extra": { "branch-alias": { @@ -638,23 +676,24 @@ }, { "name": "symfony/http-kernel", - "version": "dev-master", + "version": "v2.2.0-BETA2", "target-dir": "Symfony/Component/HttpKernel", "source": { "type": "git", "url": "https://github.com/symfony/HttpKernel", - "reference": "ce164c088666b80ffc116173065d504055414137" + "reference": "v2.2.0-BETA2" }, "dist": { "type": "zip", - "url": "https://github.com/symfony/HttpKernel/archive/ce164c088666b80ffc116173065d504055414137.zip", - "reference": "ce164c088666b80ffc116173065d504055414137", + "url": "https://github.com/symfony/HttpKernel/archive/v2.2.0-BETA2.zip", + "reference": "v2.2.0-BETA2", "shasum": "" }, "require": { "php": ">=5.3.3", "symfony/event-dispatcher": "2.2.*", - "symfony/http-foundation": "2.2.*" + "symfony/http-foundation": "2.2.*", + "psr/log": ">=1.0,<2.0" }, "require-dev": { "symfony/browser-kit": "2.2.*", @@ -675,7 +714,7 @@ "symfony/dependency-injection": "2.2.*", "symfony/finder": "2.2.*" }, - "time": "2013-01-04 16:58:00", + "time": "2013-01-24 07:15:19", "type": "library", "extra": { "branch-alias": { @@ -711,18 +750,18 @@ "source": { "type": "git", "url": "https://github.com/symfony/Process", - "reference": "058ae5038a9623fa64b120a2d10ba81f1ade05c7" + "reference": "v2.1.7" }, "dist": { "type": "zip", - "url": "https://github.com/symfony/Process/archive/058ae5038a9623fa64b120a2d10ba81f1ade05c7.zip", - "reference": "058ae5038a9623fa64b120a2d10ba81f1ade05c7", + "url": "https://api.github.com/repos/symfony/Process/zipball/v2.1.7", + "reference": "v2.1.7", "shasum": "" }, "require": { "php": ">=5.3.3" }, - "time": "2012-12-06 10:00:55", + "time": "2013-01-16 09:27:54", "type": "library", "autoload": { "psr-0": { @@ -748,34 +787,35 @@ }, { "name": "symfony/routing", - "version": "dev-master", + "version": "v2.2.0-BETA2", "target-dir": "Symfony/Component/Routing", "source": { "type": "git", "url": "https://github.com/symfony/Routing", - "reference": "87a66890450658ccac99702ac5e4f002ece9e23e" + "reference": "v2.2.0-BETA2" }, "dist": { "type": "zip", - "url": "https://github.com/symfony/Routing/archive/87a66890450658ccac99702ac5e4f002ece9e23e.zip", - "reference": "87a66890450658ccac99702ac5e4f002ece9e23e", + "url": "https://github.com/symfony/Routing/archive/v2.2.0-BETA2.zip", + "reference": "v2.2.0-BETA2", "shasum": "" }, "require": { "php": ">=5.3.3" }, "require-dev": { - "doctrine/common": ">=2.2,<2.4-dev", "symfony/config": "2.2.*", "symfony/yaml": "2.2.*", - "symfony/http-kernel": "2.2.*" + "symfony/http-kernel": "2.2.*", + "doctrine/common": ">=2.2,<2.4-dev", + "psr/log": ">=1.0,<2.0" }, "suggest": { - "doctrine/common": ">=2.2,<2.4-dev", "symfony/config": "2.2.*", - "symfony/yaml": "2.2.*" + "symfony/yaml": "2.2.*", + "doctrine/common": ">=2.2,<2.4-dev" }, - "time": "2012-12-28 13:21:48", + "time": "2013-01-21 16:57:32", "type": "library", "extra": { "branch-alias": { @@ -853,7 +893,7 @@ }, { "name": "symfony/translation", - "version": "dev-master", + "version": "2.2.x-dev", "target-dir": "Symfony/Component/Translation", "source": { "type": "git", @@ -862,7 +902,7 @@ }, "dist": { "type": "zip", - "url": "https://github.com/symfony/Translation/archive/v2.2.0-BETA2.zip", + "url": "https://api.github.com/repos/symfony/Translation/zipball/v2.2.0-BETA2", "reference": "v2.2.0-BETA2", "shasum": "" }, @@ -908,17 +948,17 @@ }, { "name": "symfony/validator", - "version": "dev-master", + "version": "v2.2.0-BETA2", "target-dir": "Symfony/Component/Validator", "source": { "type": "git", "url": "https://github.com/symfony/Validator", - "reference": "f764b2e61c51c45f93bd4c9fe933e6a66928d2d3" + "reference": "v2.2.0-BETA2" }, "dist": { "type": "zip", - "url": "https://github.com/symfony/Validator/archive/f764b2e61c51c45f93bd4c9fe933e6a66928d2d3.zip", - "reference": "f764b2e61c51c45f93bd4c9fe933e6a66928d2d3", + "url": "https://github.com/symfony/Validator/archive/v2.2.0-BETA2.zip", + "reference": "v2.2.0-BETA2", "shasum": "" }, "require": { @@ -937,7 +977,7 @@ "symfony/yaml": "2.2.*", "symfony/config": "2.2.*" }, - "time": "2013-01-24 10:00:40", + "time": "2013-01-21 16:57:12", "type": "library", "extra": { "branch-alias": { @@ -968,23 +1008,23 @@ }, { "name": "symfony/yaml", - "version": "dev-master", + "version": "v2.2.0-BETA2", "target-dir": "Symfony/Component/Yaml", "source": { "type": "git", "url": "https://github.com/symfony/Yaml", - "reference": "365b4df7802b9bb93084d2cc9a51fe88b488f956" + "reference": "v2.2.0-BETA2" }, "dist": { "type": "zip", - "url": "https://github.com/symfony/Yaml/archive/365b4df7802b9bb93084d2cc9a51fe88b488f956.zip", - "reference": "365b4df7802b9bb93084d2cc9a51fe88b488f956", + "url": "https://github.com/symfony/Yaml/archive/v2.2.0-BETA2.zip", + "reference": "v2.2.0-BETA2", "shasum": "" }, "require": { "php": ">=5.3.3" }, - "time": "2012-12-19 07:09:49", + "time": "2013-01-23 20:21:00", "type": "library", "extra": { "branch-alias": { @@ -1015,26 +1055,26 @@ }, { "name": "twig/twig", - "version": "v1.11.1", + "version": "v1.12.1", "source": { "type": "git", "url": "git://github.com/fabpot/Twig.git", - "reference": "v1.11.1" + "reference": "v1.12.1" }, "dist": { "type": "zip", - "url": "https://github.com/fabpot/Twig/archive/v1.11.1.zip", - "reference": "v1.11.1", + "url": "https://github.com/fabpot/Twig/archive/v1.12.1.zip", + "reference": "v1.12.1", "shasum": "" }, "require": { "php": ">=5.2.4" }, - "time": "2012-11-11 17:17:59", + "time": "2013-01-15 20:03:52", "type": "library", "extra": { "branch-alias": { - "dev-master": "1.11-dev" + "dev-master": "1.12-dev" } }, "autoload": { @@ -1069,12 +1109,17 @@ ], "minimum-stability": "dev", "stability-flags": { + "symfony/class-loader": 10, + "symfony/dependency-injection": 10, + "symfony/event-dispatcher": 10, + "symfony/http-foundation": 10, + "symfony/http-kernel": 10, + "symfony/routing": 10, "symfony/serializer": 10, - "twig/twig": 0, - "doctrine/common": 0, - "guzzle/http": 0, + "symfony/validator": 10, + "symfony/yaml": 10, "kriswallsmith/assetic": 15, "symfony-cmf/routing": 20, - "easyrdf/easyrdf": 20 + "easyrdf/easyrdf": 10 } } diff --git a/core/lib/Drupal/Core/CoreBundle.php b/core/lib/Drupal/Core/CoreBundle.php index 16faeef14d8f..aebb51444ebe 100644 --- a/core/lib/Drupal/Core/CoreBundle.php +++ b/core/lib/Drupal/Core/CoreBundle.php @@ -118,8 +118,7 @@ public function build(ContainerBuilder $container) { // object and get reconstructed when the request object changes (e.g., // during a subrequest). $container->addScope(new Scope('request')); - $container->register('request', 'Symfony\Component\HttpFoundation\Request') - ->setSynthetic(TRUE); + $container->register('request', 'Symfony\Component\HttpFoundation\Request'); $container->register('event_dispatcher', 'Symfony\Component\EventDispatcher\ContainerAwareEventDispatcher') ->addArgument(new Reference('service_container')); diff --git a/core/lib/Drupal/Core/Routing/CompiledRoute.php b/core/lib/Drupal/Core/Routing/CompiledRoute.php index b457afd17a61..cd8c74b1594e 100644 --- a/core/lib/Drupal/Core/Routing/CompiledRoute.php +++ b/core/lib/Drupal/Core/Routing/CompiledRoute.php @@ -67,17 +67,17 @@ class CompiledRoute extends SymfonyCompiledRoute { * An array of tokens to use to generate URL for this route * @param array $pathVariables * An array of path variables - * @param string|null $hostnameRegex - * Hostname regex - * @param array $hostnameTokens - * Hostname tokens - * @param array $hostnameVariables - * An array of hostname 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 hostname patterns) + * An array of variables (variables defined in the path and in the host patterns) */ - public function __construct(Route $route, $fit, $pattern_outline, $num_parts, $staticPrefix, $regex, array $tokens, array $pathVariables, $hostnameRegex = null, array $hostnameTokens = array(), array $hostnameVariables = array(), array $variables = array()) { - parent::__construct($staticPrefix, $regex, $tokens, $pathVariables, $hostnameRegex, $hostnameTokens, $hostnameVariables, $variables); + public function __construct(Route $route, $fit, $pattern_outline, $num_parts, $staticPrefix, $regex, array $tokens, array $pathVariables, $hostRegex = null, array $hostTokens = array(), array $hostVariables = array(), array $variables = array()) { + parent::__construct($staticPrefix, $regex, $tokens, $pathVariables, $hostRegex, $hostTokens, $hostVariables, $variables); $this->route = $route; $this->fit = $fit; diff --git a/core/lib/Drupal/Core/Routing/RouteCompiler.php b/core/lib/Drupal/Core/Routing/RouteCompiler.php index c71c5cae27fc..bd6c7b400d0f 100644 --- a/core/lib/Drupal/Core/Routing/RouteCompiler.php +++ b/core/lib/Drupal/Core/Routing/RouteCompiler.php @@ -40,14 +40,14 @@ class RouteCompiler extends SymfonyRouteCompiler implements RouteCompilerInterfa * @return \Drupal\Core\Routing\CompiledRoute * A CompiledRoute instance. */ - public function compile(Route $route) { + public static function compile(Route $route) { $symfony_compiled = parent::compile($route); // The Drupal-specific compiled information. - $stripped_path = $this->getPathWithoutDefaults($route); - $fit = $this->getFit($stripped_path); - $pattern_outline = $this->getPatternOutline($stripped_path); + $stripped_path = static::getPathWithoutDefaults($route); + $fit = static::getFit($stripped_path); + $pattern_outline = static::getPatternOutline($stripped_path); $num_parts = count(explode('/', trim($pattern_outline, '/'))); return new CompiledRoute( @@ -60,9 +60,9 @@ public function compile(Route $route) { $symfony_compiled->getRegex(), $symfony_compiled->getTokens(), $symfony_compiled->getPathVariables(), - $symfony_compiled->getHostnameRegex(), - $symfony_compiled->getHostnameTokens(), - $symfony_compiled->getHostnameVariables(), + $symfony_compiled->getHostRegex(), + $symfony_compiled->getHostTokens(), + $symfony_compiled->getHostVariables(), $symfony_compiled->getVariables() ); } @@ -79,7 +79,7 @@ public function compile(Route $route) { * @return string * The path pattern outline. */ - public function getPatternOutline($path) { + public static function getPatternOutline($path) { return preg_replace('#\{\w+\}#', '%', $path); } @@ -92,7 +92,7 @@ public function getPatternOutline($path) { * @return int * The fitness of the path, as an integer. */ - public function getFit($path) { + public static function getFit($path) { $parts = explode('/', trim($path, '/'), static::MAX_PARTS); $number_parts = count($parts); // We store the highest index of parts here to save some work in the fit @@ -124,7 +124,7 @@ public function getFit($path) { * @return string * The path string, stripped of placeholders that have default values. */ - protected function getPathWithoutDefaults(Route $route) { + protected static function getPathWithoutDefaults(Route $route) { $path = $route->getPattern(); $defaults = $route->getDefaults(); diff --git a/core/vendor/autoload.php b/core/vendor/autoload.php index 6842a6afc74b..299fea1dd558 100644 --- a/core/vendor/autoload.php +++ b/core/vendor/autoload.php @@ -4,4 +4,4 @@ require_once __DIR__ . '/composer' . '/autoload_real.php'; -return ComposerAutoloaderInit4166b4dc5e0c1c9d89ac8e8f9eefcd74::getLoader(); +return ComposerAutoloaderInitf05567eba27abe19ce0204f90ff18248::getLoader(); diff --git a/core/vendor/composer/autoload_namespaces.php b/core/vendor/composer/autoload_namespaces.php index 9d2667381be4..54b2551e7bcf 100644 --- a/core/vendor/composer/autoload_namespaces.php +++ b/core/vendor/composer/autoload_namespaces.php @@ -19,6 +19,7 @@ 'Symfony\\Component\\DependencyInjection\\' => $vendorDir . '/symfony/dependency-injection/', 'Symfony\\Component\\ClassLoader\\' => $vendorDir . '/symfony/class-loader/', 'Symfony\\Cmf\\Component\\Routing' => $vendorDir . '/symfony-cmf/routing/', + 'Psr\\Log\\' => $vendorDir . '/psr/log/', 'Guzzle\\Stream' => $vendorDir . '/guzzle/stream/', 'Guzzle\\Parser' => $vendorDir . '/guzzle/parser/', 'Guzzle\\Http' => $vendorDir . '/guzzle/http/', diff --git a/core/vendor/composer/autoload_real.php b/core/vendor/composer/autoload_real.php index c5a6d374c2de..b67069eff28c 100644 --- a/core/vendor/composer/autoload_real.php +++ b/core/vendor/composer/autoload_real.php @@ -2,7 +2,7 @@ // autoload_real.php generated by Composer -class ComposerAutoloaderInit4166b4dc5e0c1c9d89ac8e8f9eefcd74 +class ComposerAutoloaderInitf05567eba27abe19ce0204f90ff18248 { private static $loader; @@ -19,9 +19,9 @@ public static function getLoader() return self::$loader; } - spl_autoload_register(array('ComposerAutoloaderInit4166b4dc5e0c1c9d89ac8e8f9eefcd74', 'loadClassLoader')); + spl_autoload_register(array('ComposerAutoloaderInitf05567eba27abe19ce0204f90ff18248', 'loadClassLoader')); self::$loader = $loader = new \Composer\Autoload\ClassLoader(); - spl_autoload_unregister(array('ComposerAutoloaderInit4166b4dc5e0c1c9d89ac8e8f9eefcd74', 'loadClassLoader')); + spl_autoload_unregister(array('ComposerAutoloaderInitf05567eba27abe19ce0204f90ff18248', 'loadClassLoader')); $vendorDir = dirname(__DIR__); $baseDir = dirname($vendorDir); diff --git a/core/vendor/composer/installed.json b/core/vendor/composer/installed.json index 35bd16bdcba7..5b3d732dd297 100644 --- a/core/vendor/composer/installed.json +++ b/core/vendor/composer/installed.json @@ -1,4 +1,55 @@ [ + { + "name": "twig/twig", + "version": "v1.12.1", + "version_normalized": "1.12.1.0", + "source": { + "type": "git", + "url": "git://github.com/fabpot/Twig.git", + "reference": "v1.12.1" + }, + "dist": { + "type": "zip", + "url": "https://github.com/fabpot/Twig/archive/v1.12.1.zip", + "reference": "v1.12.1", + "shasum": "" + }, + "require": { + "php": ">=5.2.4" + }, + "time": "2013-01-15 20:03:52", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.12-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-0": { + "Twig_": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Armin Ronacher", + "email": "armin.ronacher@active-4.com" + } + ], + "description": "Twig, the flexible, fast, and secure template language for PHP", + "homepage": "http://twig.sensiolabs.org", + "keywords": [ + "templating" + ] + }, { "name": "doctrine/common", "version": "2.3.0", @@ -56,7 +107,7 @@ { "name": "Johannes Schmitt", "email": "schmittjoh@gmail.com", - "homepage": "http://jmsyst.com", + "homepage": "https://github.com/schmittjoh", "role": "Developer of wrapped JMSSerializerBundle" } ], @@ -70,57 +121,6 @@ "persistence" ] }, - { - "name": "twig/twig", - "version": "v1.11.1", - "version_normalized": "1.11.1.0", - "source": { - "type": "git", - "url": "git://github.com/fabpot/Twig.git", - "reference": "v1.11.1" - }, - "dist": { - "type": "zip", - "url": "https://github.com/fabpot/Twig/archive/v1.11.1.zip", - "reference": "v1.11.1", - "shasum": "" - }, - "require": { - "php": ">=5.2.4" - }, - "time": "2012-11-11 17:17:59", - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.11-dev" - } - }, - "installation-source": "dist", - "autoload": { - "psr-0": { - "Twig_": "lib/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Armin Ronacher", - "email": "armin.ronacher@active-4.com" - } - ], - "description": "Twig, the flexible, fast, and secure template language for PHP", - "homepage": "http://twig.sensiolabs.org", - "keywords": [ - "templating" - ] - }, { "name": "symfony/process", "version": "2.1.x-dev", @@ -129,18 +129,18 @@ "source": { "type": "git", "url": "https://github.com/symfony/Process", - "reference": "058ae5038a9623fa64b120a2d10ba81f1ade05c7" + "reference": "v2.1.7" }, "dist": { "type": "zip", - "url": "https://github.com/symfony/Process/archive/058ae5038a9623fa64b120a2d10ba81f1ade05c7.zip", - "reference": "058ae5038a9623fa64b120a2d10ba81f1ade05c7", + "url": "https://api.github.com/repos/symfony/Process/zipball/v2.1.7", + "reference": "v2.1.7", "shasum": "" }, "require": { "php": ">=5.3.3" }, - "time": "2012-12-06 10:00:55", + "time": "2013-01-16 09:27:54", "type": "library", "installation-source": "source", "autoload": { @@ -229,38 +229,26 @@ ] }, { - "name": "symfony/class-loader", - "version": "dev-master", - "version_normalized": "9999999-dev", - "target-dir": "Symfony/Component/ClassLoader", + "name": "psr/log", + "version": "1.0.0", + "version_normalized": "1.0.0.0", "source": { "type": "git", - "url": "https://github.com/symfony/ClassLoader", - "reference": "0730d0f8f99cfeafbc23271f1e87f54da15f1e06" + "url": "https://github.com/php-fig/log", + "reference": "1.0.0" }, "dist": { "type": "zip", - "url": "https://github.com/symfony/ClassLoader/archive/0730d0f8f99cfeafbc23271f1e87f54da15f1e06.zip", - "reference": "0730d0f8f99cfeafbc23271f1e87f54da15f1e06", + "url": "https://github.com/php-fig/log/archive/1.0.0.zip", + "reference": "1.0.0", "shasum": "" }, - "require": { - "php": ">=5.3.3" - }, - "require-dev": { - "symfony/finder": "2.2.*" - }, - "time": "2013-01-04 16:58:00", + "time": "2012-12-21 11:40:51", "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.2-dev" - } - }, - "installation-source": "source", + "installation-source": "dist", "autoload": { "psr-0": { - "Symfony\\Component\\ClassLoader\\": "" + "Psr\\Log\\": "" } }, "notification-url": "https://packagist.org/downloads/", @@ -269,56 +257,51 @@ ], "authors": [ { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "http://symfony.com/contributors" + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" } ], - "description": "Symfony ClassLoader Component", - "homepage": "http://symfony.com" + "description": "Common interface for logging libraries", + "keywords": [ + "log", + "psr", + "psr-3" + ] }, { - "name": "symfony/dependency-injection", - "version": "dev-master", - "version_normalized": "9999999-dev", - "target-dir": "Symfony/Component/DependencyInjection", + "name": "symfony/http-foundation", + "version": "v2.2.0-BETA2", + "version_normalized": "2.2.0.0-beta2", + "target-dir": "Symfony/Component/HttpFoundation", "source": { "type": "git", - "url": "https://github.com/symfony/DependencyInjection", - "reference": "13b47742e1ef22aed78132e5e0930d28571142a4" + "url": "https://github.com/symfony/HttpFoundation", + "reference": "v2.2.0-BETA2" }, "dist": { "type": "zip", - "url": "https://github.com/symfony/DependencyInjection/archive/13b47742e1ef22aed78132e5e0930d28571142a4.zip", - "reference": "13b47742e1ef22aed78132e5e0930d28571142a4", + "url": "https://github.com/symfony/HttpFoundation/archive/v2.2.0-BETA2.zip", + "reference": "v2.2.0-BETA2", "shasum": "" }, "require": { "php": ">=5.3.3" }, - "require-dev": { - "symfony/yaml": "2.2.*", - "symfony/config": "2.2.*" - }, - "suggest": { - "symfony/yaml": "2.2.*", - "symfony/config": "2.2.*" - }, - "time": "2013-01-04 16:58:00", + "time": "2013-01-21 16:56:55", "type": "library", "extra": { "branch-alias": { "dev-master": "2.2-dev" } }, - "installation-source": "source", + "installation-source": "dist", "autoload": { "psr-0": { - "Symfony\\Component\\DependencyInjection\\": "" - } + "Symfony\\Component\\HttpFoundation\\": "" + }, + "classmap": [ + "Symfony/Component/HttpFoundation/Resources/stubs" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -334,23 +317,23 @@ "homepage": "http://symfony.com/contributors" } ], - "description": "Symfony DependencyInjection Component", + "description": "Symfony HttpFoundation Component", "homepage": "http://symfony.com" }, { "name": "symfony/event-dispatcher", - "version": "dev-master", - "version_normalized": "9999999-dev", + "version": "v2.2.0-BETA2", + "version_normalized": "2.2.0.0-beta2", "target-dir": "Symfony/Component/EventDispatcher", "source": { "type": "git", "url": "https://github.com/symfony/EventDispatcher", - "reference": "0fcc9fa82fa3ea7ec2605af2e8137698fbaca3dc" + "reference": "v2.2.0-BETA2" }, "dist": { "type": "zip", - "url": "https://github.com/symfony/EventDispatcher/archive/0fcc9fa82fa3ea7ec2605af2e8137698fbaca3dc.zip", - "reference": "0fcc9fa82fa3ea7ec2605af2e8137698fbaca3dc", + "url": "https://github.com/symfony/EventDispatcher/archive/v2.2.0-BETA2.zip", + "reference": "v2.2.0-BETA2", "shasum": "" }, "require": { @@ -363,14 +346,14 @@ "symfony/dependency-injection": "2.2.*", "symfony/http-kernel": "2.2.*" }, - "time": "2013-01-04 17:02:19", + "time": "2013-01-17 15:25:59", "type": "library", "extra": { "branch-alias": { "dev-master": "2.2-dev" } }, - "installation-source": "source", + "installation-source": "dist", "autoload": { "psr-0": { "Symfony\\Component\\EventDispatcher\\": "" @@ -393,78 +376,27 @@ "description": "Symfony EventDispatcher Component", "homepage": "http://symfony.com" }, - { - "name": "symfony/http-foundation", - "version": "dev-master", - "version_normalized": "9999999-dev", - "target-dir": "Symfony/Component/HttpFoundation", - "source": { - "type": "git", - "url": "https://github.com/symfony/HttpFoundation", - "reference": "5aa0119417f1fc8de7513d9432dd2f43f9d9e97b" - }, - "dist": { - "type": "zip", - "url": "https://github.com/symfony/HttpFoundation/archive/5aa0119417f1fc8de7513d9432dd2f43f9d9e97b.zip", - "reference": "5aa0119417f1fc8de7513d9432dd2f43f9d9e97b", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "time": "2013-01-04 17:02:19", - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.2-dev" - } - }, - "installation-source": "source", - "autoload": { - "psr-0": { - "Symfony\\Component\\HttpFoundation\\": "" - }, - "classmap": [ - "Symfony/Component/HttpFoundation/Resources/stubs" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "http://symfony.com/contributors" - } - ], - "description": "Symfony HttpFoundation Component", - "homepage": "http://symfony.com" - }, { "name": "symfony/http-kernel", - "version": "dev-master", - "version_normalized": "9999999-dev", + "version": "v2.2.0-BETA2", + "version_normalized": "2.2.0.0-beta2", "target-dir": "Symfony/Component/HttpKernel", "source": { "type": "git", "url": "https://github.com/symfony/HttpKernel", - "reference": "ce164c088666b80ffc116173065d504055414137" + "reference": "v2.2.0-BETA2" }, "dist": { "type": "zip", - "url": "https://github.com/symfony/HttpKernel/archive/ce164c088666b80ffc116173065d504055414137.zip", - "reference": "ce164c088666b80ffc116173065d504055414137", + "url": "https://github.com/symfony/HttpKernel/archive/v2.2.0-BETA2.zip", + "reference": "v2.2.0-BETA2", "shasum": "" }, "require": { "php": ">=5.3.3", "symfony/event-dispatcher": "2.2.*", - "symfony/http-foundation": "2.2.*" + "symfony/http-foundation": "2.2.*", + "psr/log": ">=1.0,<2.0" }, "require-dev": { "symfony/browser-kit": "2.2.*", @@ -485,14 +417,14 @@ "symfony/dependency-injection": "2.2.*", "symfony/finder": "2.2.*" }, - "time": "2013-01-04 16:58:00", + "time": "2013-01-24 07:15:19", "type": "library", "extra": { "branch-alias": { "dev-master": "2.2-dev" } }, - "installation-source": "source", + "installation-source": "dist", "autoload": { "psr-0": { "Symfony\\Component\\HttpKernel\\": "" @@ -517,42 +449,43 @@ }, { "name": "symfony/routing", - "version": "dev-master", - "version_normalized": "9999999-dev", + "version": "v2.2.0-BETA2", + "version_normalized": "2.2.0.0-beta2", "target-dir": "Symfony/Component/Routing", "source": { "type": "git", "url": "https://github.com/symfony/Routing", - "reference": "87a66890450658ccac99702ac5e4f002ece9e23e" + "reference": "v2.2.0-BETA2" }, "dist": { "type": "zip", - "url": "https://github.com/symfony/Routing/archive/87a66890450658ccac99702ac5e4f002ece9e23e.zip", - "reference": "87a66890450658ccac99702ac5e4f002ece9e23e", + "url": "https://github.com/symfony/Routing/archive/v2.2.0-BETA2.zip", + "reference": "v2.2.0-BETA2", "shasum": "" }, "require": { "php": ">=5.3.3" }, "require-dev": { - "doctrine/common": ">=2.2,<2.4-dev", "symfony/config": "2.2.*", "symfony/yaml": "2.2.*", - "symfony/http-kernel": "2.2.*" + "symfony/http-kernel": "2.2.*", + "doctrine/common": ">=2.2,<2.4-dev", + "psr/log": ">=1.0,<2.0" }, "suggest": { - "doctrine/common": ">=2.2,<2.4-dev", "symfony/config": "2.2.*", - "symfony/yaml": "2.2.*" + "symfony/yaml": "2.2.*", + "doctrine/common": ">=2.2,<2.4-dev" }, - "time": "2012-12-28 13:21:48", + "time": "2013-01-21 16:57:32", "type": "library", "extra": { "branch-alias": { "dev-master": "2.2-dev" } }, - "installation-source": "source", + "installation-source": "dist", "autoload": { "psr-0": { "Symfony\\Component\\Routing\\": "" @@ -576,35 +509,37 @@ "homepage": "http://symfony.com" }, { - "name": "symfony/yaml", + "name": "symfony-cmf/routing", "version": "dev-master", "version_normalized": "9999999-dev", - "target-dir": "Symfony/Component/Yaml", + "target-dir": "Symfony/Cmf/Component/Routing", "source": { "type": "git", - "url": "https://github.com/symfony/Yaml", - "reference": "365b4df7802b9bb93084d2cc9a51fe88b488f956" + "url": "https://github.com/symfony-cmf/Routing", + "reference": "ea4a10" }, "dist": { "type": "zip", - "url": "https://github.com/symfony/Yaml/archive/365b4df7802b9bb93084d2cc9a51fe88b488f956.zip", - "reference": "365b4df7802b9bb93084d2cc9a51fe88b488f956", + "url": "https://api.github.com/repos/symfony-cmf/Routing/zipball/72df1da07b3c4edf16df169fb7987f504070fe0d", + "reference": "ea4a10", "shasum": "" }, "require": { - "php": ">=5.3.3" + "php": ">=5.3.2", + "symfony/routing": ">=2.1,<2.3-dev", + "symfony/http-kernel": ">=2.1,<2.3-dev" }, - "time": "2012-12-19 07:09:49", + "time": "2013-01-24 16:09:01", "type": "library", "extra": { "branch-alias": { - "dev-master": "2.2-dev" + "dev-master": "1.0-dev" } }, "installation-source": "source", "autoload": { "psr-0": { - "Symfony\\Component\\Yaml\\": "" + "Symfony\\Cmf\\Component\\Routing": "" } }, "notification-url": "https://packagist.org/downloads/", @@ -613,94 +548,155 @@ ], "authors": [ { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "http://symfony.com/contributors" + "name": "Symfony CMF Community", + "homepage": "https://github.com/symfony-cmf/Routing/contributors" } ], - "description": "Symfony Yaml Component", - "homepage": "http://symfony.com" - }, - { - "name": "guzzle/common", - "version": "v3.1.0", - "version_normalized": "3.1.0.0", - "target-dir": "Guzzle/Common", + "description": "Extends the Symfony2 routing component for dynamic routes and chaining several routers", + "homepage": "http://cmf.symfony.com", + "keywords": [ + "database", + "routing" + ] + }, + { + "name": "easyrdf/easyrdf", + "version": "0.8.0-beta.1", + "version_normalized": "0.8.0.0-beta1", "source": { "type": "git", - "url": "git://github.com/guzzle/common.git", - "reference": "v3.1.0" + "url": "git://github.com/njh/easyrdf.git", + "reference": "0.8.0-beta.1" }, "dist": { "type": "zip", - "url": "https://github.com/guzzle/common/archive/v3.1.0.zip", - "reference": "v3.1.0", + "url": "https://github.com/njh/easyrdf/archive/0.8.0-beta.1.zip", + "reference": "0.8.0-beta.1", "shasum": "" }, "require": { - "php": ">=5.3.2", - "symfony/event-dispatcher": ">=2.1" + "php": ">=5.2.8" }, - "time": "2013-01-13 05:14:34", + "replace": { + "njh/easyrdf": "self.version" + }, + "require-dev": { + "phpunit/phpunit": ">=3.5.15", + "squizlabs/php_codesniffer": ">=1.4.3", + "sami/sami": "dev-master" + }, + "time": "2013-01-18 15:54:28", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-0": { + "EasyRdf_": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Nicholas Humfrey", + "email": "njh@aelius.com", + "homepage": "http://www.aelius.com/njh/", + "role": "Developer" + } + ], + "description": "EasyRdf is a PHP library designed to make it easy to consume and produce RDF.", + "homepage": "http://www.easyrdf.org/", + "keywords": [ + "rdfa", + "RDF", + "Semantic Web", + "Turtle", + "Linked Data" + ] + }, + { + "name": "symfony/class-loader", + "version": "v2.2.0-BETA2", + "version_normalized": "2.2.0.0-beta2", + "target-dir": "Symfony/Component/ClassLoader", + "source": { + "type": "git", + "url": "https://github.com/symfony/ClassLoader", + "reference": "v2.2.0-BETA2" + }, + "dist": { + "type": "zip", + "url": "https://github.com/symfony/ClassLoader/archive/v2.2.0-BETA2.zip", + "reference": "v2.2.0-BETA2", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "symfony/finder": "2.2.*" + }, + "time": "2013-01-23 20:21:00", "type": "library", "extra": { "branch-alias": { - "dev-master": "3.0-dev" + "dev-master": "2.2-dev" } }, "installation-source": "dist", "autoload": { "psr-0": { - "Guzzle\\Common": "" + "Symfony\\Component\\ClassLoader\\": "" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], - "description": "Common libraries used by Guzzle", - "homepage": "http://guzzlephp.org/", - "keywords": [ - "event", - "exception", - "common", - "collection" - ] + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "http://symfony.com/contributors" + } + ], + "description": "Symfony ClassLoader Component", + "homepage": "http://symfony.com" }, { - "name": "guzzle/stream", - "version": "v3.1.0", - "version_normalized": "3.1.0.0", - "target-dir": "Guzzle/Stream", + "name": "symfony/yaml", + "version": "v2.2.0-BETA2", + "version_normalized": "2.2.0.0-beta2", + "target-dir": "Symfony/Component/Yaml", "source": { "type": "git", - "url": "https://github.com/guzzle/stream", - "reference": "v3.1.0" + "url": "https://github.com/symfony/Yaml", + "reference": "v2.2.0-BETA2" }, "dist": { "type": "zip", - "url": "https://github.com/guzzle/stream/archive/v3.1.0.zip", - "reference": "v3.1.0", + "url": "https://github.com/symfony/Yaml/archive/v2.2.0-BETA2.zip", + "reference": "v2.2.0-BETA2", "shasum": "" }, "require": { - "php": ">=5.3.2", - "guzzle/common": "self.version" + "php": ">=5.3.3" }, - "time": "2012-12-07 16:45:11", + "time": "2013-01-23 20:21:00", "type": "library", "extra": { "branch-alias": { - "dev-master": "3.0-dev" + "dev-master": "2.2-dev" } }, "installation-source": "dist", "autoload": { "psr-0": { - "Guzzle\\Stream": "" + "Symfony\\Component\\Yaml\\": "" } }, "notification-url": "https://packagist.org/downloads/", @@ -709,99 +705,166 @@ ], "authors": [ { - "name": "Michael Dowling", - "email": "mtdowling@gmail.com", - "homepage": "https://github.com/mtdowling" + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "http://symfony.com/contributors" } ], - "description": "Guzzle stream wrapper component", - "homepage": "http://guzzlephp.org/", - "keywords": [ - "stream", - "Guzzle", - "component" - ] + "description": "Symfony Yaml Component", + "homepage": "http://symfony.com" }, { - "name": "guzzle/parser", - "version": "v3.1.0", - "version_normalized": "3.1.0.0", - "target-dir": "Guzzle/Parser", + "name": "symfony/translation", + "version": "2.2.x-dev", + "version_normalized": "2.2.9999999.9999999-dev", + "target-dir": "Symfony/Component/Translation", "source": { "type": "git", - "url": "git://github.com/guzzle/parser.git", - "reference": "v3.1.0" + "url": "https://github.com/symfony/Translation", + "reference": "v2.2.0-BETA2" }, "dist": { "type": "zip", - "url": "https://github.com/guzzle/parser/archive/v3.1.0.zip", - "reference": "v3.1.0", + "url": "https://api.github.com/repos/symfony/Translation/zipball/v2.2.0-BETA2", + "reference": "v2.2.0-BETA2", "shasum": "" }, "require": { - "php": ">=5.3.2" + "php": ">=5.3.3" }, - "time": "2013-01-12 21:43:21", + "require-dev": { + "symfony/config": "2.2.*", + "symfony/yaml": "2.2.*" + }, + "suggest": { + "symfony/config": "2.2.*", + "symfony/yaml": "2.2.*" + }, + "time": "2013-01-17 15:25:59", "type": "library", "extra": { "branch-alias": { - "dev-master": "3.0-dev" + "dev-master": "2.2-dev" + } + }, + "installation-source": "source", + "autoload": { + "psr-0": { + "Symfony\\Component\\Translation\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "http://symfony.com/contributors" + } + ], + "description": "Symfony Translation Component", + "homepage": "http://symfony.com" + }, + { + "name": "symfony/validator", + "version": "v2.2.0-BETA2", + "version_normalized": "2.2.0.0-beta2", + "target-dir": "Symfony/Component/Validator", + "source": { + "type": "git", + "url": "https://github.com/symfony/Validator", + "reference": "v2.2.0-BETA2" + }, + "dist": { + "type": "zip", + "url": "https://github.com/symfony/Validator/archive/v2.2.0-BETA2.zip", + "reference": "v2.2.0-BETA2", + "shasum": "" + }, + "require": { + "php": ">=5.3.3", + "symfony/translation": "2.2.*" + }, + "require-dev": { + "symfony/http-foundation": "2.2.*", + "symfony/locale": "2.2.*", + "symfony/yaml": "2.2.*", + "symfony/config": "2.2.*" + }, + "suggest": { + "doctrine/common": ">=2.1,<2.4-dev", + "symfony/http-foundation": "2.2.*", + "symfony/yaml": "2.2.*", + "symfony/config": "2.2.*" + }, + "time": "2013-01-21 16:57:12", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.2-dev" } }, "installation-source": "dist", "autoload": { "psr-0": { - "Guzzle\\Parser": "" + "Symfony\\Component\\Validator\\": "" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], - "description": "Interchangeable parsers used by Guzzle", - "homepage": "http://guzzlephp.org/", - "keywords": [ - "http", - "url", - "message", - "cookie", - "URI Template" - ] + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "http://symfony.com/contributors" + } + ], + "description": "Symfony Validator Component", + "homepage": "http://symfony.com" }, { - "name": "guzzle/http", - "version": "v3.1.0", - "version_normalized": "3.1.0.0", - "target-dir": "Guzzle/Http", + "name": "symfony/serializer", + "version": "v2.2.0-BETA2", + "version_normalized": "2.2.0.0-beta2", + "target-dir": "Symfony/Component/Serializer", "source": { "type": "git", - "url": "git://github.com/guzzle/http.git", - "reference": "v3.1.0" + "url": "https://github.com/symfony/Serializer", + "reference": "v2.2.0-BETA2" }, "dist": { "type": "zip", - "url": "https://github.com/guzzle/http/archive/v3.1.0.zip", - "reference": "v3.1.0", + "url": "https://github.com/symfony/Serializer/archive/v2.2.0-BETA2.zip", + "reference": "v2.2.0-BETA2", "shasum": "" }, "require": { - "php": ">=5.3.2", - "ext-curl": "*", - "guzzle/common": "self.version", - "guzzle/parser": "self.version", - "guzzle/stream": "self.version" + "php": ">=5.3.3" }, - "time": "2013-01-13 05:09:32", + "time": "2013-01-19 07:50:02", "type": "library", "extra": { "branch-alias": { - "dev-master": "3.0-dev" + "dev-master": "2.2-dev" } }, "installation-source": "dist", "autoload": { "psr-0": { - "Guzzle\\Http": "" + "Symfony\\Component\\Serializer\\": "" } }, "notification-url": "https://packagist.org/downloads/", @@ -810,166 +873,151 @@ ], "authors": [ { - "name": "Michael Dowling", - "email": "mtdowling@gmail.com", - "homepage": "https://github.com/mtdowling" + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "http://symfony.com/contributors" } ], - "description": "HTTP libraries used by Guzzle", - "homepage": "http://guzzlephp.org/", - "keywords": [ - "curl", - "http", - "http client", - "client", - "Guzzle" - ] + "description": "Symfony Serializer Component", + "homepage": "http://symfony.com" }, { - "name": "easyrdf/easyrdf", - "version": "dev-master", - "version_normalized": "9999999-dev", + "name": "symfony/dependency-injection", + "version": "v2.2.0-BETA2", + "version_normalized": "2.2.0.0-beta2", + "target-dir": "Symfony/Component/DependencyInjection", "source": { "type": "git", - "url": "git://github.com/njh/easyrdf.git", - "reference": "d1c363bd04cd55169fbefe52328e86031c6db3a2" + "url": "https://github.com/symfony/DependencyInjection", + "reference": "v2.2.0-BETA2" }, "dist": { "type": "zip", - "url": "https://github.com/njh/easyrdf/archive/d1c363bd04cd55169fbefe52328e86031c6db3a2.zip", - "reference": "d1c363bd04cd55169fbefe52328e86031c6db3a2", + "url": "https://github.com/symfony/DependencyInjection/archive/v2.2.0-BETA2.zip", + "reference": "v2.2.0-BETA2", "shasum": "" }, "require": { - "php": ">=5.2.8" - }, - "replace": { - "njh/easyrdf": "self.version" + "php": ">=5.3.3" }, "require-dev": { - "phpunit/phpunit": ">=3.5.15", - "squizlabs/php_codesniffer": ">=1.4.3", - "sami/sami": "dev-master" + "symfony/yaml": "2.2.*", + "symfony/config": "2.2.*" + }, + "suggest": { + "symfony/yaml": "2.2.*", + "symfony/config": "2.2.*" }, - "time": "2013-01-13 01:20:04", + "time": "2013-01-23 20:21:00", "type": "library", - "installation-source": "source", + "extra": { + "branch-alias": { + "dev-master": "2.2-dev" + } + }, + "installation-source": "dist", "autoload": { "psr-0": { - "EasyRdf_": "lib/" + "Symfony\\Component\\DependencyInjection\\": "" } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { - "name": "Nicholas Humfrey", - "email": "njh@aelius.com", - "homepage": "http://www.aelius.com/njh/", - "role": "Developer" + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "http://symfony.com/contributors" } ], - "description": "EasyRdf is a PHP library designed to make it easy to consume and produce RDF.", - "homepage": "http://www.easyrdf.org/", - "keywords": [ - "rdfa", - "RDF", - "Semantic Web", - "Turtle", - "Linked Data" - ] + "description": "Symfony DependencyInjection Component", + "homepage": "http://symfony.com" }, { - "name": "symfony-cmf/routing", - "version": "dev-master", - "version_normalized": "9999999-dev", - "target-dir": "Symfony/Cmf/Component/Routing", + "name": "guzzle/common", + "version": "v3.1.0", + "version_normalized": "3.1.0.0", + "target-dir": "Guzzle/Common", "source": { "type": "git", - "url": "https://github.com/symfony-cmf/Routing", - "reference": "ea4a10" + "url": "git://github.com/guzzle/common.git", + "reference": "v3.1.0" }, "dist": { "type": "zip", - "url": "https://github.com/symfony-cmf/Routing/archive/ea4a10dd971580a9a57a69397f165e25233ba667.zip", - "reference": "ea4a10", + "url": "https://github.com/guzzle/common/archive/v3.1.0.zip", + "reference": "v3.1.0", "shasum": "" }, "require": { "php": ">=5.3.2", - "symfony/routing": ">=2.1,<2.3-dev", - "symfony/http-kernel": ">=2.1,<2.3-dev" + "symfony/event-dispatcher": ">=2.1" }, - "time": "2013-01-21 20:33:16", + "time": "2013-01-13 05:14:34", "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0-dev" + "dev-master": "3.0-dev" } }, - "installation-source": "source", + "installation-source": "dist", "autoload": { "psr-0": { - "Symfony\\Cmf\\Component\\Routing": "" + "Guzzle\\Common": "" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], - "authors": [ - { - "name": "Symfony CMF Community", - "homepage": "https://github.com/symfony-cmf/Routing/contributors" - } - ], - "description": "Extends the Symfony2 routing component for dynamic routes and chaining several routers", - "homepage": "http://cmf.symfony.com", + "description": "Common libraries used by Guzzle", + "homepage": "http://guzzlephp.org/", "keywords": [ - "database", - "routing" + "event", + "exception", + "common", + "collection" ] }, { - "name": "symfony/translation", - "version": "dev-master", - "version_normalized": "9999999-dev", - "target-dir": "Symfony/Component/Translation", + "name": "guzzle/stream", + "version": "v3.1.0", + "version_normalized": "3.1.0.0", + "target-dir": "Guzzle/Stream", "source": { "type": "git", - "url": "https://github.com/symfony/Translation", - "reference": "v2.2.0-BETA2" + "url": "https://github.com/guzzle/stream", + "reference": "v3.1.0" }, "dist": { "type": "zip", - "url": "https://github.com/symfony/Translation/archive/v2.2.0-BETA2.zip", - "reference": "v2.2.0-BETA2", + "url": "https://github.com/guzzle/stream/archive/v3.1.0.zip", + "reference": "v3.1.0", "shasum": "" }, "require": { - "php": ">=5.3.3" - }, - "require-dev": { - "symfony/config": "2.2.*", - "symfony/yaml": "2.2.*" - }, - "suggest": { - "symfony/config": "2.2.*", - "symfony/yaml": "2.2.*" + "php": ">=5.3.2", + "guzzle/common": "self.version" }, - "time": "2013-01-17 15:25:59", + "time": "2012-12-07 16:45:11", "type": "library", "extra": { "branch-alias": { - "dev-master": "2.2-dev" + "dev-master": "3.0-dev" } }, - "installation-source": "source", + "installation-source": "dist", "autoload": { "psr-0": { - "Symfony\\Component\\Translation\\": "" + "Guzzle\\Stream": "" } }, "notification-url": "https://packagist.org/downloads/", @@ -978,109 +1026,99 @@ ], "authors": [ { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "http://symfony.com/contributors" + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" } ], - "description": "Symfony Translation Component", - "homepage": "http://symfony.com" + "description": "Guzzle stream wrapper component", + "homepage": "http://guzzlephp.org/", + "keywords": [ + "stream", + "Guzzle", + "component" + ] }, { - "name": "symfony/validator", - "version": "dev-master", - "version_normalized": "9999999-dev", - "target-dir": "Symfony/Component/Validator", + "name": "guzzle/parser", + "version": "v3.1.0", + "version_normalized": "3.1.0.0", + "target-dir": "Guzzle/Parser", "source": { "type": "git", - "url": "https://github.com/symfony/Validator", - "reference": "f764b2e61c51c45f93bd4c9fe933e6a66928d2d3" + "url": "git://github.com/guzzle/parser.git", + "reference": "v3.1.0" }, "dist": { "type": "zip", - "url": "https://github.com/symfony/Validator/archive/f764b2e61c51c45f93bd4c9fe933e6a66928d2d3.zip", - "reference": "f764b2e61c51c45f93bd4c9fe933e6a66928d2d3", + "url": "https://github.com/guzzle/parser/archive/v3.1.0.zip", + "reference": "v3.1.0", "shasum": "" }, "require": { - "php": ">=5.3.3", - "symfony/translation": "2.2.*" - }, - "require-dev": { - "symfony/http-foundation": "2.2.*", - "symfony/locale": "2.2.*", - "symfony/yaml": "2.2.*", - "symfony/config": "2.2.*" - }, - "suggest": { - "doctrine/common": ">=2.1,<2.4-dev", - "symfony/http-foundation": "2.2.*", - "symfony/yaml": "2.2.*", - "symfony/config": "2.2.*" + "php": ">=5.3.2" }, - "time": "2013-01-24 10:00:40", + "time": "2013-01-12 21:43:21", "type": "library", "extra": { "branch-alias": { - "dev-master": "2.2-dev" + "dev-master": "3.0-dev" } }, - "installation-source": "source", + "installation-source": "dist", "autoload": { "psr-0": { - "Symfony\\Component\\Validator\\": "" + "Guzzle\\Parser": "" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "http://symfony.com/contributors" - } - ], - "description": "Symfony Validator Component", - "homepage": "http://symfony.com" + "description": "Interchangeable parsers used by Guzzle", + "homepage": "http://guzzlephp.org/", + "keywords": [ + "http", + "url", + "message", + "cookie", + "URI Template" + ] }, { - "name": "symfony/serializer", - "version": "v2.2.0-BETA2", - "version_normalized": "2.2.0.0-beta2", - "target-dir": "Symfony/Component/Serializer", + "name": "guzzle/http", + "version": "v3.1.0", + "version_normalized": "3.1.0.0", + "target-dir": "Guzzle/Http", "source": { "type": "git", - "url": "https://github.com/symfony/Serializer", - "reference": "v2.2.0-BETA2" + "url": "git://github.com/guzzle/http.git", + "reference": "v3.1.0" }, "dist": { "type": "zip", - "url": "https://github.com/symfony/Serializer/archive/v2.2.0-BETA2.zip", - "reference": "v2.2.0-BETA2", + "url": "https://github.com/guzzle/http/archive/v3.1.0.zip", + "reference": "v3.1.0", "shasum": "" }, "require": { - "php": ">=5.3.3" + "php": ">=5.3.2", + "ext-curl": "*", + "guzzle/common": "self.version", + "guzzle/parser": "self.version", + "guzzle/stream": "self.version" }, - "time": "2013-01-19 07:50:02", + "time": "2013-01-13 05:09:32", "type": "library", "extra": { "branch-alias": { - "dev-master": "2.2-dev" + "dev-master": "3.0-dev" } }, "installation-source": "dist", "autoload": { "psr-0": { - "Symfony\\Component\\Serializer\\": "" + "Guzzle\\Http": "" } }, "notification-url": "https://packagist.org/downloads/", @@ -1089,15 +1127,19 @@ ], "authors": [ { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "http://symfony.com/contributors" + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" } ], - "description": "Symfony Serializer Component", - "homepage": "http://symfony.com" + "description": "HTTP libraries used by Guzzle", + "homepage": "http://guzzlephp.org/", + "keywords": [ + "curl", + "http", + "http client", + "client", + "Guzzle" + ] } ] diff --git a/core/vendor/easyrdf/easyrdf/.gitignore b/core/vendor/easyrdf/easyrdf/.gitignore deleted file mode 100644 index 83892d7ccbfb..000000000000 --- a/core/vendor/easyrdf/easyrdf/.gitignore +++ /dev/null @@ -1,9 +0,0 @@ -doap.rdf -docs -samicache -lib/arc/ -reports -*.tar.gz -vendor -composer.phar -composer.lock diff --git a/core/vendor/easyrdf/easyrdf/Makefile b/core/vendor/easyrdf/easyrdf/Makefile deleted file mode 100644 index fe453680f146..000000000000 --- a/core/vendor/easyrdf/easyrdf/Makefile +++ /dev/null @@ -1,136 +0,0 @@ -PACKAGE = easyrdf -VERSION = $(shell php -r "print json_decode(file_get_contents('composer.json'))->version;") -distdir = $(PACKAGE)-$(VERSION) -PHP = $(shell which php) -COMPOSER_FLAGS=--no-ansi --no-interaction -PHPUNIT = vendor/bin/phpunit -PHPUNIT_FLAGS = -c config/phpunit.xml -PHPCS = vendor/bin/phpcs -PHPCS_FLAGS = --standard=./config/phpcs_ruleset.xml --encoding=utf8 --extensions=php -SAMI = vendor/bin/sami.php - -EXAMPLE_FILES = examples/*.php -SOURCE_FILES = lib/EasyRdf.php \ - lib/EasyRdf/*.php \ - lib/EasyRdf/*/*.php -TEST_FILES = test/*/*Test.php \ - test/*/*/*Test.php -TEST_SUPPORT = Makefile test/cli_example_wrapper.php \ - test/TestHelper.php \ - test/EasyRdf/TestCase.php \ - test/EasyRdf/Http/MockClient.php \ - test/EasyRdf/Serialiser/NtriplesArray.php \ - test/fixtures/* -DOC_FILES = composer.json \ - doap.rdf \ - docs/api \ - README.md \ - LICENSE.md \ - CHANGELOG.md - -DISTFILES = $(EXAMPLE_FILES) $(SOURCE_FILES) $(TEST_FILES) \ - $(TEST_SUPPORT) $(DOC_FILES) - -.DEFAULT: help -all: help - -# TARGET:test Run all the PHPUnit tests -.PHONY: test -test: $(PHPUNIT) - mkdir -p reports - $(PHP) $(PHPUNIT) $(PHPUNIT_FLAGS) - -# TARGET:test-examples Run PHPUnit tests for each of the examples -.PHONY: test-examples -test-examples: $(PHPUNIT) - mkdir -p reports - $(PHP) $(PHPUNIT) $(PHPUNIT_FLAGS) --testsuite "EasyRdf Examples" - -# TARGET:test-lib Run PHPUnit tests for the library -.PHONY: test-lib -test-lib: $(PHPUNIT) - mkdir -p reports - $(PHP) $(PHPUNIT) $(PHPUNIT_FLAGS) --testsuite "EasyRdf Library" - -# TARGET:coverage Run the library tests and generate a code coverage report -.PHONY: coverage -coverage: $(PHPUNIT) - mkdir -p reports/coverage - $(PHP) $(PHPUNIT) $(PHPUNIT_FLAGS) --coverage-html ./reports/coverage --testsuite "EasyRdf Library" - -# TARGET:apidocs Generate HTML API documentation -.PHONY: apidocs -apidocs: $(SAMI) - $(PHP) $(SAMI) update config/sami.php -n -v --force - -docs/api: apidocs - -doap.rdf: doap.php composer.json - $(PHP) doap.php > doap.rdf - -# TARGET:cs Check the code style of the PHP source code -.PHONY: cs -cs: $(PHPCS) - $(PHPCS) $(PHPCS_FLAGS) lib test - -# TARGET:lint Perform basic PHP syntax check on all files -.PHONY: lint -lint: $(EXAMPLE_FILES) $(SOURCE_FILES) $(TEST_FILES) - @for file in $^; do \ - $(PHP) -l $$file || exit -1; \ - done - -# TARGET:dist Build tarball for distribution -.PHONY: dist -dist: $(distdir) - tar zcf $(distdir).tar.gz $(distdir) - rm -Rf $(distdir) - @echo "Created $(distdir).tar.gz" - -$(distdir): $(DISTFILES) - @for file in $^; do \ - dir=$(distdir)/`dirname "$$file"`; \ - test -d "$$dir" || mkdir -p "$$dir" || exit -1; \ - cp -Rfp "$$file" "$(distdir)/$$file" || exit -1; \ - done - -# TARGET:clean Delete any temporary and generated files -.PHONY: clean -clean: - -rm -Rf $(distdir) reports vendor - -rm -Rf docs/api samicache - -rm -f composer.phar composer.lock - -rm -f doap.rdf - -# TARGET:check-fixme Scan for files containing the words TODO or FIXME -.PHONY: check-fixme -check-fixme: - @git grep -n -E 'FIXME|TODO' || echo "No FIXME or TODO lines found." - -# TARGET:help You're looking at it! -.PHONY: help -help: - # Usage: - # make <target> [OPTION=value] - # - # Targets: - @egrep "^# TARGET:" [Mm]akefile | sed 's/^# TARGET:/# /' - # - # Options: - # PHP Path to php - - - -# Composer rules -composer.phar: - curl -s -z composer.phar -o composer.phar http://getcomposer.org/composer.phar - -composer-install: composer.phar - $(PHP) composer.phar $(COMPOSER_FLAGS) install --dev - -composer-update: clean composer.phar - $(PHP) composer.phar $(COMPOSER_FLAGS) update --dev - -vendor/bin/phpunit: composer-install -vendor/bin/phpcs: composer-install -vendor/bin/sami.php: composer-install diff --git a/core/vendor/easyrdf/easyrdf/README.md b/core/vendor/easyrdf/easyrdf/README.md index 3a71ccdda119..182b1a54a186 100644 --- a/core/vendor/easyrdf/easyrdf/README.md +++ b/core/vendor/easyrdf/easyrdf/README.md @@ -64,31 +64,6 @@ Features * Comes with a number of examples -Property Paths --------------- - -EasyRdf supports querying the data in a graph using basic property paths. -This is a small subset of the property paths described in [SPARQL 1.1 query language]. - - -You may use the caret character (^) to get an inverse property, for example: - - $person = $homepage->get('^foaf:homepage'); - -You can use the pipe character (|) to get alternate properties, for example: - - $title = $document->get('dc:title|dc11:title'); - -You can use a forward slash (/) to follow a property sequence, for example to get -the names of all my friends: - - $names = $me->all('foaf:knows/foaf:name'); - -Finally, in order to use a full property URI, enclose it in angle brackets: - - $name = $me->get('<http://xmlns.com/foaf/0.1/name>'); - - More Examples ------------- diff --git a/core/vendor/easyrdf/easyrdf/composer.json b/core/vendor/easyrdf/easyrdf/composer.json index 8ce254edec34..c93d98dcfa97 100644 --- a/core/vendor/easyrdf/easyrdf/composer.json +++ b/core/vendor/easyrdf/easyrdf/composer.json @@ -1,7 +1,7 @@ { "name": "easyrdf/easyrdf", "description": "EasyRdf is a PHP library designed to make it easy to consume and produce RDF.", - "version": "0.8.0", + "version": "0.8.0-beta.1", "type": "library", "keywords": ["RDF", "Semantic Web", "Linked Data", "Turtle", "RDFa"], "homepage": "http://www.easyrdf.org/", diff --git a/core/vendor/easyrdf/easyrdf/doap.php b/core/vendor/easyrdf/easyrdf/doap.php index 60274ff9ca01..ff9f190a48e9 100644 --- a/core/vendor/easyrdf/easyrdf/doap.php +++ b/core/vendor/easyrdf/easyrdf/doap.php @@ -1,9 +1,8 @@ <?php - set_include_path(get_include_path() . PATH_SEPARATOR . './lib/'); - require_once "EasyRdf.php"; + require_once "vendor/autoload.php"; // Load some properties from the composer file - $composer = json_decode(file_get_contents('composer.json')); + $composer = json_decode(file_get_contents(__DIR__."/composer.json")); // Start building up a RDF graph $doap = new EasyRdf_Graph($composer->homepage.'doap.rdf'); diff --git a/core/vendor/psr/log/.gitignore b/core/vendor/psr/log/.gitignore new file mode 100644 index 000000000000..22d0d82f8095 --- /dev/null +++ b/core/vendor/psr/log/.gitignore @@ -0,0 +1 @@ +vendor diff --git a/core/vendor/psr/log/LICENSE b/core/vendor/psr/log/LICENSE new file mode 100644 index 000000000000..474c952b4b50 --- /dev/null +++ b/core/vendor/psr/log/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2012 PHP Framework Interoperability Group + +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/core/vendor/psr/log/Psr/Log/AbstractLogger.php b/core/vendor/psr/log/Psr/Log/AbstractLogger.php new file mode 100644 index 000000000000..00f9034521b4 --- /dev/null +++ b/core/vendor/psr/log/Psr/Log/AbstractLogger.php @@ -0,0 +1,120 @@ +<?php + +namespace Psr\Log; + +/** + * This is a simple Logger implementation that other Loggers can inherit from. + * + * It simply delegates all log-level-specific methods to the `log` method to + * reduce boilerplate code that a simple Logger that does the same thing with + * messages regardless of the error level has to implement. + */ +abstract class AbstractLogger implements LoggerInterface +{ + /** + * System is unusable. + * + * @param string $message + * @param array $context + * @return null + */ + public function emergency($message, array $context = array()) + { + $this->log(LogLevel::EMERGENCY, $message, $context); + } + + /** + * Action must be taken immediately. + * + * Example: Entire website down, database unavailable, etc. This should + * trigger the SMS alerts and wake you up. + * + * @param string $message + * @param array $context + * @return null + */ + public function alert($message, array $context = array()) + { + $this->log(LogLevel::ALERT, $message, $context); + } + + /** + * Critical conditions. + * + * Example: Application component unavailable, unexpected exception. + * + * @param string $message + * @param array $context + * @return null + */ + public function critical($message, array $context = array()) + { + $this->log(LogLevel::CRITICAL, $message, $context); + } + + /** + * Runtime errors that do not require immediate action but should typically + * be logged and monitored. + * + * @param string $message + * @param array $context + * @return null + */ + public function error($message, array $context = array()) + { + $this->log(LogLevel::ERROR, $message, $context); + } + + /** + * Exceptional occurrences that are not errors. + * + * Example: Use of deprecated APIs, poor use of an API, undesirable things + * that are not necessarily wrong. + * + * @param string $message + * @param array $context + * @return null + */ + public function warning($message, array $context = array()) + { + $this->log(LogLevel::WARNING, $message, $context); + } + + /** + * Normal but significant events. + * + * @param string $message + * @param array $context + * @return null + */ + public function notice($message, array $context = array()) + { + $this->log(LogLevel::NOTICE, $message, $context); + } + + /** + * Interesting events. + * + * Example: User logs in, SQL logs. + * + * @param string $message + * @param array $context + * @return null + */ + public function info($message, array $context = array()) + { + $this->log(LogLevel::INFO, $message, $context); + } + + /** + * Detailed debug information. + * + * @param string $message + * @param array $context + * @return null + */ + public function debug($message, array $context = array()) + { + $this->log(LogLevel::DEBUG, $message, $context); + } +} diff --git a/core/vendor/psr/log/Psr/Log/InvalidArgumentException.php b/core/vendor/psr/log/Psr/Log/InvalidArgumentException.php new file mode 100644 index 000000000000..67f852d1dbc6 --- /dev/null +++ b/core/vendor/psr/log/Psr/Log/InvalidArgumentException.php @@ -0,0 +1,7 @@ +<?php + +namespace Psr\Log; + +class InvalidArgumentException extends \InvalidArgumentException +{ +} diff --git a/core/vendor/psr/log/Psr/Log/LogLevel.php b/core/vendor/psr/log/Psr/Log/LogLevel.php new file mode 100644 index 000000000000..e32c151cb195 --- /dev/null +++ b/core/vendor/psr/log/Psr/Log/LogLevel.php @@ -0,0 +1,18 @@ +<?php + +namespace Psr\Log; + +/** + * Describes log levels + */ +class LogLevel +{ + const EMERGENCY = 'emergency'; + const ALERT = 'alert'; + const CRITICAL = 'critical'; + const ERROR = 'error'; + const WARNING = 'warning'; + const NOTICE = 'notice'; + const INFO = 'info'; + const DEBUG = 'debug'; +} diff --git a/core/vendor/psr/log/Psr/Log/LoggerAwareInterface.php b/core/vendor/psr/log/Psr/Log/LoggerAwareInterface.php new file mode 100644 index 000000000000..2eebc4ebddb5 --- /dev/null +++ b/core/vendor/psr/log/Psr/Log/LoggerAwareInterface.php @@ -0,0 +1,17 @@ +<?php + +namespace Psr\Log; + +/** + * Describes a logger-aware instance + */ +interface LoggerAwareInterface +{ + /** + * Sets a logger instance on the object + * + * @param LoggerInterface $logger + * @return null + */ + public function setLogger(LoggerInterface $logger); +} diff --git a/core/vendor/psr/log/Psr/Log/LoggerAwareTrait.php b/core/vendor/psr/log/Psr/Log/LoggerAwareTrait.php new file mode 100644 index 000000000000..f087a3dac894 --- /dev/null +++ b/core/vendor/psr/log/Psr/Log/LoggerAwareTrait.php @@ -0,0 +1,22 @@ +<?php + +namespace Psr\Log; + +/** + * Basic Implementation of LoggerAwareInterface. + */ +trait LoggerAwareTrait +{ + /** @var LoggerInterface */ + protected $logger; + + /** + * Sets a logger. + * + * @param LoggerInterface $logger + */ + public function setLogger(LoggerInterface $logger) + { + $this->logger = $logger; + } +} diff --git a/core/vendor/psr/log/Psr/Log/LoggerInterface.php b/core/vendor/psr/log/Psr/Log/LoggerInterface.php new file mode 100644 index 000000000000..476bb962af78 --- /dev/null +++ b/core/vendor/psr/log/Psr/Log/LoggerInterface.php @@ -0,0 +1,114 @@ +<?php + +namespace Psr\Log; + +/** + * Describes a logger instance + * + * The message MUST be a string or object implementing __toString(). + * + * The message MAY contain placeholders in the form: {foo} where foo + * will be replaced by the context data in key "foo". + * + * The context array can contain arbitrary data, the only assumption that + * can be made by implementors is that if an Exception instance is given + * to produce a stack trace, it MUST be in a key named "exception". + * + * See https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-3-logger-interface.md + * for the full interface specification. + */ +interface LoggerInterface +{ + /** + * System is unusable. + * + * @param string $message + * @param array $context + * @return null + */ + public function emergency($message, array $context = array()); + + /** + * Action must be taken immediately. + * + * Example: Entire website down, database unavailable, etc. This should + * trigger the SMS alerts and wake you up. + * + * @param string $message + * @param array $context + * @return null + */ + public function alert($message, array $context = array()); + + /** + * Critical conditions. + * + * Example: Application component unavailable, unexpected exception. + * + * @param string $message + * @param array $context + * @return null + */ + public function critical($message, array $context = array()); + + /** + * Runtime errors that do not require immediate action but should typically + * be logged and monitored. + * + * @param string $message + * @param array $context + * @return null + */ + public function error($message, array $context = array()); + + /** + * Exceptional occurrences that are not errors. + * + * Example: Use of deprecated APIs, poor use of an API, undesirable things + * that are not necessarily wrong. + * + * @param string $message + * @param array $context + * @return null + */ + public function warning($message, array $context = array()); + + /** + * Normal but significant events. + * + * @param string $message + * @param array $context + * @return null + */ + public function notice($message, array $context = array()); + + /** + * Interesting events. + * + * Example: User logs in, SQL logs. + * + * @param string $message + * @param array $context + * @return null + */ + public function info($message, array $context = array()); + + /** + * Detailed debug information. + * + * @param string $message + * @param array $context + * @return null + */ + public function debug($message, array $context = array()); + + /** + * Logs with an arbitrary level. + * + * @param mixed $level + * @param string $message + * @param array $context + * @return null + */ + public function log($level, $message, array $context = array()); +} diff --git a/core/vendor/psr/log/Psr/Log/LoggerTrait.php b/core/vendor/psr/log/Psr/Log/LoggerTrait.php new file mode 100644 index 000000000000..5912496000b1 --- /dev/null +++ b/core/vendor/psr/log/Psr/Log/LoggerTrait.php @@ -0,0 +1,131 @@ +<?php + +namespace Psr\Log; + +/** + * This is a simple Logger trait that classes unable to extend AbstractLogger + * (because they extend another class, etc) can include. + * + * It simply delegates all log-level-specific methods to the `log` method to + * reduce boilerplate code that a simple Logger that does the same thing with + * messages regardless of the error level has to implement. + */ +trait LoggerTrait +{ + /** + * System is unusable. + * + * @param string $message + * @param array $context + * @return null + */ + public function emergency($message, array $context = array()) + { + $this->log(LogLevel::EMERGENCY, $message, $context); + } + + /** + * Action must be taken immediately. + * + * Example: Entire website down, database unavailable, etc. This should + * trigger the SMS alerts and wake you up. + * + * @param string $message + * @param array $context + * @return null + */ + public function alert($message, array $context = array()) + { + $this->log(LogLevel::ALERT, $message, $context); + } + + /** + * Critical conditions. + * + * Example: Application component unavailable, unexpected exception. + * + * @param string $message + * @param array $context + * @return null + */ + public function critical($message, array $context = array()) + { + $this->log(LogLevel::CRITICAL, $message, $context); + } + + /** + * Runtime errors that do not require immediate action but should typically + * be logged and monitored. + * + * @param string $message + * @param array $context + * @return null + */ + public function error($message, array $context = array()) + { + $this->log(LogLevel::ERROR, $message, $context); + } + + /** + * Exceptional occurrences that are not errors. + * + * Example: Use of deprecated APIs, poor use of an API, undesirable things + * that are not necessarily wrong. + * + * @param string $message + * @param array $context + * @return null + */ + public function warning($message, array $context = array()) + { + $this->log(LogLevel::WARNING, $message, $context); + } + + /** + * Normal but significant events. + * + * @param string $message + * @param array $context + * @return null + */ + public function notice($message, array $context = array()) + { + $this->log(LogLevel::NOTICE, $message, $context); + } + + /** + * Interesting events. + * + * Example: User logs in, SQL logs. + * + * @param string $message + * @param array $context + * @return null + */ + public function info($message, array $context = array()) + { + $this->log(LogLevel::INFO, $message, $context); + } + + /** + * Detailed debug information. + * + * @param string $message + * @param array $context + * @return null + */ + public function debug($message, array $context = array()) + { + $this->log(LogLevel::DEBUG, $message, $context); + } + + /** + * Logs with an arbitrary level. + * + * @param mixed $level + * @param string $message + * @param array $context + * @return null + */ + abstract public function log($level, $message, array $context = array()); +} diff --git a/core/vendor/psr/log/Psr/Log/NullLogger.php b/core/vendor/psr/log/Psr/Log/NullLogger.php new file mode 100644 index 000000000000..553a3c593ae5 --- /dev/null +++ b/core/vendor/psr/log/Psr/Log/NullLogger.php @@ -0,0 +1,27 @@ +<?php + +namespace Psr\Log; + +/** + * This Logger can be used to avoid conditional log calls + * + * Logging should always be optional, and if no logger is provided to your + * library creating a NullLogger instance to have something to throw logs at + * is a good way to avoid littering your code with `if ($this->logger) { }` + * blocks. + */ +class NullLogger extends AbstractLogger +{ + /** + * Logs with an arbitrary level. + * + * @param mixed $level + * @param string $message + * @param array $context + * @return null + */ + public function log($level, $message, array $context = array()) + { + // noop + } +} diff --git a/core/vendor/psr/log/Psr/Log/Test/LoggerInterfaceTest.php b/core/vendor/psr/log/Psr/Log/Test/LoggerInterfaceTest.php new file mode 100644 index 000000000000..a9328151112a --- /dev/null +++ b/core/vendor/psr/log/Psr/Log/Test/LoggerInterfaceTest.php @@ -0,0 +1,116 @@ +<?php + +namespace Psr\Log\Test; + +use Psr\Log\LogLevel; + +/** + * Provides a base test class for ensuring compliance with the LoggerInterface + * + * Implementors can extend the class and implement abstract methods to run this as part of their test suite + */ +abstract class LoggerInterfaceTest extends \PHPUnit_Framework_TestCase +{ + /** + * @return LoggerInterface + */ + abstract function getLogger(); + + /** + * This must return the log messages in order with a simple formatting: "<LOG LEVEL> <MESSAGE>" + * + * Example ->error('Foo') would yield "error Foo" + * + * @return string[] + */ + abstract function getLogs(); + + public function testImplements() + { + $this->assertInstanceOf('Psr\Log\LoggerInterface', $this->getLogger()); + } + + /** + * @dataProvider provideLevelsAndMessages + */ + public function testLogsAtAllLevels($level, $message) + { + $logger = $this->getLogger(); + $logger->{$level}($message, array('user' => 'Bob')); + $logger->log($level, $message, array('user' => 'Bob')); + + $expected = array( + $level.' message of level '.$level.' with context: Bob', + $level.' message of level '.$level.' with context: Bob', + ); + $this->assertEquals($expected, $this->getLogs()); + } + + public function provideLevelsAndMessages() + { + return array( + LogLevel::EMERGENCY => array(LogLevel::EMERGENCY, 'message of level emergency with context: {user}'), + LogLevel::ALERT => array(LogLevel::ALERT, 'message of level alert with context: {user}'), + LogLevel::CRITICAL => array(LogLevel::CRITICAL, 'message of level critical with context: {user}'), + LogLevel::ERROR => array(LogLevel::ERROR, 'message of level error with context: {user}'), + LogLevel::WARNING => array(LogLevel::WARNING, 'message of level warning with context: {user}'), + LogLevel::NOTICE => array(LogLevel::NOTICE, 'message of level notice with context: {user}'), + LogLevel::INFO => array(LogLevel::INFO, 'message of level info with context: {user}'), + LogLevel::DEBUG => array(LogLevel::DEBUG, 'message of level debug with context: {user}'), + ); + } + + /** + * @expectedException Psr\Log\InvalidArgumentException + */ + public function testThrowsOnInvalidLevel() + { + $logger = $this->getLogger(); + $logger->log('invalid level', 'Foo'); + } + + public function testContextReplacement() + { + $logger = $this->getLogger(); + $logger->info('{Message {nothing} {user} {foo.bar} a}', array('user' => 'Bob', 'foo.bar' => 'Bar')); + + $expected = array('info {Message {nothing} Bob Bar a}'); + $this->assertEquals($expected, $this->getLogs()); + } + + public function testObjectCastToString() + { + $dummy = $this->getMock('Psr\Log\Test\DummyTest', array('__toString')); + $dummy->expects($this->once()) + ->method('__toString') + ->will($this->returnValue('DUMMY')); + + $this->getLogger()->warning($dummy); + } + + public function testContextCanContainAnything() + { + $context = array( + 'bool' => true, + 'null' => null, + 'string' => 'Foo', + 'int' => 0, + 'float' => 0.5, + 'nested' => array('with object' => new DummyTest), + 'object' => new \DateTime, + 'resource' => fopen('php://memory', 'r'), + ); + + $this->getLogger()->warning('Crazy context data', $context); + } + + public function testContextExceptionKeyCanBeExceptionOrOtherValues() + { + $this->getLogger()->warning('Random message', array('exception' => 'oops')); + $this->getLogger()->critical('Uncaught Exception!', array('exception' => new \LogicException('Fail'))); + } +} + +class DummyTest +{ +} \ No newline at end of file diff --git a/core/vendor/psr/log/README.md b/core/vendor/psr/log/README.md new file mode 100644 index 000000000000..574bc1cb2a82 --- /dev/null +++ b/core/vendor/psr/log/README.md @@ -0,0 +1,45 @@ +PSR Log +======= + +This repository holds all interfaces/classes/traits related to +[PSR-3](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-3-logger-interface.md). + +Note that this is not a logger of its own. It is merely an interface that +describes a logger. See the specification for more details. + +Usage +----- + +If you need a logger, you can use the interface like this: + +```php +<?php + +use Psr\Log\LoggerInterface; + +class Foo +{ + private $logger; + + public function __construct(LoggerInterface $logger = null) + { + $this->logger = $logger; + } + + public function doSomething() + { + if ($this->logger) { + $this->logger->info('Doing work'); + } + + // do something useful + } +} +``` + +You can then pick one of the implementations of the interface to get a logger. + +If you want to implement the interface, you can require this package and +implement `Psr\Log\LoggerInterface` in your code. Please read the +[specification text](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-3-logger-interface.md) +for details. diff --git a/core/vendor/psr/log/composer.json b/core/vendor/psr/log/composer.json new file mode 100644 index 000000000000..6bdcc2194be9 --- /dev/null +++ b/core/vendor/psr/log/composer.json @@ -0,0 +1,17 @@ +{ + "name": "psr/log", + "description": "Common interface for logging libraries", + "keywords": ["psr", "psr-3", "log"], + "license": "MIT", + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "autoload": { + "psr-0": { + "Psr\\Log\\": "" + } + } +} diff --git a/core/vendor/symfony/class-loader/Symfony/Component/ClassLoader/.gitattributes b/core/vendor/symfony/class-loader/Symfony/Component/ClassLoader/.gitattributes deleted file mode 100644 index 80481513cff2..000000000000 --- a/core/vendor/symfony/class-loader/Symfony/Component/ClassLoader/.gitattributes +++ /dev/null @@ -1,2 +0,0 @@ -/Tests export-ignore -phpunit.xml.dist export-ignore diff --git a/core/vendor/symfony/class-loader/Symfony/Component/ClassLoader/DebugClassLoader.php b/core/vendor/symfony/class-loader/Symfony/Component/ClassLoader/DebugClassLoader.php index 911b51590265..777f694e57c3 100644 --- a/core/vendor/symfony/class-loader/Symfony/Component/ClassLoader/DebugClassLoader.php +++ b/core/vendor/symfony/class-loader/Symfony/Component/ClassLoader/DebugClassLoader.php @@ -84,6 +84,10 @@ public function loadClass($class) require $file; if (!class_exists($class, false) && !interface_exists($class, false) && (!function_exists('trait_exists') || !trait_exists($class, false))) { + if (false !== strpos($class, '/')) { + throw new \RuntimeException(sprintf('Trying to autoload a class with an invalid name "%s". Be careful that the namespace separator is "\" in PHP, not "/".')); + } + throw new \RuntimeException(sprintf('The autoloader expected class "%s" to be defined in file "%s". The file was found but the class was not in it, the class name or namespace probably has a typo.', $class, $file)); } diff --git a/core/vendor/symfony/dependency-injection/Symfony/Component/DependencyInjection/.gitattributes b/core/vendor/symfony/dependency-injection/Symfony/Component/DependencyInjection/.gitattributes deleted file mode 100644 index 80481513cff2..000000000000 --- a/core/vendor/symfony/dependency-injection/Symfony/Component/DependencyInjection/.gitattributes +++ /dev/null @@ -1,2 +0,0 @@ -/Tests export-ignore -phpunit.xml.dist export-ignore diff --git a/core/vendor/symfony/dependency-injection/Symfony/Component/DependencyInjection/Compiler/MergeExtensionConfigurationPass.php b/core/vendor/symfony/dependency-injection/Symfony/Component/DependencyInjection/Compiler/MergeExtensionConfigurationPass.php index 2bc04927da6f..7573084c36c3 100644 --- a/core/vendor/symfony/dependency-injection/Symfony/Component/DependencyInjection/Compiler/MergeExtensionConfigurationPass.php +++ b/core/vendor/symfony/dependency-injection/Symfony/Component/DependencyInjection/Compiler/MergeExtensionConfigurationPass.php @@ -12,6 +12,7 @@ namespace Symfony\Component\DependencyInjection\Compiler; use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Extension\PrependExtensionInterface; /** * Merges extension configs into the container builder diff --git a/core/vendor/symfony/dependency-injection/Symfony/Component/DependencyInjection/Compiler/ReplaceAliasByActualDefinitionPass.php b/core/vendor/symfony/dependency-injection/Symfony/Component/DependencyInjection/Compiler/ReplaceAliasByActualDefinitionPass.php index 1964184955dc..972d708c593c 100644 --- a/core/vendor/symfony/dependency-injection/Symfony/Component/DependencyInjection/Compiler/ReplaceAliasByActualDefinitionPass.php +++ b/core/vendor/symfony/dependency-injection/Symfony/Component/DependencyInjection/Compiler/ReplaceAliasByActualDefinitionPass.php @@ -12,6 +12,7 @@ namespace Symfony\Component\DependencyInjection\Compiler; use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; use Symfony\Component\DependencyInjection\Reference; /** @@ -30,6 +31,8 @@ class ReplaceAliasByActualDefinitionPass implements CompilerPassInterface * Process the Container to replace aliases with service definitions. * * @param ContainerBuilder $container + * + * @throws InvalidArgumentException if the service definition does not exist */ public function process(ContainerBuilder $container) { @@ -39,7 +42,11 @@ public function process(ContainerBuilder $container) foreach ($container->getAliases() as $id => $alias) { $aliasId = (string) $alias; - $definition = $container->getDefinition($aliasId); + try { + $definition = $container->getDefinition($aliasId); + } catch (InvalidArgumentException $e) { + throw new InvalidArgumentException(sprintf('Unable to replace alias "%s" with "%s".', $alias, $id), null, $e); + } if ($definition->isPublic()) { continue; diff --git a/core/vendor/symfony/dependency-injection/Symfony/Component/DependencyInjection/Compiler/ResolveInvalidReferencesPass.php b/core/vendor/symfony/dependency-injection/Symfony/Component/DependencyInjection/Compiler/ResolveInvalidReferencesPass.php index c69d078e8bcc..6fad9a284165 100644 --- a/core/vendor/symfony/dependency-injection/Symfony/Component/DependencyInjection/Compiler/ResolveInvalidReferencesPass.php +++ b/core/vendor/symfony/dependency-injection/Symfony/Component/DependencyInjection/Compiler/ResolveInvalidReferencesPass.php @@ -89,7 +89,7 @@ private function processArguments(array $arguments, $inMethodCall = false) // resolve invalid behavior if ($exists && ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE !== $invalidBehavior) { - $arguments[$k] = new Reference($id); + $arguments[$k] = new Reference($id, ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE, $argument->isStrict()); } elseif (!$exists && ContainerInterface::NULL_ON_INVALID_REFERENCE === $invalidBehavior) { $arguments[$k] = null; } elseif (!$exists && ContainerInterface::IGNORE_ON_INVALID_REFERENCE === $invalidBehavior) { diff --git a/core/vendor/symfony/dependency-injection/Symfony/Component/DependencyInjection/ContainerBuilder.php b/core/vendor/symfony/dependency-injection/Symfony/Component/DependencyInjection/ContainerBuilder.php index 6f4390a6e56c..8e4b059252d4 100644 --- a/core/vendor/symfony/dependency-injection/Symfony/Component/DependencyInjection/ContainerBuilder.php +++ b/core/vendor/symfony/dependency-injection/Symfony/Component/DependencyInjection/ContainerBuilder.php @@ -834,19 +834,22 @@ public function findDefinition($id) * * @throws RuntimeException When the scope is inactive * @throws RuntimeException When the factory definition is incomplete + * @throws RuntimeException When the service is a synthetic service * @throws InvalidArgumentException When configure callable is not callable */ private function createService(Definition $definition, $id) { + if ($definition->isSynthetic()) { + throw new RuntimeException(sprintf('You have requested a synthetic service ("%s"). The DIC does not know how to construct this service.', $id)); + } + $parameterBag = $this->getParameterBag(); if (null !== $definition->getFile()) { require_once $parameterBag->resolveValue($definition->getFile()); } - $arguments = $this->resolveServices( - $parameterBag->unescapeValue($parameterBag->resolveValue($definition->getArguments())) - ); + $arguments = $this->resolveServices($parameterBag->unescapeValue($parameterBag->resolveValue($definition->getArguments()))); if (null !== $definition->getFactoryMethod()) { if (null !== $definition->getFactoryClass()) { diff --git a/core/vendor/symfony/dependency-injection/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php b/core/vendor/symfony/dependency-injection/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php index eb099d2d91d8..2a29b01c9005 100644 --- a/core/vendor/symfony/dependency-injection/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php +++ b/core/vendor/symfony/dependency-injection/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php @@ -203,7 +203,7 @@ private function addServiceInlinedDefinitions($id, $definition) $nbOccurrences->offsetSet($definition, 1); } else { $i = $nbOccurrences->offsetGet($definition); - $nbOccurrences->offsetSet($definition, $i+1); + $nbOccurrences->offsetSet($definition, $i + 1); } } @@ -214,7 +214,7 @@ private function addServiceInlinedDefinitions($id, $definition) $processed->offsetSet($sDefinition); $class = $this->dumpValue($sDefinition->getClass()); - if ($nbOccurrences->offsetGet($sDefinition) > 1 || count($sDefinition->getMethodCalls()) > 0 || $sDefinition->getProperties() || null !== $sDefinition->getConfigurator() || false !== strpos($class, '$')) { + if ($nbOccurrences->offsetGet($sDefinition) > 1 || $sDefinition->getMethodCalls() || $sDefinition->getProperties() || null !== $sDefinition->getConfigurator() || false !== strpos($class, '$')) { $name = $this->getNextVariableName(); $variableMap->offsetSet($sDefinition, new Variable($name)); @@ -229,26 +229,9 @@ private function addServiceInlinedDefinitions($id, $definition) throw new ServiceCircularReferenceException($id, array($id)); } - $arguments = array(); - foreach ($sDefinition->getArguments() as $argument) { - $arguments[] = $this->dumpValue($argument); - } - - if (null !== $sDefinition->getFactoryMethod()) { - if (null !== $sDefinition->getFactoryClass()) { - $code .= sprintf(" \$%s = call_user_func(array(%s, '%s')%s);\n", $name, $this->dumpValue($sDefinition->getFactoryClass()), $sDefinition->getFactoryMethod(), count($arguments) > 0 ? ', '.implode(', ', $arguments) : ''); - } elseif (null !== $sDefinition->getFactoryService()) { - $code .= sprintf(" \$%s = %s->%s(%s);\n", $name, $this->getServiceCall($sDefinition->getFactoryService()), $sDefinition->getFactoryMethod(), implode(', ', $arguments)); - } else { - throw new RuntimeException('Factory service or factory class must be defined in service definition for '.$id); - } - } elseif (false !== strpos($class, '$')) { - $code .= sprintf(" \$class = %s;\n \$%s = new \$class(%s);\n", $class, $name, implode(', ', $arguments)); - } else { - $code .= sprintf(" \$%s = new \\%s(%s);\n", $name, substr(str_replace('\\\\', '\\', $class), 1, -1), implode(', ', $arguments)); - } + $code .= $this->addNewInstance($id, $sDefinition, '$'.$name, ' = '); - if (!$this->hasReference($id, $sDefinition->getMethodCalls()) && !$this->hasReference($id, $sDefinition->getProperties())) { + if (!$this->hasReference($id, $sDefinition->getMethodCalls(), true) && !$this->hasReference($id, $sDefinition->getProperties(), true)) { $code .= $this->addServiceMethodCalls(null, $sDefinition, $name); $code .= $this->addServiceProperties(null, $sDefinition, $name); $code .= $this->addServiceConfigurator(null, $sDefinition, $name); @@ -297,11 +280,6 @@ private function addServiceInstance($id, $definition) throw new InvalidArgumentException(sprintf('"%s" is not a valid class name for the "%s" service.', $class, $id)); } - $arguments = array(); - foreach ($definition->getArguments() as $value) { - $arguments[] = $this->dumpValue($value); - } - $simple = $this->isSimpleInstance($id, $definition); $instantiation = ''; @@ -320,19 +298,7 @@ private function addServiceInstance($id, $definition) $instantiation .= ' = '; } - if (null !== $definition->getFactoryMethod()) { - if (null !== $definition->getFactoryClass()) { - $code = sprintf(" $return{$instantiation}call_user_func(array(%s, '%s')%s);\n", $this->dumpValue($definition->getFactoryClass()), $definition->getFactoryMethod(), $arguments ? ', '.implode(', ', $arguments) : ''); - } elseif (null !== $definition->getFactoryService()) { - $code = sprintf(" $return{$instantiation}%s->%s(%s);\n", $this->getServiceCall($definition->getFactoryService()), $definition->getFactoryMethod(), implode(', ', $arguments)); - } else { - throw new RuntimeException('Factory method requires a factory service or factory class in service definition for '.$id); - } - } elseif (false !== strpos($class, '$')) { - $code = sprintf(" \$class = %s;\n\n $return{$instantiation}new \$class(%s);\n", $class, implode(', ', $arguments)); - } else { - $code = sprintf(" $return{$instantiation}new \\%s(%s);\n", substr(str_replace('\\\\', '\\', $class), 1, -1), implode(', ', $arguments)); - } + $code = $this->addNewInstance($id, $definition, $return, $instantiation); if (!$simple) { $code .= "\n"; @@ -417,16 +383,14 @@ private function addServiceInlinedDefinitionsSetup($id, $definition) } $processed->offsetSet($iDefinition); - if (!$this->hasReference($id, $iDefinition->getMethodCalls())) { + if (!$this->hasReference($id, $iDefinition->getMethodCalls(), true) && !$this->hasReference($id, $iDefinition->getProperties(), true)) { continue; } - if ($iDefinition->getMethodCalls()) { - $code .= $this->addServiceMethodCalls(null, $iDefinition, (string) $this->definitionVariables->offsetGet($iDefinition)); - } - if ($iDefinition->getConfigurator()) { - $code .= $this->addServiceConfigurator(null, $iDefinition, (string) $this->definitionVariables->offsetGet($iDefinition)); - } + $name = (string) $this->definitionVariables->offsetGet($iDefinition); + $code .= $this->addServiceMethodCalls(null, $iDefinition, $name); + $code .= $this->addServiceProperties(null, $iDefinition, $name); + $code .= $this->addServiceConfigurator(null, $iDefinition, $name); } if ('' !== $code) { @@ -613,6 +577,34 @@ private function addServices() return $publicServices.$aliasServices.$privateServices; } + private function addNewInstance($id, Definition $definition, $return, $instantiation) + { + $class = $this->dumpValue($definition->getClass()); + + $arguments = array(); + foreach ($definition->getArguments() as $value) { + $arguments[] = $this->dumpValue($value); + } + + if (null !== $definition->getFactoryMethod()) { + if (null !== $definition->getFactoryClass()) { + return sprintf(" $return{$instantiation}call_user_func(array(%s, '%s')%s);\n", $this->dumpValue($definition->getFactoryClass()), $definition->getFactoryMethod(), $arguments ? ', '.implode(', ', $arguments) : ''); + } + + if (null !== $definition->getFactoryService()) { + return sprintf(" $return{$instantiation}%s->%s(%s);\n", $this->getServiceCall($definition->getFactoryService()), $definition->getFactoryMethod(), implode(', ', $arguments)); + } + + throw new RuntimeException('Factory method requires a factory service or factory class in service definition for '.$id); + } + + if (false !== strpos($class, '$')) { + return sprintf(" \$class = %s;\n\n $return{$instantiation}new \$class(%s);\n", $class, implode(', ', $arguments)); + } + + return sprintf(" $return{$instantiation}new \\%s(%s);\n", substr(str_replace('\\\\', '\\', $class), 1, -1), implode(', ', $arguments)); + } + /** * Adds the class headers. * @@ -960,22 +952,32 @@ private function getDefinitionsFromArguments(array $arguments) /** * Checks if a service id has a reference * - * @param string $id - * @param array $arguments + * @param string $id + * @param array $arguments + * @param Boolean $deep * * @return Boolean */ - private function hasReference($id, array $arguments) + private function hasReference($id, array $arguments, $deep = false) { foreach ($arguments as $argument) { if (is_array($argument)) { - if ($this->hasReference($id, $argument)) { + if ($this->hasReference($id, $argument, $deep)) { return true; } } elseif ($argument instanceof Reference) { if ($id === (string) $argument) { return true; } + + if ($deep) { + $service = $this->container->getDefinition((string) $argument); + $arguments = array_merge($service->getMethodCalls(), $service->getArguments(), $service->getProperties()); + + if ($this->hasReference($id, $arguments, $deep)) { + return true; + } + } } } diff --git a/core/vendor/symfony/dependency-injection/Symfony/Component/DependencyInjection/Dumper/YamlDumper.php b/core/vendor/symfony/dependency-injection/Symfony/Component/DependencyInjection/Dumper/YamlDumper.php index 82d68008e0ee..e4e168257e4e 100644 --- a/core/vendor/symfony/dependency-injection/Symfony/Component/DependencyInjection/Dumper/YamlDumper.php +++ b/core/vendor/symfony/dependency-injection/Symfony/Component/DependencyInjection/Dumper/YamlDumper.php @@ -184,11 +184,7 @@ private function addParameters() return ''; } - if ($this->container->isFrozen()) { - $parameters = $this->prepareParameters($this->container->getParameterBag()->all()); - } else { - $parameters = $this->container->getParameterBag()->all(); - } + $parameters = $this->prepareParameters($this->container->getParameterBag()->all(), $this->container->isFrozen()); return $this->dumper->dump(array('parameters' => $parameters), 2); } @@ -258,12 +254,12 @@ private function getParameterCall($id) * * @return array */ - private function prepareParameters($parameters) + private function prepareParameters($parameters, $escape = true) { $filtered = array(); foreach ($parameters as $key => $value) { if (is_array($value)) { - $value = $this->prepareParameters($value); + $value = $this->prepareParameters($value, $escape); } elseif ($value instanceof Reference) { $value = '@'.$value; } @@ -271,7 +267,7 @@ private function prepareParameters($parameters) $filtered[$key] = $value; } - return $this->escape($filtered); + return $escape ? $this->escape($filtered) : $filtered; } /** diff --git a/core/vendor/symfony/dependency-injection/Symfony/Component/DependencyInjection/Compiler/PrependExtensionInterface.php b/core/vendor/symfony/dependency-injection/Symfony/Component/DependencyInjection/Extension/PrependExtensionInterface.php similarity index 89% rename from core/vendor/symfony/dependency-injection/Symfony/Component/DependencyInjection/Compiler/PrependExtensionInterface.php rename to core/vendor/symfony/dependency-injection/Symfony/Component/DependencyInjection/Extension/PrependExtensionInterface.php index bba1b6cd46d9..c666bdbcf8d4 100644 --- a/core/vendor/symfony/dependency-injection/Symfony/Component/DependencyInjection/Compiler/PrependExtensionInterface.php +++ b/core/vendor/symfony/dependency-injection/Symfony/Component/DependencyInjection/Extension/PrependExtensionInterface.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace Symfony\Component\DependencyInjection\Compiler; +namespace Symfony\Component\DependencyInjection\Extension; use Symfony\Component\DependencyInjection\ContainerBuilder; diff --git a/core/vendor/symfony/dependency-injection/Symfony/Component/DependencyInjection/Tests/Compiler/CheckExceptionOnInvalidReferenceBehaviorPassTest.php b/core/vendor/symfony/dependency-injection/Symfony/Component/DependencyInjection/Tests/Compiler/CheckExceptionOnInvalidReferenceBehaviorPassTest.php index cbf9934a1037..e71835edc687 100644 --- a/core/vendor/symfony/dependency-injection/Symfony/Component/DependencyInjection/Tests/Compiler/CheckExceptionOnInvalidReferenceBehaviorPassTest.php +++ b/core/vendor/symfony/dependency-injection/Symfony/Component/DependencyInjection/Tests/Compiler/CheckExceptionOnInvalidReferenceBehaviorPassTest.php @@ -31,7 +31,7 @@ public function testProcess() } /** - * @expectedException Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException + * @expectedException \Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException */ public function testProcessThrowsExceptionOnInvalidReference() { @@ -46,7 +46,7 @@ public function testProcessThrowsExceptionOnInvalidReference() } /** - * @expectedException Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException + * @expectedException \Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException */ public function testProcessThrowsExceptionOnInvalidReferenceFromInlinedDefinition() { diff --git a/core/vendor/symfony/dependency-injection/Symfony/Component/DependencyInjection/Tests/Compiler/ReplaceAliasByActualDefinitionPassTest.php b/core/vendor/symfony/dependency-injection/Symfony/Component/DependencyInjection/Tests/Compiler/ReplaceAliasByActualDefinitionPassTest.php index a445a20d0981..e4d22401d3cd 100644 --- a/core/vendor/symfony/dependency-injection/Symfony/Component/DependencyInjection/Tests/Compiler/ReplaceAliasByActualDefinitionPassTest.php +++ b/core/vendor/symfony/dependency-injection/Symfony/Component/DependencyInjection/Tests/Compiler/ReplaceAliasByActualDefinitionPassTest.php @@ -41,6 +41,16 @@ public function testProcess() ); } + /** + * @expectedException \InvalidArgumentException + */ + public function testProcessWithInvalidAlias() + { + $container = new ContainerBuilder(); + $container->setAlias('a_alias', 'a'); + $this->process($container); + } + protected function process(ContainerBuilder $container) { $pass = new ReplaceAliasByActualDefinitionPass(); diff --git a/core/vendor/symfony/dependency-injection/Symfony/Component/DependencyInjection/Tests/Compiler/ResolveInvalidReferencesPassTest.php b/core/vendor/symfony/dependency-injection/Symfony/Component/DependencyInjection/Tests/Compiler/ResolveInvalidReferencesPassTest.php index a18ba73862bc..72058868d44e 100644 --- a/core/vendor/symfony/dependency-injection/Symfony/Component/DependencyInjection/Tests/Compiler/ResolveInvalidReferencesPassTest.php +++ b/core/vendor/symfony/dependency-injection/Symfony/Component/DependencyInjection/Tests/Compiler/ResolveInvalidReferencesPassTest.php @@ -61,6 +61,20 @@ public function testProcessRemovesPropertiesOnInvalid() $this->assertEquals(array(), $def->getProperties()); } + public function testStrictFlagIsPreserved() + { + $container = new ContainerBuilder(); + $container->register('bar'); + $def = $container + ->register('foo') + ->addArgument(new Reference('bar', ContainerInterface::NULL_ON_INVALID_REFERENCE, false)) + ; + + $this->process($container); + + $this->assertFalse($def->getArgument(0)->isStrict()); + } + protected function process(ContainerBuilder $container) { $pass = new ResolveInvalidReferencesPass(); diff --git a/core/vendor/symfony/dependency-injection/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php b/core/vendor/symfony/dependency-injection/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php index 4a6f17d093c3..de542db17b1c 100644 --- a/core/vendor/symfony/dependency-injection/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php +++ b/core/vendor/symfony/dependency-injection/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php @@ -316,6 +316,17 @@ public function testCreateServiceConfigurator() } } + /** + * @covers Symfony\Component\DependencyInjection\ContainerBuilder::createService + * @expectedException \RuntimeException + */ + public function testCreateSyntheticService() + { + $builder = new ContainerBuilder(); + $builder->register('foo', 'FooClass')->setSynthetic(true); + $builder->get('foo'); + } + /** * @covers Symfony\Component\DependencyInjection\ContainerBuilder::resolveServices */ diff --git a/core/vendor/symfony/dependency-injection/Symfony/Component/DependencyInjection/Tests/DefinitionTest.php b/core/vendor/symfony/dependency-injection/Symfony/Component/DependencyInjection/Tests/DefinitionTest.php index 46ea75d5cd63..89f7ae1ea0ad 100644 --- a/core/vendor/symfony/dependency-injection/Symfony/Component/DependencyInjection/Tests/DefinitionTest.php +++ b/core/vendor/symfony/dependency-injection/Symfony/Component/DependencyInjection/Tests/DefinitionTest.php @@ -96,7 +96,7 @@ public function testMethodCalls() } /** - * @expectedException Symfony\Component\DependencyInjection\Exception\InvalidArgumentException + * @expectedException \Symfony\Component\DependencyInjection\Exception\InvalidArgumentException * @expectedExceptionMessage Method name cannot be empty. */ public function testExceptionOnEmptyMethodCall() diff --git a/core/vendor/symfony/dependency-injection/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php b/core/vendor/symfony/dependency-injection/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php index 2697852c9360..72d587ff070f 100644 --- a/core/vendor/symfony/dependency-injection/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php +++ b/core/vendor/symfony/dependency-injection/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php @@ -98,10 +98,17 @@ public function testAddParameters() public function testAddService() { + // without compilation $container = include self::$fixturesPath.'/containers/container9.php'; $dumper = new PhpDumper($container); $this->assertEquals(str_replace('%path%', str_replace('\\','\\\\',self::$fixturesPath.DIRECTORY_SEPARATOR.'includes'.DIRECTORY_SEPARATOR), file_get_contents(self::$fixturesPath.'/php/services9.php')), $dumper->dump(), '->dump() dumps services'); + // with compilation + $container = include self::$fixturesPath.'/containers/container9.php'; + $container->compile(); + $dumper = new PhpDumper($container); + $this->assertEquals(str_replace('%path%', str_replace('\\','\\\\',self::$fixturesPath.DIRECTORY_SEPARATOR.'includes'.DIRECTORY_SEPARATOR), file_get_contents(self::$fixturesPath.'/php/services9_compiled.php')), $dumper->dump(), '->dump() dumps services'); + $dumper = new PhpDumper($container = new ContainerBuilder()); $container->register('foo', 'FooClass')->addArgument(new \stdClass()); try { diff --git a/core/vendor/symfony/dependency-injection/Symfony/Component/DependencyInjection/Tests/Fixtures/containers/container9.php b/core/vendor/symfony/dependency-injection/Symfony/Component/DependencyInjection/Tests/Fixtures/containers/container9.php index 663f2a7fd90a..71d29f209bfc 100644 --- a/core/vendor/symfony/dependency-injection/Symfony/Component/DependencyInjection/Tests/Fixtures/containers/container9.php +++ b/core/vendor/symfony/dependency-injection/Symfony/Component/DependencyInjection/Tests/Fixtures/containers/container9.php @@ -14,9 +14,8 @@ addTag('foo', array('bar' => 'bar'))-> setFactoryClass('FooClass')-> setFactoryMethod('getInstance')-> - setArguments(array('foo', new Reference('foo.baz'), array('%foo%' => 'foo is %foo%', 'bar' => '%foo%'), true, new Reference('service_container')))-> + setArguments(array('foo', new Reference('foo.baz'), array('%foo%' => 'foo is %foo%', 'foobar' => '%foo%'), true, new Reference('service_container')))-> setProperties(array('foo' => 'bar', 'moo' => new Reference('foo.baz')))-> - setScope('prototype')-> addMethodCall('setBar', array(new Reference('bar')))-> addMethodCall('initialize')-> setConfigurator('sc_configure') @@ -33,7 +32,10 @@ setFactoryMethod('getInstance')-> setConfigurator(array('%baz_class%', 'configureStatic1')) ; -$container->register('foo_bar', '%foo_class%'); +$container-> + register('foo_bar', '%foo_class%')-> + setScope('prototype') +; $container->getParameterBag()->clear(); $container->getParameterBag()->add(array( 'baz_class' => 'BazClass', @@ -50,9 +52,24 @@ addMethodCall('setBar', array(new Reference('foobaz', ContainerInterface::IGNORE_ON_INVALID_REFERENCE))) ; $container-> - register('factory_service')-> + register('factory_service', 'Bar')-> setFactoryService('foo.baz')-> setFactoryMethod('getInstance') ; +$container + ->register('foo_with_inline', 'Foo') + ->addMethodCall('setBar', array(new Reference('inlined'))) +; +$container + ->register('inlined', 'Bar') + ->setProperty('pub', 'pub') + ->addMethodCall('setBaz', array(new Reference('baz'))) + ->setPublic(false) +; +$container + ->register('baz', 'Baz') + ->addMethodCall('setFoo', array(new Reference('foo_with_inline'))) +; + return $container; diff --git a/core/vendor/symfony/dependency-injection/Symfony/Component/DependencyInjection/Tests/Fixtures/graphviz/services9.dot b/core/vendor/symfony/dependency-injection/Symfony/Component/DependencyInjection/Tests/Fixtures/graphviz/services9.dot index fdff2219ef94..73608e27fc91 100644 --- a/core/vendor/symfony/dependency-injection/Symfony/Component/DependencyInjection/Tests/Fixtures/graphviz/services9.dot +++ b/core/vendor/symfony/dependency-injection/Symfony/Component/DependencyInjection/Tests/Fixtures/graphviz/services9.dot @@ -3,12 +3,15 @@ digraph sc { node [fontsize="11" fontname="Arial" shape="record"]; edge [fontsize="9" fontname="Arial" color="grey" arrowhead="open" arrowsize="0.5"]; - node_foo [label="foo (alias_for_foo)\nFooClass\n", shape=record, fillcolor="#eeeeee", style="dotted"]; + node_foo [label="foo (alias_for_foo)\nFooClass\n", shape=record, fillcolor="#eeeeee", style="filled"]; node_bar [label="bar\nFooClass\n", shape=record, fillcolor="#eeeeee", style="filled"]; node_foo_baz [label="foo.baz\nBazClass\n", shape=record, fillcolor="#eeeeee", style="filled"]; - node_foo_bar [label="foo_bar\nFooClass\n", shape=record, fillcolor="#eeeeee", style="filled"]; + node_foo_bar [label="foo_bar\nFooClass\n", shape=record, fillcolor="#eeeeee", style="dotted"]; node_method_call1 [label="method_call1\nFooClass\n", shape=record, fillcolor="#eeeeee", style="filled"]; - node_factory_service [label="factory_service\n\n", shape=record, fillcolor="#eeeeee", style="filled"]; + node_factory_service [label="factory_service\nBar\n", shape=record, fillcolor="#eeeeee", style="filled"]; + node_foo_with_inline [label="foo_with_inline\nFoo\n", shape=record, fillcolor="#eeeeee", style="filled"]; + node_inlined [label="inlined\nBar\n", shape=record, fillcolor="#eeeeee", style="filled"]; + node_baz [label="baz\nBaz\n", shape=record, fillcolor="#eeeeee", style="filled"]; node_service_container [label="service_container\nSymfony\\Component\\DependencyInjection\\ContainerBuilder\n", shape=record, fillcolor="#9999ff", style="filled"]; node_foo2 [label="foo2\n\n", shape=record, fillcolor="#ff9999", style="filled"]; node_foo3 [label="foo3\n\n", shape=record, fillcolor="#ff9999", style="filled"]; @@ -22,4 +25,7 @@ digraph sc { node_method_call1 -> node_foo2 [label="setBar()" style="dashed"]; node_method_call1 -> node_foo3 [label="setBar()" style="dashed"]; node_method_call1 -> node_foobaz [label="setBar()" style="dashed"]; + node_foo_with_inline -> node_inlined [label="setBar()" style="dashed"]; + node_inlined -> node_baz [label="setBaz()" style="dashed"]; + node_baz -> node_foo_with_inline [label="setFoo()" style="dashed"]; } diff --git a/core/vendor/symfony/dependency-injection/Symfony/Component/DependencyInjection/Tests/Fixtures/includes/classes.php b/core/vendor/symfony/dependency-injection/Symfony/Component/DependencyInjection/Tests/Fixtures/includes/classes.php index 514df23e5104..fb6d4cf19d5c 100644 --- a/core/vendor/symfony/dependency-injection/Symfony/Component/DependencyInjection/Tests/Fixtures/includes/classes.php +++ b/core/vendor/symfony/dependency-injection/Symfony/Component/DependencyInjection/Tests/Fixtures/includes/classes.php @@ -7,10 +7,23 @@ function sc_configure($instance) class BarClass { + protected $baz; + + public function setBaz(BazClass $baz) + { + $this->baz = $baz; + } } class BazClass { + protected $foo; + + public function setFoo(Foo $foo) + { + $this->foo = $foo; + } + public function configure($instance) { $instance->configure(); diff --git a/core/vendor/symfony/dependency-injection/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services9.php b/core/vendor/symfony/dependency-injection/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services9.php index a0d2ece432ff..80d24c540dbd 100644 --- a/core/vendor/symfony/dependency-injection/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services9.php +++ b/core/vendor/symfony/dependency-injection/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services9.php @@ -43,13 +43,30 @@ protected function getBarService() return $instance; } + /** + * Gets the 'baz' service. + * + * This service is shared. + * This method always returns the same instance of the service. + * + * @return Baz A Baz instance. + */ + protected function getBazService() + { + $this->services['baz'] = $instance = new \Baz(); + + $instance->setFoo($this->get('foo_with_inline')); + + return $instance; + } + /** * Gets the 'factory_service' service. * * This service is shared. * This method always returns the same instance of the service. * - * @return Object An instance returned by foo.baz::getInstance(). + * @return Bar A Bar instance. */ protected function getFactoryServiceService() { @@ -59,13 +76,16 @@ protected function getFactoryServiceService() /** * Gets the 'foo' service. * + * This service is shared. + * This method always returns the same instance of the service. + * * @return FooClass A FooClass instance. */ protected function getFooService() { $a = $this->get('foo.baz'); - $instance = call_user_func(array('FooClass', 'getInstance'), 'foo', $a, array($this->getParameter('foo') => 'foo is '.$this->getParameter('foo').'', 'bar' => $this->getParameter('foo')), true, $this); + $this->services['foo'] = $instance = call_user_func(array('FooClass', 'getInstance'), 'foo', $a, array($this->getParameter('foo') => 'foo is '.$this->getParameter('foo').'', 'foobar' => $this->getParameter('foo')), true, $this); $instance->setBar($this->get('bar')); $instance->initialize(); @@ -96,16 +116,30 @@ protected function getFoo_BazService() /** * Gets the 'foo_bar' service. * - * This service is shared. - * This method always returns the same instance of the service. - * * @return Object A %foo_class% instance. */ protected function getFooBarService() { $class = $this->getParameter('foo_class'); - return $this->services['foo_bar'] = new $class(); + return new $class(); + } + + /** + * Gets the 'foo_with_inline' service. + * + * This service is shared. + * This method always returns the same instance of the service. + * + * @return Foo A Foo instance. + */ + protected function getFooWithInlineService() + { + $this->services['foo_with_inline'] = $instance = new \Foo(); + + $instance->setBar($this->get('inlined')); + + return $instance; } /** @@ -144,6 +178,28 @@ protected function getAliasForFooService() return $this->get('foo'); } + /** + * Gets the 'inlined' service. + * + * This service is shared. + * This method always returns the same instance of the service. + * + * This service is private. + * If you want to be able to request this service from the container directly, + * make it public, otherwise you might end up with broken code. + * + * @return Bar A Bar instance. + */ + protected function getInlinedService() + { + $this->services['inlined'] = $instance = new \Bar(); + + $instance->setBaz($this->get('baz')); + $instance->pub = 'pub'; + + return $instance; + } + /** * Gets the default parameters. * diff --git a/core/vendor/symfony/dependency-injection/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services9_compiled.php b/core/vendor/symfony/dependency-injection/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services9_compiled.php new file mode 100644 index 000000000000..5903b8a41390 --- /dev/null +++ b/core/vendor/symfony/dependency-injection/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services9_compiled.php @@ -0,0 +1,241 @@ +<?php + +use Symfony\Component\DependencyInjection\ContainerInterface; +use Symfony\Component\DependencyInjection\Container; +use Symfony\Component\DependencyInjection\Exception\InactiveScopeException; +use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; +use Symfony\Component\DependencyInjection\Exception\LogicException; +use Symfony\Component\DependencyInjection\Exception\RuntimeException; +use Symfony\Component\DependencyInjection\Reference; +use Symfony\Component\DependencyInjection\Parameter; +use Symfony\Component\DependencyInjection\ParameterBag\FrozenParameterBag; + +/** + * ProjectServiceContainer + * + * This class has been auto-generated + * by the Symfony Dependency Injection Component. + */ +class ProjectServiceContainer extends Container +{ + /** + * Constructor. + */ + public function __construct() + { + $this->parameters = $this->getDefaultParameters(); + + $this->services = + $this->scopedServices = + $this->scopeStacks = array(); + + $this->set('service_container', $this); + + $this->scopes = array(); + $this->scopeChildren = array(); + } + + /** + * Gets the 'bar' service. + * + * This service is shared. + * This method always returns the same instance of the service. + * + * @return FooClass A FooClass instance. + */ + protected function getBarService() + { + $this->services['bar'] = $instance = new \FooClass('foo', $this->get('foo.baz'), $this->getParameter('foo_bar')); + + $this->get('foo.baz')->configure($instance); + + return $instance; + } + + /** + * Gets the 'baz' service. + * + * This service is shared. + * This method always returns the same instance of the service. + * + * @return Baz A Baz instance. + */ + protected function getBazService() + { + $this->services['baz'] = $instance = new \Baz(); + + $instance->setFoo($this->get('foo_with_inline')); + + return $instance; + } + + /** + * Gets the 'factory_service' service. + * + * This service is shared. + * This method always returns the same instance of the service. + * + * @return Bar A Bar instance. + */ + protected function getFactoryServiceService() + { + return $this->services['factory_service'] = $this->get('foo.baz')->getInstance(); + } + + /** + * Gets the 'foo' service. + * + * This service is shared. + * This method always returns the same instance of the service. + * + * @return FooClass A FooClass instance. + */ + protected function getFooService() + { + $a = $this->get('foo.baz'); + + $this->services['foo'] = $instance = call_user_func(array('FooClass', 'getInstance'), 'foo', $a, array('bar' => 'foo is bar', 'foobar' => 'bar'), true, $this); + + $instance->setBar($this->get('bar')); + $instance->initialize(); + $instance->foo = 'bar'; + $instance->moo = $a; + sc_configure($instance); + + return $instance; + } + + /** + * Gets the 'foo.baz' service. + * + * This service is shared. + * This method always returns the same instance of the service. + * + * @return BazClass A BazClass instance. + */ + protected function getFoo_BazService() + { + $this->services['foo.baz'] = $instance = call_user_func(array('BazClass', 'getInstance')); + + call_user_func(array('BazClass', 'configureStatic1'), $instance); + + return $instance; + } + + /** + * Gets the 'foo_bar' service. + * + * @return FooClass A FooClass instance. + */ + protected function getFooBarService() + { + return new \FooClass(); + } + + /** + * Gets the 'foo_with_inline' service. + * + * This service is shared. + * This method always returns the same instance of the service. + * + * @return Foo A Foo instance. + */ + protected function getFooWithInlineService() + { + $a = new \Bar(); + + $this->services['foo_with_inline'] = $instance = new \Foo(); + + $a->setBaz($this->get('baz')); + $a->pub = 'pub'; + + $instance->setBar($a); + + return $instance; + } + + /** + * Gets the 'method_call1' service. + * + * This service is shared. + * This method always returns the same instance of the service. + * + * @return FooClass A FooClass instance. + */ + protected function getMethodCall1Service() + { + require_once '%path%foo.php'; + + $this->services['method_call1'] = $instance = new \FooClass(); + + $instance->setBar($this->get('foo')); + $instance->setBar(NULL); + + return $instance; + } + + /** + * Gets the alias_for_foo service alias. + * + * @return FooClass An instance of the foo service + */ + protected function getAliasForFooService() + { + return $this->get('foo'); + } + + /** + * {@inheritdoc} + */ + public function getParameter($name) + { + $name = strtolower($name); + + if (!array_key_exists($name, $this->parameters)) { + throw new InvalidArgumentException(sprintf('The parameter "%s" must be defined.', $name)); + } + + return $this->parameters[$name]; + } + + /** + * {@inheritdoc} + */ + public function hasParameter($name) + { + return array_key_exists(strtolower($name), $this->parameters); + } + + /** + * {@inheritdoc} + */ + public function setParameter($name, $value) + { + throw new LogicException('Impossible to call set() on a frozen ParameterBag.'); + } + + /** + * {@inheritDoc} + */ + public function getParameterBag() + { + if (null === $this->parameterBag) { + $this->parameterBag = new FrozenParameterBag($this->parameters); + } + + return $this->parameterBag; + } + /** + * Gets the default parameters. + * + * @return array An array of the default parameters + */ + protected function getDefaultParameters() + { + return array( + 'baz_class' => 'BazClass', + 'foo_class' => 'FooClass', + 'foo' => 'bar', + ); + } +} diff --git a/core/vendor/symfony/dependency-injection/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/services9.xml b/core/vendor/symfony/dependency-injection/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/services9.xml index a73fb3e7d1aa..58eb6d79a3c1 100644 --- a/core/vendor/symfony/dependency-injection/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/services9.xml +++ b/core/vendor/symfony/dependency-injection/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/services9.xml @@ -6,14 +6,14 @@ <parameter key="foo">bar</parameter> </parameters> <services> - <service id="foo" class="FooClass" factory-method="getInstance" scope="prototype"> + <service id="foo" class="FooClass" factory-method="getInstance"> <tag name="foo" foo="foo"/> <tag name="foo" bar="bar"/> <argument>foo</argument> <argument type="service" id="foo.baz"/> <argument type="collection"> <argument key="%foo%">foo is %foo%</argument> - <argument key="bar">%foo%</argument> + <argument key="foobar">%foo%</argument> </argument> <argument>true</argument> <argument type="service" id="service_container"/> @@ -34,7 +34,7 @@ <service id="foo.baz" class="%baz_class%" factory-method="getInstance"> <configurator class="%baz_class%" method="configureStatic1"/> </service> - <service id="foo_bar" class="%foo_class%"/> + <service id="foo_bar" class="%foo_class%" scope="prototype"/> <service id="method_call1" class="FooClass"> <file>%path%foo.php</file> <call method="setBar"> @@ -50,7 +50,23 @@ <argument type="service" id="foobaz" on-invalid="ignore"/> </call> </service> - <service id="factory_service" factory-method="getInstance" factory-service="foo.baz"/> + <service id="factory_service" class="Bar" factory-method="getInstance" factory-service="foo.baz"/> + <service id="foo_with_inline" class="Foo"> + <call method="setBar"> + <argument type="service" id="inlined"/> + </call> + </service> + <service id="inlined" class="Bar" public="false"> + <property name="pub">pub</property> + <call method="setBaz"> + <argument type="service" id="baz"/> + </call> + </service> + <service id="baz" class="Baz"> + <call method="setFoo"> + <argument type="service" id="foo_with_inline"/> + </call> + </service> <service id="alias_for_foo" alias="foo"/> </services> </container> diff --git a/core/vendor/symfony/dependency-injection/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services9.yml b/core/vendor/symfony/dependency-injection/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services9.yml index 0fd2ae37bf4a..fcbb83f4ae7e 100644 --- a/core/vendor/symfony/dependency-injection/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services9.yml +++ b/core/vendor/symfony/dependency-injection/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services9.yml @@ -10,13 +10,12 @@ services: - { name: foo, foo: foo } - { name: foo, bar: bar } factory_method: getInstance - arguments: [foo, '@foo.baz', { '%foo%': 'foo is %foo%', bar: '%foo%' }, true, '@service_container'] + arguments: [foo, '@foo.baz', { '%foo%': 'foo is %foo%', foobar: '%foo%' }, true, '@service_container'] properties: { foo: bar, moo: '@foo.baz' } calls: - [setBar, ['@bar']] - [initialize, { }] - scope: prototype configurator: sc_configure bar: class: FooClass @@ -28,6 +27,7 @@ services: configurator: ['%baz_class%', configureStatic1] foo_bar: class: %foo_class% + scope: prototype method_call1: class: FooClass file: %path%foo.php @@ -38,6 +38,23 @@ services: - [setBar, ['@?foobaz']] factory_service: + class: Bar factory_method: getInstance factory_service: foo.baz + foo_with_inline: + class: Foo + calls: + - [setBar, ['@inlined']] + + inlined: + class: Bar + properties: { pub: pub } + calls: + - [setBaz, ['@baz']] + + baz: + class: Baz + calls: + - [setFoo, ['@foo_with_inline']] + alias_for_foo: @foo diff --git a/core/vendor/symfony/event-dispatcher/Symfony/Component/EventDispatcher/.gitattributes b/core/vendor/symfony/event-dispatcher/Symfony/Component/EventDispatcher/.gitattributes deleted file mode 100644 index 80481513cff2..000000000000 --- a/core/vendor/symfony/event-dispatcher/Symfony/Component/EventDispatcher/.gitattributes +++ /dev/null @@ -1,2 +0,0 @@ -/Tests export-ignore -phpunit.xml.dist export-ignore diff --git a/core/vendor/symfony/event-dispatcher/Symfony/Component/EventDispatcher/Tests/GenericEventTest.php b/core/vendor/symfony/event-dispatcher/Symfony/Component/EventDispatcher/Tests/GenericEventTest.php index 179e9a34ed87..8dd6f5b419ac 100644 --- a/core/vendor/symfony/event-dispatcher/Symfony/Component/EventDispatcher/Tests/GenericEventTest.php +++ b/core/vendor/symfony/event-dispatcher/Symfony/Component/EventDispatcher/Tests/GenericEventTest.php @@ -48,7 +48,7 @@ protected function tearDown() parent::tearDown(); } - public function test__construct() + public function testConstruct() { $this->assertEquals($this->event, new GenericEvent($this->subject, array('name' => 'Event'))); } diff --git a/core/vendor/symfony/http-foundation/Symfony/Component/HttpFoundation/.gitattributes b/core/vendor/symfony/http-foundation/Symfony/Component/HttpFoundation/.gitattributes deleted file mode 100644 index 80481513cff2..000000000000 --- a/core/vendor/symfony/http-foundation/Symfony/Component/HttpFoundation/.gitattributes +++ /dev/null @@ -1,2 +0,0 @@ -/Tests export-ignore -phpunit.xml.dist export-ignore diff --git a/core/vendor/symfony/http-foundation/Symfony/Component/HttpFoundation/CHANGELOG.md b/core/vendor/symfony/http-foundation/Symfony/Component/HttpFoundation/CHANGELOG.md index 13ed8dd7c96c..e7d89364b323 100644 --- a/core/vendor/symfony/http-foundation/Symfony/Component/HttpFoundation/CHANGELOG.md +++ b/core/vendor/symfony/http-foundation/Symfony/Component/HttpFoundation/CHANGELOG.md @@ -4,10 +4,14 @@ CHANGELOG 2.2.0 ----- + * added Request::getTrustedProxies() + * deprecated Request::isProxyTrusted() + * [BC BREAK] JsonResponse does not turn a top level empty array to an object anymore, use an ArrayObject to enforce objects * added a IpUtils class to check if an IP belongs to a CIDR * added Request::getRealMethod() to get the "real" HTTP method (getMethod() returns the "intended" HTTP method) * disabled _method request parameter support by default (call Request::enableHttpMethodParameterOverride() to enable it) * Request::splitHttpAcceptHeader() method is deprecated and will be removed in 2.3 + * Deprecated Flashbag::count() and \Countable interface, will be removed in 2.3 2.1.0 ----- diff --git a/core/vendor/symfony/http-foundation/Symfony/Component/HttpFoundation/File/MimeType/FileBinaryMimeTypeGuesser.php b/core/vendor/symfony/http-foundation/Symfony/Component/HttpFoundation/File/MimeType/FileBinaryMimeTypeGuesser.php index 3da63dd4834c..958e84cbae1b 100644 --- a/core/vendor/symfony/http-foundation/Symfony/Component/HttpFoundation/File/MimeType/FileBinaryMimeTypeGuesser.php +++ b/core/vendor/symfony/http-foundation/Symfony/Component/HttpFoundation/File/MimeType/FileBinaryMimeTypeGuesser.php @@ -45,7 +45,7 @@ public function __construct($cmd = 'file -b --mime %s 2>/dev/null') */ public static function isSupported() { - return !defined('PHP_WINDOWS_VERSION_BUILD'); + return !defined('PHP_WINDOWS_VERSION_BUILD') && function_exists('passthru') && function_exists('escapeshellarg'); } /** diff --git a/core/vendor/symfony/http-foundation/Symfony/Component/HttpFoundation/JsonResponse.php b/core/vendor/symfony/http-foundation/Symfony/Component/HttpFoundation/JsonResponse.php index c131575f016f..b6ac8017a3cd 100644 --- a/core/vendor/symfony/http-foundation/Symfony/Component/HttpFoundation/JsonResponse.php +++ b/core/vendor/symfony/http-foundation/Symfony/Component/HttpFoundation/JsonResponse.php @@ -28,17 +28,20 @@ class JsonResponse extends Response * @param integer $status The response status code * @param array $headers An array of response headers */ - public function __construct($data = array(), $status = 200, $headers = array()) + public function __construct($data = null, $status = 200, $headers = array()) { parent::__construct('', $status, $headers); + if (null === $data) { + $data = new \ArrayObject(); + } $this->setData($data); } /** * {@inheritDoc} */ - public static function create($data = array(), $status = 200, $headers = array()) + public static function create($data = null, $status = 200, $headers = array()) { return new static($data, $status, $headers); } @@ -79,11 +82,6 @@ public function setCallback($callback = null) */ public function setData($data = array()) { - // root should be JSON object, not array - if (is_array($data) && 0 === count($data)) { - $data = new \ArrayObject(); - } - // Encode <, >, ', &, and " for RFC4627-compliant JSON, which may also be embedded into HTML. $this->data = json_encode($data, JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_AMP | JSON_HEX_QUOT); diff --git a/core/vendor/symfony/http-foundation/Symfony/Component/HttpFoundation/Request.php b/core/vendor/symfony/http-foundation/Symfony/Component/HttpFoundation/Request.php index 3b5d1448a081..0815b46eae4b 100644 --- a/core/vendor/symfony/http-foundation/Symfony/Component/HttpFoundation/Request.php +++ b/core/vendor/symfony/http-foundation/Symfony/Component/HttpFoundation/Request.php @@ -486,6 +486,16 @@ public static function setTrustedProxies(array $proxies) self::$trustProxy = $proxies ? true : false; } + /** + * Gets the list of trusted proxies. + * + * @return array An array of trusted proxies. + */ + public static function getTrustedProxies() + { + return self::$trustedProxies; + } + /** * Sets the name for trusted headers. * @@ -517,6 +527,8 @@ public static function setTrustedHeaderName($key, $value) * false otherwise. * * @return boolean + * + * @deprecated Deprecated since version 2.2, to be removed in 2.3. Use getTrustedProxies instead. */ public static function isProxyTrusted() { @@ -572,7 +584,7 @@ public static function normalizeQueryString($qs) * Be warned that enabling this feature might lead to CSRF issues in your code. * Check that you are using CSRF tokens when required. * - * The HTTP method can only be overriden when the real HTTP method is POST. + * The HTTP method can only be overridden when the real HTTP method is POST. */ public static function enableHttpMethodParameterOverride() { @@ -676,8 +688,6 @@ public function setSession(SessionInterface $session) * * @see http://en.wikipedia.org/wiki/X-Forwarded-For * - * @deprecated The proxy argument is deprecated since version 2.0 and will be removed in 2.3. Use setTrustedProxies instead. - * * @api */ public function getClientIp() @@ -722,7 +732,7 @@ public function getScriptName() * * * http://localhost/mysite returns an empty string * * http://localhost/mysite/about returns '/about' - * * htpp://localhost/mysite/enco%20ded returns '/enco%20ded' + * * http://localhost/mysite/enco%20ded returns '/enco%20ded' * * http://localhost/mysite/about?var=1 returns '/about' * * @return string The raw path (i.e. not urldecoded) @@ -916,8 +926,7 @@ public function getSchemeAndHttpHost() */ public function getUri() { - $qs = $this->getQueryString(); - if (null !== $qs) { + if (null !== $qs = $this->getQueryString()) { $qs = '?'.$qs; } @@ -1404,7 +1413,8 @@ public function getAcceptableContentTypes() * Returns true if the request is a XMLHttpRequest. * * It works if your JavaScript library set an X-Requested-With HTTP header. - * It is known to work with Prototype, Mootools, jQuery. + * It is known to work with common JavaScript frameworks: + * @link http://en.wikipedia.org/wiki/List_of_Ajax_frameworks#JavaScript * * @return Boolean true if the request is an XMLHttpRequest, false otherwise * diff --git a/core/vendor/symfony/http-foundation/Symfony/Component/HttpFoundation/Session/Flash/FlashBag.php b/core/vendor/symfony/http-foundation/Symfony/Component/HttpFoundation/Session/Flash/FlashBag.php index ce9308e15456..5bb43bc53a4b 100644 --- a/core/vendor/symfony/http-foundation/Symfony/Component/HttpFoundation/Session/Flash/FlashBag.php +++ b/core/vendor/symfony/http-foundation/Symfony/Component/HttpFoundation/Session/Flash/FlashBag.php @@ -177,10 +177,17 @@ public function getIterator() /** * Returns the number of flashes. * + * This method does not work. + * + * @deprecated in 2.2, removed in 2.3 + * @see https://github.com/symfony/symfony/issues/6408 + * * @return int The number of flashes */ public function count() { + trigger_error(sprintf('%s() is deprecated since 2.2 and will be removed in 2.3', __METHOD__), E_USER_DEPRECATED); + return count($this->flashes); } } diff --git a/core/vendor/symfony/http-foundation/Symfony/Component/HttpFoundation/Tests/File/UploadedFileTest.php b/core/vendor/symfony/http-foundation/Symfony/Component/HttpFoundation/Tests/File/UploadedFileTest.php index 94a075ac4612..7fd2f5e6d004 100644 --- a/core/vendor/symfony/http-foundation/Symfony/Component/HttpFoundation/Tests/File/UploadedFileTest.php +++ b/core/vendor/symfony/http-foundation/Symfony/Component/HttpFoundation/Tests/File/UploadedFileTest.php @@ -103,7 +103,7 @@ public function testGetClientOriginalExtension() } /** - * @expectedException Symfony\Component\HttpFoundation\File\Exception\FileException + * @expectedException \Symfony\Component\HttpFoundation\File\Exception\FileException */ public function testMoveLocalFileIsNotAllowed() { diff --git a/core/vendor/symfony/http-foundation/Symfony/Component/HttpFoundation/Tests/RequestTest.php b/core/vendor/symfony/http-foundation/Symfony/Component/HttpFoundation/Tests/RequestTest.php index a178b2fd8d15..9f4cb57571cb 100644 --- a/core/vendor/symfony/http-foundation/Symfony/Component/HttpFoundation/Tests/RequestTest.php +++ b/core/vendor/symfony/http-foundation/Symfony/Component/HttpFoundation/Tests/RequestTest.php @@ -303,9 +303,9 @@ public function testGetUri() $server = array(); // Standard Request on non default PORT - // http://hostname:8080/index.php/path/info?query=string + // http://host:8080/index.php/path/info?query=string - $server['HTTP_HOST'] = 'hostname:8080'; + $server['HTTP_HOST'] = 'host:8080'; $server['SERVER_NAME'] = 'servername'; $server['SERVER_PORT'] = '8080'; @@ -321,16 +321,16 @@ public function testGetUri() $request->initialize(array(), array(), array(), array(), array(), $server); - $this->assertEquals('http://hostname:8080/index.php/path/info?query=string', $request->getUri(), '->getUri() with non default port'); + $this->assertEquals('http://host:8080/index.php/path/info?query=string', $request->getUri(), '->getUri() with non default port'); // Use std port number - $server['HTTP_HOST'] = 'hostname'; + $server['HTTP_HOST'] = 'host'; $server['SERVER_NAME'] = 'servername'; $server['SERVER_PORT'] = '80'; $request->initialize(array(), array(), array(), array(), array(), $server); - $this->assertEquals('http://hostname/index.php/path/info?query=string', $request->getUri(), '->getUri() with default port'); + $this->assertEquals('http://host/index.php/path/info?query=string', $request->getUri(), '->getUri() with default port'); // Without HOST HEADER unset($server['HTTP_HOST']); @@ -344,9 +344,9 @@ public function testGetUri() // Request with URL REWRITING (hide index.php) // RewriteCond %{REQUEST_FILENAME} !-f // RewriteRule ^(.*)$ index.php [QSA,L] - // http://hostname:8080/path/info?query=string + // http://host:8080/path/info?query=string $server = array(); - $server['HTTP_HOST'] = 'hostname:8080'; + $server['HTTP_HOST'] = 'host:8080'; $server['SERVER_NAME'] = 'servername'; $server['SERVER_PORT'] = '8080'; @@ -360,17 +360,17 @@ public function testGetUri() $server['SCRIPT_FILENAME'] = '/some/where/index.php'; $request->initialize(array(), array(), array(), array(), array(), $server); - $this->assertEquals('http://hostname:8080/path/info?query=string', $request->getUri(), '->getUri() with rewrite'); + $this->assertEquals('http://host:8080/path/info?query=string', $request->getUri(), '->getUri() with rewrite'); // Use std port number - // http://hostname/path/info?query=string - $server['HTTP_HOST'] = 'hostname'; + // http://host/path/info?query=string + $server['HTTP_HOST'] = 'host'; $server['SERVER_NAME'] = 'servername'; $server['SERVER_PORT'] = '80'; $request->initialize(array(), array(), array(), array(), array(), $server); - $this->assertEquals('http://hostname/path/info?query=string', $request->getUri(), '->getUri() with rewrite and default port'); + $this->assertEquals('http://host/path/info?query=string', $request->getUri(), '->getUri() with rewrite and default port'); // Without HOST HEADER unset($server['HTTP_HOST']); @@ -384,7 +384,7 @@ public function testGetUri() // With encoded characters $server = array( - 'HTTP_HOST' => 'hostname:8080', + 'HTTP_HOST' => 'host:8080', 'SERVER_NAME' => 'servername', 'SERVER_PORT' => '8080', 'QUERY_STRING' => 'query=string', @@ -398,7 +398,7 @@ public function testGetUri() $request->initialize(array(), array(), array(), array(), array(), $server); $this->assertEquals( - 'http://hostname:8080/ba%20se/index_dev.php/foo%20bar/in+fo?query=string', + 'http://host:8080/ba%20se/index_dev.php/foo%20bar/in+fo?query=string', $request->getUri() ); @@ -406,11 +406,11 @@ public function testGetUri() $server['PHP_AUTH_USER'] = 'fabien'; $request->initialize(array(), array(), array(), array(), array(), $server); - $this->assertEquals('http://hostname:8080/ba%20se/index_dev.php/foo%20bar/in+fo?query=string', $request->getUri()); + $this->assertEquals('http://host:8080/ba%20se/index_dev.php/foo%20bar/in+fo?query=string', $request->getUri()); $server['PHP_AUTH_PW'] = 'symfony'; $request->initialize(array(), array(), array(), array(), array(), $server); - $this->assertEquals('http://hostname:8080/ba%20se/index_dev.php/foo%20bar/in+fo?query=string', $request->getUri()); + $this->assertEquals('http://host:8080/ba%20se/index_dev.php/foo%20bar/in+fo?query=string', $request->getUri()); } /** @@ -433,9 +433,9 @@ public function testGetUriForPath() $server = array(); // Standard Request on non default PORT - // http://hostname:8080/index.php/path/info?query=string + // http://host:8080/index.php/path/info?query=string - $server['HTTP_HOST'] = 'hostname:8080'; + $server['HTTP_HOST'] = 'host:8080'; $server['SERVER_NAME'] = 'servername'; $server['SERVER_PORT'] = '8080'; @@ -451,16 +451,16 @@ public function testGetUriForPath() $request->initialize(array(), array(), array(), array(), array(),$server); - $this->assertEquals('http://hostname:8080/index.php/some/path', $request->getUriForPath('/some/path'), '->getUriForPath() with non default port'); + $this->assertEquals('http://host:8080/index.php/some/path', $request->getUriForPath('/some/path'), '->getUriForPath() with non default port'); // Use std port number - $server['HTTP_HOST'] = 'hostname'; + $server['HTTP_HOST'] = 'host'; $server['SERVER_NAME'] = 'servername'; $server['SERVER_PORT'] = '80'; $request->initialize(array(), array(), array(), array(), array(), $server); - $this->assertEquals('http://hostname/index.php/some/path', $request->getUriForPath('/some/path'), '->getUriForPath() with default port'); + $this->assertEquals('http://host/index.php/some/path', $request->getUriForPath('/some/path'), '->getUriForPath() with default port'); // Without HOST HEADER unset($server['HTTP_HOST']); @@ -474,9 +474,9 @@ public function testGetUriForPath() // Request with URL REWRITING (hide index.php) // RewriteCond %{REQUEST_FILENAME} !-f // RewriteRule ^(.*)$ index.php [QSA,L] - // http://hostname:8080/path/info?query=string + // http://host:8080/path/info?query=string $server = array(); - $server['HTTP_HOST'] = 'hostname:8080'; + $server['HTTP_HOST'] = 'host:8080'; $server['SERVER_NAME'] = 'servername'; $server['SERVER_PORT'] = '8080'; @@ -490,17 +490,17 @@ public function testGetUriForPath() $server['SCRIPT_FILENAME'] = '/some/where/index.php'; $request->initialize(array(), array(), array(), array(), array(), $server); - $this->assertEquals('http://hostname:8080/some/path', $request->getUriForPath('/some/path'), '->getUri() with rewrite'); + $this->assertEquals('http://host:8080/some/path', $request->getUriForPath('/some/path'), '->getUri() with rewrite'); // Use std port number - // http://hostname/path/info?query=string - $server['HTTP_HOST'] = 'hostname'; + // http://host/path/info?query=string + $server['HTTP_HOST'] = 'host'; $server['SERVER_NAME'] = 'servername'; $server['SERVER_PORT'] = '80'; $request->initialize(array(), array(), array(), array(), array(), $server); - $this->assertEquals('http://hostname/some/path', $request->getUriForPath('/some/path'), '->getUriForPath() with rewrite and default port'); + $this->assertEquals('http://host/some/path', $request->getUriForPath('/some/path'), '->getUriForPath() with rewrite and default port'); // Without HOST HEADER unset($server['HTTP_HOST']); diff --git a/core/vendor/symfony/http-foundation/Symfony/Component/HttpFoundation/Tests/Session/Flash/FlashBagTest.php b/core/vendor/symfony/http-foundation/Symfony/Component/HttpFoundation/Tests/Session/Flash/FlashBagTest.php index d7d12e59b76b..208a5e705b12 100644 --- a/core/vendor/symfony/http-foundation/Symfony/Component/HttpFoundation/Tests/Session/Flash/FlashBagTest.php +++ b/core/vendor/symfony/http-foundation/Symfony/Component/HttpFoundation/Tests/Session/Flash/FlashBagTest.php @@ -135,6 +135,7 @@ public function testPeekAll() /** * @covers Symfony\Component\HttpFoundation\Session\Flash\FlashBag::count + * @expectedException \PHPUnit_Framework_Error_Deprecated */ public function testCount() { @@ -163,6 +164,6 @@ public function testGetIterator() } $this->assertEquals(count($flashes), $i); - $this->assertEquals(0, count($this->bag)); + $this->assertEquals(0, count($this->bag->all())); } } diff --git a/core/vendor/symfony/http-foundation/Symfony/Component/HttpFoundation/Tests/Session/Storage/Handler/MemcachedSessionHandlerTest.php b/core/vendor/symfony/http-foundation/Symfony/Component/HttpFoundation/Tests/Session/Storage/Handler/MemcachedSessionHandlerTest.php index 6f158cd1b767..7fbfd0a479f1 100644 --- a/core/vendor/symfony/http-foundation/Symfony/Component/HttpFoundation/Tests/Session/Storage/Handler/MemcachedSessionHandlerTest.php +++ b/core/vendor/symfony/http-foundation/Symfony/Component/HttpFoundation/Tests/Session/Storage/Handler/MemcachedSessionHandlerTest.php @@ -13,7 +13,7 @@ use Symfony\Component\HttpFoundation\Session\Storage\Handler\MemcachedSessionHandler; -class MemcacheddSessionHandlerTest extends \PHPUnit_Framework_TestCase +class MemcachedSessionHandlerTest extends \PHPUnit_Framework_TestCase { const PREFIX = 'prefix_'; const TTL = 1000; diff --git a/core/vendor/symfony/http-foundation/Symfony/Component/HttpFoundation/Tests/Session/Storage/Handler/NativeFileSessionHandlerTest.php b/core/vendor/symfony/http-foundation/Symfony/Component/HttpFoundation/Tests/Session/Storage/Handler/NativeFileSessionHandlerTest.php index de2c4939f092..20cefabf497b 100644 --- a/core/vendor/symfony/http-foundation/Symfony/Component/HttpFoundation/Tests/Session/Storage/Handler/NativeFileSessionHandlerTest.php +++ b/core/vendor/symfony/http-foundation/Symfony/Component/HttpFoundation/Tests/Session/Storage/Handler/NativeFileSessionHandlerTest.php @@ -23,7 +23,7 @@ */ class NativeFileSessionHandlerTest extends \PHPUnit_Framework_TestCase { - public function test__Construct() + public function testConstruct() { $storage = new NativeSessionStorage(array('name' => 'TESTING'), new NativeFileSessionHandler(sys_get_temp_dir())); @@ -42,7 +42,7 @@ public function test__Construct() /** * @dataProvider savePathDataProvider */ - public function test__ConstructSavePath($savePath, $expectedSavePath, $path) + public function testConstructSavePath($savePath, $expectedSavePath, $path) { $handler = new NativeFileSessionHandler($savePath); $this->assertEquals($expectedSavePath, ini_get('session.save_path')); @@ -65,7 +65,7 @@ public function savePathDataProvider() /** * @expectedException \InvalidArgumentException */ - public function test__ConstructException() + public function testConstructException() { $handler = new NativeFileSessionHandler('something;invalid;with;too-many-args'); } diff --git a/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/.gitattributes b/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/.gitattributes deleted file mode 100644 index 80481513cff2..000000000000 --- a/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/.gitattributes +++ /dev/null @@ -1,2 +0,0 @@ -/Tests export-ignore -phpunit.xml.dist export-ignore diff --git a/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/CHANGELOG.md b/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/CHANGELOG.md index 75b5d9321a7f..0bb901ec39d8 100644 --- a/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/CHANGELOG.md +++ b/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/CHANGELOG.md @@ -4,6 +4,12 @@ CHANGELOG 2.2.0 ----- + * added Symfony\Component\HttpKernel\EventListener\RouterProxyListener + * added Symfony\Component\HttpKernel\UriSigner + * added Symfony\Component\HttpKernel\HttpContentRenderer and rendering strategies (in Symfony\Component\HttpKernel\RenderingStrategy) + * added Symfony\Component\HttpKernel\EventListener\RouterProxyListener + * added Symfony\Component\HttpKernel\DependencyInjection\ContainerAwareHttpKernel + * added ControllerReference to create reference of Controllers (used in the HttpContentRenderer class) * [BC BREAK] renamed TimeDataCollector::getTotalTime() to TimeDataCollector::getDuration() * updated the MemoryDataCollector to include the memory used in the diff --git a/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Controller/ControllerReference.php b/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Controller/ControllerReference.php new file mode 100644 index 000000000000..905e89f5dc00 --- /dev/null +++ b/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Controller/ControllerReference.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\HttpKernel\Controller; + +/** + * Acts as a marker and a data holder for a Controller. + * + * Some methods in Symfony accept both a URI (as a string) or a controller as + * an argument. In the latter case, instead of passing an array representing + * the controller, you can use an instance of this class. + * + * @author Fabien Potencier <fabien@symfony.com> + * + * @see Symfony\Component\HttpKernel\HttpContentRenderer + * @see Symfony\Component\HttpKernel\RenderingStrategy\RenderingStrategyInterface + */ +class ControllerReference +{ + public $controller; + public $attributes = array(); + public $query = array(); + + /** + * Constructor. + * + * @param string $controller The controller name + * @param array $attributes An array of parameters to add to the Request attributes + * @param array $query An array of parameters to add to the Request query string + */ + public function __construct($controller, array $attributes = array(), array $query = array()) + { + $this->controller = $controller; + $this->attributes = $attributes; + $this->query = $query; + } +} diff --git a/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Controller/ControllerResolver.php b/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Controller/ControllerResolver.php index 0d308c9d834a..bbe77467340f 100644 --- a/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Controller/ControllerResolver.php +++ b/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Controller/ControllerResolver.php @@ -11,7 +11,7 @@ namespace Symfony\Component\HttpKernel\Controller; -use Symfony\Component\HttpKernel\Log\LoggerInterface; +use Psr\Log\LoggerInterface; use Symfony\Component\HttpFoundation\Request; /** @@ -58,7 +58,7 @@ public function getController(Request $request) { if (!$controller = $request->attributes->get('_controller')) { if (null !== $this->logger) { - $this->logger->warn('Unable to look for the controller as the "_controller" parameter is missing'); + $this->logger->warning('Unable to look for the controller as the "_controller" parameter is missing'); } return false; diff --git a/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/DataCollector/ConfigDataCollector.php b/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/DataCollector/ConfigDataCollector.php index cfaa0b7277b0..3cd17b12cfcb 100644 --- a/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/DataCollector/ConfigDataCollector.php +++ b/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/DataCollector/ConfigDataCollector.php @@ -54,6 +54,7 @@ public function collect(Request $request, Response $response, \Exception $except 'xcache_enabled' => extension_loaded('xcache') && ini_get('xcache.cacher'), 'wincache_enabled' => extension_loaded('wincache') && ini_get('wincache.ocenabled'), 'bundles' => array(), + 'sapi_name' => php_sapi_name() ); if (isset($this->kernel)) { @@ -188,6 +189,16 @@ public function getBundles() return $this->data['bundles']; } + /** + * Gets the PHP SAPI name. + * + * @return string The environment + */ + public function getSapiName() + { + return $this->data['sapi_name']; + } + /** * {@inheritdoc} */ diff --git a/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/DataCollector/RequestDataCollector.php b/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/DataCollector/RequestDataCollector.php index fd544b8204b7..a797e754944d 100644 --- a/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/DataCollector/RequestDataCollector.php +++ b/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/DataCollector/RequestDataCollector.php @@ -51,7 +51,7 @@ public function collect(Request $request, Response $response, \Exception $except $attributes = array(); foreach ($request->attributes->all() as $key => $value) { if ('_route' == $key && is_object($value)) { - $value = $value->getPattern(); + $value = $value->getPath(); } $attributes[$key] = $this->varToString($value); diff --git a/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Debug/ErrorHandler.php b/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Debug/ErrorHandler.php index 50eadfe0a535..c014582d252b 100644 --- a/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Debug/ErrorHandler.php +++ b/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Debug/ErrorHandler.php @@ -12,7 +12,7 @@ namespace Symfony\Component\HttpKernel\Debug; use Symfony\Component\HttpKernel\Exception\FatalErrorException; -use Symfony\Component\HttpKernel\Log\LoggerInterface; +use Psr\Log\LoggerInterface; /** * ErrorHandler. @@ -86,16 +86,9 @@ public function handle($level, $message, $file, $line, $context) if ($level & (E_USER_DEPRECATED | E_DEPRECATED)) { if (null !== self::$logger) { - $deprecation = array( - 'type' => self::TYPE_DEPRECATION, - 'file' => $file, - 'line' => $line, - 'stack' => version_compare(PHP_VERSION, '5.4', '<') - ? array_slice(debug_backtrace(false), 0, 10) - : debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 10) - ); - - self::$logger->warn($message, $deprecation); + $stack = version_compare(PHP_VERSION, '5.4', '<') ? array_slice(debug_backtrace(false), 0, 10) : debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 10); + + self::$logger->warning($message, array('type' => self::TYPE_DEPRECATION, 'stack' => $stack)); } return true; diff --git a/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Debug/TraceableEventDispatcher.php b/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Debug/TraceableEventDispatcher.php index a8a27d9eab96..adbd4969abc8 100644 --- a/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Debug/TraceableEventDispatcher.php +++ b/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Debug/TraceableEventDispatcher.php @@ -13,7 +13,7 @@ use Symfony\Component\Stopwatch\Stopwatch; use Symfony\Component\HttpKernel\KernelEvents; -use Symfony\Component\HttpKernel\Log\LoggerInterface; +use Psr\Log\LoggerInterface; use Symfony\Component\HttpKernel\Profiler\Profile; use Symfony\Component\HttpKernel\Profiler\Profiler; use Symfony\Component\HttpKernel\HttpKernelInterface; diff --git a/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/DependencyInjection/ContainerAwareHttpKernel.php b/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/DependencyInjection/ContainerAwareHttpKernel.php new file mode 100644 index 000000000000..20b4a5e75e9a --- /dev/null +++ b/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/DependencyInjection/ContainerAwareHttpKernel.php @@ -0,0 +1,68 @@ +<?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\HttpKernel\DependencyInjection; + +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\HttpKernel\HttpKernelInterface; +use Symfony\Component\HttpKernel\HttpKernel; +use Symfony\Component\HttpKernel\Controller\ControllerResolverInterface; +use Symfony\Component\EventDispatcher\EventDispatcherInterface; +use Symfony\Component\DependencyInjection\ContainerInterface; + +/** + * This HttpKernel is used to manage scope changes of the DI container. + * + * @author Fabien Potencier <fabien@symfony.com> + * @author Johannes M. Schmitt <schmittjoh@gmail.com> + */ +class ContainerAwareHttpKernel extends HttpKernel +{ + protected $container; + + /** + * Constructor. + * + * @param EventDispatcherInterface $dispatcher An EventDispatcherInterface instance + * @param ContainerInterface $container A ContainerInterface instance + * @param ControllerResolverInterface $controllerResolver A ControllerResolverInterface instance + */ + public function __construct(EventDispatcherInterface $dispatcher, ContainerInterface $container, ControllerResolverInterface $controllerResolver) + { + parent::__construct($dispatcher, $controllerResolver); + + $this->container = $container; + } + + /** + * {@inheritdoc} + */ + public function handle(Request $request, $type = HttpKernelInterface::MASTER_REQUEST, $catch = true) + { + $request->headers->set('X-Php-Ob-Level', ob_get_level()); + + $this->container->enterScope('request'); + $this->container->set('request', $request, 'request'); + + try { + $response = parent::handle($request, $type, $catch); + } catch (\Exception $e) { + $this->container->leaveScope('request'); + + throw $e; + } + + $this->container->leaveScope('request'); + + return $response; + } +} diff --git a/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/EventListener/DeprecationLoggerListener.php b/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/EventListener/DeprecationLoggerListener.php index a40e866155b2..ca2c480582d0 100644 --- a/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/EventListener/DeprecationLoggerListener.php +++ b/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/EventListener/DeprecationLoggerListener.php @@ -11,7 +11,7 @@ namespace Symfony\Component\HttpKernel\EventListener; -use Symfony\Component\HttpKernel\Log\LoggerInterface; +use Psr\Log\LoggerInterface; use Symfony\Component\HttpKernel\Debug\ErrorHandler; use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Symfony\Component\HttpKernel\KernelEvents; diff --git a/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/EventListener/ExceptionListener.php b/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/EventListener/ExceptionListener.php index 8c49d022b001..3d3c7a1c363b 100644 --- a/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/EventListener/ExceptionListener.php +++ b/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/EventListener/ExceptionListener.php @@ -11,7 +11,7 @@ namespace Symfony\Component\HttpKernel\EventListener; -use Symfony\Component\HttpKernel\Log\LoggerInterface; +use Psr\Log\LoggerInterface; use Symfony\Component\HttpKernel\Log\DebugLoggerInterface; use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent; use Symfony\Component\HttpKernel\KernelEvents; @@ -69,7 +69,7 @@ public function onKernelException(GetResponseForExceptionEvent $event) // set handling to false otherwise it wont be able to handle further more $handling = false; - // re-throw the exception as this is a catch-all + // re-throw the exception from within HttpKernel as this is a catch-all return; } @@ -97,9 +97,9 @@ protected function logException(\Exception $exception, $message, $original = tru $isCritical = !$exception instanceof HttpExceptionInterface || $exception->getStatusCode() >= 500; if (null !== $this->logger) { if ($isCritical) { - $this->logger->crit($message); + $this->logger->critical($message); } else { - $this->logger->err($message); + $this->logger->error($message); } } elseif (!$original || $isCritical) { error_log($message); diff --git a/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/EventListener/RouterListener.php b/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/EventListener/RouterListener.php index 208ffc17827d..606b358e72f0 100644 --- a/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/EventListener/RouterListener.php +++ b/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/EventListener/RouterListener.php @@ -11,7 +11,7 @@ namespace Symfony\Component\HttpKernel\EventListener; -use Symfony\Component\HttpKernel\Log\LoggerInterface; +use Psr\Log\LoggerInterface; use Symfony\Component\HttpKernel\Event\GetResponseEvent; use Symfony\Component\HttpKernel\KernelEvents; use Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException; diff --git a/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/EventListener/RouterProxyListener.php b/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/EventListener/RouterProxyListener.php new file mode 100644 index 000000000000..3554361ae355 --- /dev/null +++ b/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/EventListener/RouterProxyListener.php @@ -0,0 +1,106 @@ +<?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\HttpKernel\EventListener; + +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\IpUtils; +use Symfony\Component\HttpKernel\Event\GetResponseEvent; +use Symfony\Component\HttpKernel\KernelEvents; +use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException; +use Symfony\Component\HttpKernel\UriSigner; +use Symfony\Component\EventDispatcher\EventSubscriberInterface; + +/** + * Proxies URIs when the current route name is "_proxy". + * + * If the request does not come from a trusted IP, it throws an + * AccessDeniedHttpException exception. + * + * @author Fabien Potencier <fabien@symfony.com> + */ +class RouterProxyListener implements EventSubscriberInterface +{ + private $signer; + private $proxyPath; + + /** + * Constructor. + * + * @param UriSigner $signer A UriSigner instance + * @param string $proxyPath The path that triggers this listener + */ + public function __construct(UriSigner $signer, $proxyPath = '/_proxy') + { + $this->signer = $signer; + $this->proxyPath = $proxyPath; + } + + /** + * Fixes request attributes when the route is '_proxy'. + * + * @param GetResponseEvent $event A GetResponseEvent instance + * + * @throws AccessDeniedHttpException if the request does not come from a trusted IP. + */ + public function onKernelRequest(GetResponseEvent $event) + { + $request = $event->getRequest(); + + if ($this->proxyPath !== rawurldecode($request->getPathInfo())) { + return; + } + + $this->validateRequest($request); + + parse_str($request->query->get('_path', ''), $attributes); + $request->attributes->add($attributes); + $request->attributes->set('_route_params', array_replace($request->attributes->get('_route_params', array()), $attributes)); + $request->query->remove('_path'); + } + + protected function validateRequest(Request $request) + { + // is the Request safe? + if (!$request->isMethodSafe()) { + throw new AccessDeniedHttpException(); + } + + // does the Request come from a trusted IP? + $trustedIps = array_merge($this->getLocalIpAddresses(), $request->getTrustedProxies()); + $remoteAddress = $request->server->get('REMOTE_ADDR'); + foreach ($trustedIps as $ip) { + if (IpUtils::checkIp($remoteAddress, $ip)) { + return; + } + } + + // is the Request signed? + // we cannot use $request->getUri() here as we want to work with the original URI (no query string reordering) + if ($this->signer->check($request->getSchemeAndHttpHost().$request->getBaseUrl().$request->getPathInfo().(null !== ($qs = $request->server->get('QUERY_STRING')) ? '?'.$qs : ''))) { + return; + } + + throw new AccessDeniedHttpException(); + } + + protected function getLocalIpAddresses() + { + return array('127.0.0.1', 'fe80::1', '::1'); + } + + public static function getSubscribedEvents() + { + return array( + KernelEvents::REQUEST => array(array('onKernelRequest', 48)), + ); + } +} diff --git a/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/HttpContentRenderer.php b/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/HttpContentRenderer.php new file mode 100644 index 000000000000..d476bb2dba09 --- /dev/null +++ b/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/HttpContentRenderer.php @@ -0,0 +1,176 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpKernel; + +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\HttpFoundation\StreamedResponse; +use Symfony\Component\HttpKernel\Controller\ControllerReference; +use Symfony\Component\HttpKernel\Event\GetResponseEvent; +use Symfony\Component\HttpKernel\Event\FilterResponseEvent; +use Symfony\Component\HttpKernel\RenderingStrategy\RenderingStrategyInterface; +use Symfony\Component\EventDispatcher\EventSubscriberInterface; + +/** + * Renders a URI using different strategies. + * + * This class handles sub-requests. The response content from the sub-request + * is then embedded into a master request. The handling of the sub-request + * is managed by rendering strategies. + * + * @author Fabien Potencier <fabien@symfony.com> + * + * @see RenderingStrategyInterface + */ +class HttpContentRenderer implements EventSubscriberInterface +{ + private $debug; + private $strategies; + private $requests; + + /** + * Constructor. + * + * @param RenderingStrategyInterface[] $strategies An array of RenderingStrategyInterface instances + * @param Boolean $debug Whether the debug mode is enabled or not + */ + public function __construct(array $strategies = array(), $debug = false) + { + $this->strategies = array(); + foreach ($strategies as $strategy) { + $this->addStrategy($strategy); + } + $this->debug = $debug; + $this->requests = array(); + } + + /** + * Adds a rendering strategy. + * + * @param RenderingStrategyInterface $strategy A RenderingStrategyInterface instance + */ + public function addStrategy(RenderingStrategyInterface $strategy) + { + $this->strategies[$strategy->getName()] = $strategy; + } + + /** + * Stores the Request object. + * + * @param GetResponseEvent $event A GetResponseEvent instance + */ + public function onKernelRequest(GetResponseEvent $event) + { + array_unshift($this->requests, $event->getRequest()); + } + + /** + * Removes the most recent Request object. + * + * @param FilterResponseEvent $event A FilterResponseEvent instance + */ + public function onKernelResponse(FilterResponseEvent $event) + { + array_shift($this->requests); + } + + /** + * Renders a URI and returns the Response content. + * + * Available options: + * + * * ignore_errors: true to return an empty string in case of an error + * + * @param string|ControllerReference $uri A URI as a string or a ControllerReference instance + * @param string $strategy The strategy to use for the rendering + * @param array $options An array of options + * + * @return string|null The Response content or null when the Response is streamed + * + * @throws \InvalidArgumentException when the strategy does not exist + * @throws \RuntimeException when the Response is not successful + */ + public function render($uri, $strategy = 'default', array $options = array()) + { + if (!isset($options['ignore_errors'])) { + $options['ignore_errors'] = !$this->debug; + } + + if (!isset($this->strategies[$strategy])) { + throw new \InvalidArgumentException(sprintf('The "%s" rendering strategy does not exist.', $strategy)); + } + + return $this->deliver($this->strategies[$strategy]->render($uri, $this->requests[0], $options)); + } + + /** + * Delivers the Response as a string. + * + * When the Response is a StreamedResponse, the content is streamed immediately + * instead of being returned. + * + * @param Response $response A Response instance + * + * @return string|null The Response content or null when the Response is streamed + * + * @throws \RuntimeException when the Response is not successful + */ + protected function deliver(Response $response) + { + if (!$response->isSuccessful()) { + throw new \RuntimeException(sprintf('Error when rendering "%s" (Status code is %s).', $this->requests[0]->getUri(), $response->getStatusCode())); + } + + if (!$response instanceof StreamedResponse) { + return $response->getContent(); + } + + $response->sendContent(); + } + + public static function getSubscribedEvents() + { + return array( + KernelEvents::REQUEST => 'onKernelRequest', + KernelEvents::RESPONSE => 'onKernelResponse', + ); + } + + // to be removed in 2.3 + public function fixOptions(array $options) + { + // support for the standalone option is @deprecated in 2.2 and replaced with the strategy option + if (isset($options['standalone'])) { + trigger_error('The "standalone" option is deprecated in version 2.2 and replaced with the "strategy" option.', E_USER_DEPRECATED); + + // support for the true value is @deprecated in 2.2, will be removed in 2.3 + if (true === $options['standalone']) { + trigger_error('The "true" value for the "standalone" option is deprecated in version 2.2 and replaced with the "esi" value.', E_USER_DEPRECATED); + + $options['standalone'] = 'esi'; + } elseif (false === $options['standalone']) { + trigger_error('The "false" value for the "standalone" option is deprecated in version 2.2 and replaced with the "default" value.', E_USER_DEPRECATED); + + $options['standalone'] = 'default'; + } elseif ('js' === $options['standalone']) { + trigger_error('The "js" value for the "standalone" option is deprecated in version 2.2 and replaced with the "hinclude" value.', E_USER_DEPRECATED); + + $options['standalone'] = 'hinclude'; + } + + $options['strategy'] = $options['standalone']; + unset($options['standalone']); + } + + return $options; + } +} diff --git a/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Kernel.php b/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Kernel.php index 46440a346871..f1752f517876 100644 --- a/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Kernel.php +++ b/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Kernel.php @@ -62,12 +62,12 @@ abstract class Kernel implements KernelInterface, TerminableInterface protected $classes; protected $errorReportingLevel; - const VERSION = '2.2.0-DEV'; + const VERSION = '2.2.0-BETA2'; const VERSION_ID = '20100'; const MAJOR_VERSION = '2'; const MINOR_VERSION = '2'; const RELEASE_VERSION = '0'; - const EXTRA_VERSION = 'DEV'; + const EXTRA_VERSION = 'BETA2'; /** * Constructor. diff --git a/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Log/LoggerInterface.php b/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Log/LoggerInterface.php index 34847c8098f0..148c92c4cc31 100644 --- a/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Log/LoggerInterface.php +++ b/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Log/LoggerInterface.php @@ -11,52 +11,39 @@ namespace Symfony\Component\HttpKernel\Log; +use Psr\Log\LoggerInterface as PsrLogger; + /** * LoggerInterface. * * @author Fabien Potencier <fabien@symfony.com> * + * @deprecated since 2.2, to be removed in 3.0. Type-hint \Psr\Log\LoggerInterface instead. * @api */ -interface LoggerInterface +interface LoggerInterface extends PsrLogger { /** * @api + * @deprecated since 2.2, to be removed in 3.0. Use emergency() which is PSR-3 compatible. */ public function emerg($message, array $context = array()); /** * @api - */ - public function alert($message, array $context = array()); - - /** - * @api + * @deprecated since 2.2, to be removed in 3.0. Use critical() which is PSR-3 compatible. */ public function crit($message, array $context = array()); /** * @api + * @deprecated since 2.2, to be removed in 3.0. Use error() which is PSR-3 compatible. */ public function err($message, array $context = array()); /** * @api + * @deprecated since 2.2, to be removed in 3.0. Use warning() which is PSR-3 compatible. */ public function warn($message, array $context = array()); - - /** - * @api - */ - public function notice($message, array $context = array()); - - /** - * @api - */ - public function info($message, array $context = array()); - - /** - * @api - */ - public function debug($message, array $context = array()); } diff --git a/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Log/NullLogger.php b/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Log/NullLogger.php index 8edec8913ba9..8c1dfaa3b332 100644 --- a/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Log/NullLogger.php +++ b/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Log/NullLogger.php @@ -11,7 +11,7 @@ namespace Symfony\Component\HttpKernel\Log; -use Symfony\Component\HttpKernel\Log\LoggerInterface; +use Psr\Log\NullLogger as PsrNullLogger; /** * NullLogger. @@ -20,10 +20,11 @@ * * @api */ -class NullLogger implements LoggerInterface +class NullLogger extends PsrNullLogger { /** * @api + * @deprecated since 2.2, to be removed in 3.0. Use emergency() which is PSR-3 compatible. */ public function emerg($message, array $context = array()) { @@ -31,13 +32,7 @@ public function emerg($message, array $context = array()) /** * @api - */ - public function alert($message, array $context = array()) - { - } - - /** - * @api + * @deprecated since 2.2, to be removed in 3.0. Use critical() which is PSR-3 compatible. */ public function crit($message, array $context = array()) { @@ -45,6 +40,7 @@ public function crit($message, array $context = array()) /** * @api + * @deprecated since 2.2, to be removed in 3.0. Use error() which is PSR-3 compatible. */ public function err($message, array $context = array()) { @@ -52,29 +48,9 @@ public function err($message, array $context = array()) /** * @api + * @deprecated since 2.2, to be removed in 3.0. Use warning() which is PSR-3 compatible. */ public function warn($message, array $context = array()) { } - - /** - * @api - */ - public function notice($message, array $context = array()) - { - } - - /** - * @api - */ - public function info($message, array $context = array()) - { - } - - /** - * @api - */ - public function debug($message, array $context = array()) - { - } } diff --git a/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Profiler/FileProfilerStorage.php b/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Profiler/FileProfilerStorage.php index 41287c825a9c..25d0fdde16d8 100644 --- a/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Profiler/FileProfilerStorage.php +++ b/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Profiler/FileProfilerStorage.php @@ -61,17 +61,13 @@ public function find($ip, $url, $limit, $method, $start = null, $end = null) $result = array(); - while ($limit > 0) { + for (;$limit > 0; $limit--) { $line = $this->readLineFromFile($file); - if (false === $line) { + if (null === $line) { break; } - if ($line === '') { - continue; - } - list($csvToken, $csvIp, $csvMethod, $csvUrl, $csvTime, $csvParent) = str_getcsv($line); $csvTime = (int) $csvTime; @@ -96,7 +92,6 @@ public function find($ip, $url, $limit, $method, $start = null, $end = null) 'time' => $csvTime, 'parent' => $csvParent, ); - --$limit; } fclose($file); @@ -213,44 +208,50 @@ protected function getIndexFilename() } /** - * Reads a line in the file, ending with the current position. + * Reads a line in the file, backward. * * This function automatically skips the empty lines and do not include the line return in result value. * * @param resource $file The file resource, with the pointer placed at the end of the line to read * - * @return mixed A string representing the line or FALSE if beginning of file is reached + * @return mixed A string representing the line or null if beginning of file is reached */ protected function readLineFromFile($file) { - if (ftell($file) === 0) { - return false; - } + $line = ''; + $position = ftell($file); - fseek($file, -1, SEEK_CUR); - $str = ''; + if (0 === $position) { + return null; + } - while (true) { - $char = fgetc($file); + while(true) { + $chunkSize = min($position, 1024); + $position -= $chunkSize; + fseek($file, $position); - if ($char === "\n") { - // Leave the file with cursor before the line return - fseek($file, -1, SEEK_CUR); + if (0 === $chunkSize) { + // bof reached break; } - $str = $char.$str; + $buffer = fread($file, $chunkSize); - if (ftell($file) === 1) { - // All file is read, so we move cursor to the position 0 - fseek($file, -1, SEEK_CUR); - break; + if (false === ($upTo = strrpos($buffer, "\n"))) { + $line = $buffer . $line; + continue; } - fseek($file, -2, SEEK_CUR); + $position += $upTo; + $line = substr($buffer, $upTo + 1) . $line; + fseek($file, max(0, $position), SEEK_SET); + + if ('' !== $line) { + break; + } } - return $str === '' ? $this->readLineFromFile($file) : $str; + return '' === $line ? null : $line; } protected function createProfileFromData($token, $data, $parent = null) diff --git a/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Profiler/Profiler.php b/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Profiler/Profiler.php index ea93a24aea18..1ca3e973034f 100644 --- a/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Profiler/Profiler.php +++ b/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Profiler/Profiler.php @@ -15,7 +15,7 @@ use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\Profiler\ProfilerStorageInterface; use Symfony\Component\HttpKernel\DataCollector\DataCollectorInterface; -use Symfony\Component\HttpKernel\Log\LoggerInterface; +use Psr\Log\LoggerInterface; /** * Profiler. @@ -110,7 +110,7 @@ public function loadProfile($token) public function saveProfile(Profile $profile) { if (!($ret = $this->storage->write($profile)) && null !== $this->logger) { - $this->logger->warn('Unable to store the profiler information.'); + $this->logger->warning('Unable to store the profiler information.'); } return $ret; diff --git a/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Profiler/RedisProfilerStorage.php b/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Profiler/RedisProfilerStorage.php index 5c143129c086..d62d6c7996d0 100644 --- a/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Profiler/RedisProfilerStorage.php +++ b/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Profiler/RedisProfilerStorage.php @@ -17,6 +17,7 @@ * RedisProfilerStorage stores profiling information in Redis. * * @author Andrej Hudec <pulzarraider@gmail.com> + * @author Stephane PY <py.stephane1@gmail.com> */ class RedisProfilerStorage implements ProfilerStorageInterface { @@ -60,7 +61,7 @@ public function find($ip, $url, $limit, $method, $start = null, $end = null) return array(); } - $profileList = explode("\n", $indexContent); + $profileList = array_reverse(explode("\n", $indexContent)); $result = array(); foreach ($profileList as $item) { @@ -88,7 +89,7 @@ public function find($ip, $url, $limit, $method, $start = null, $end = null) continue; } - $result[$itemToken] = array( + $result[] = array( 'token' => $itemToken, 'ip' => $itemIp, 'method' => $itemMethod, @@ -99,14 +100,6 @@ public function find($ip, $url, $limit, $method, $start = null, $end = null) --$limit; } - usort($result, function($a, $b) { - if ($a['time'] === $b['time']) { - return 0; - } - - return $a['time'] > $b['time'] ? -1 : 1; - }); - return $result; } @@ -213,19 +206,26 @@ public function write(Profile $profile) protected function getRedis() { if (null === $this->redis) { - if (!preg_match('#^redis://(?(?=\[.*\])\[(.*)\]|(.*)):(.*)$#', $this->dsn, $matches)) { - throw new \RuntimeException(sprintf('Please check your configuration. You are trying to use Redis with an invalid dsn "%s". The expected format is "redis://[host]:port".', $this->dsn)); - } + $data = parse_url($this->dsn); - $host = $matches[1] ?: $matches[2]; - $port = $matches[3]; + if (false === $data || !isset($data['scheme']) || $data['scheme'] !== 'redis' || !isset($data['host']) || !isset($data['port'])) { + throw new \RuntimeException(sprintf('Please check your configuration. You are trying to use Redis with an invalid dsn "%s". The minimal expected format is "redis://[host]:port".', $this->dsn)); + } if (!extension_loaded('redis')) { throw new \RuntimeException('RedisProfilerStorage requires that the redis extension is loaded.'); } $redis = new Redis; - $redis->connect($host, $port); + $redis->connect($data['host'], $data['port']); + + if (isset($data['path'])) { + $redis->select(substr($data['path'], 1)); + } + + if (isset($data['pass'])) { + $redis->auth($data['pass']); + } $redis->setOption(self::REDIS_OPT_PREFIX, self::TOKEN_PREFIX); diff --git a/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/RenderingStrategy/DefaultRenderingStrategy.php b/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/RenderingStrategy/DefaultRenderingStrategy.php new file mode 100644 index 000000000000..5a3427e05e3c --- /dev/null +++ b/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/RenderingStrategy/DefaultRenderingStrategy.php @@ -0,0 +1,100 @@ +<?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\HttpKernel\RenderingStrategy; + +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\HttpKernel\HttpKernelInterface; +use Symfony\Component\HttpKernel\Controller\ControllerReference; + +/** + * Implements the default rendering strategy where the Request is rendered by the current HTTP kernel. + * + * @author Fabien Potencier <fabien@symfony.com> + */ +class DefaultRenderingStrategy extends ProxyAwareRenderingStrategy +{ + private $kernel; + + /** + * Constructor. + * + * @param HttpKernelInterface $kernel A HttpKernelInterface instance + */ + public function __construct(HttpKernelInterface $kernel) + { + $this->kernel = $kernel; + } + + /** + * {@inheritdoc} + * + * Additional available options: + * + * * alt: an alternative URI to render in case of an error + */ + public function render($uri, Request $request, array $options = array()) + { + if ($uri instanceof ControllerReference) { + $uri = $this->generateProxyUri($uri, $request); + } + + $subRequest = $this->createSubRequest($uri, $request); + + $level = ob_get_level(); + try { + return $this->kernel->handle($subRequest, HttpKernelInterface::SUB_REQUEST, false); + } catch (\Exception $e) { + // let's clean up the output buffers that were created by the sub-request + while (ob_get_level() > $level) { + ob_get_clean(); + } + + if (isset($options['alt'])) { + $alt = $options['alt']; + unset($options['alt']); + + return $this->render($alt, $request, $options); + } + + if (!isset($options['ignore_errors']) || !$options['ignore_errors']) { + throw $e; + } + + return new Response(); + } + } + + protected function createSubRequest($uri, Request $request) + { + $cookies = $request->cookies->all(); + $server = $request->server->all(); + + // the sub-request is internal + $server['REMOTE_ADDR'] = '127.0.0.1'; + + $subRequest = Request::create($uri, 'get', array(), $cookies, array(), $server); + if ($session = $request->getSession()) { + $subRequest->setSession($session); + } + + return $subRequest; + } + + /** + * {@inheritdoc} + */ + public function getName() + { + return 'default'; + } +} diff --git a/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/RenderingStrategy/EsiRenderingStrategy.php b/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/RenderingStrategy/EsiRenderingStrategy.php new file mode 100644 index 000000000000..195066d00494 --- /dev/null +++ b/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/RenderingStrategy/EsiRenderingStrategy.php @@ -0,0 +1,85 @@ +<?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\HttpKernel\RenderingStrategy; + +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\HttpKernel\Controller\ControllerReference; +use Symfony\Component\HttpKernel\HttpCache\Esi; + +/** + * Implements the ESI rendering strategy. + * + * @author Fabien Potencier <fabien@symfony.com> + */ +class EsiRenderingStrategy extends ProxyAwareRenderingStrategy +{ + private $esi; + private $defaultStrategy; + + /** + * Constructor. + * + * The "fallback" strategy when ESI is not available should always be an + * instance of DefaultRenderingStrategy (or a class you are using for the + * default strategy). + * + * @param Esi $esi An Esi instance + * @param RenderingStrategyInterface $defaultStrategy The default strategy to use when ESI is not supported + */ + public function __construct(Esi $esi, RenderingStrategyInterface $defaultStrategy) + { + $this->esi = $esi; + $this->defaultStrategy = $defaultStrategy; + } + + /** + * {@inheritdoc} + * + * Note that if the current Request has no ESI capability, this method + * falls back to use the default rendering strategy. + * + * Additional available options: + * + * * alt: an alternative URI to render in case of an error + * * comment: a comment to add when returning an esi:include tag + * + * @see Symfony\Component\HttpKernel\HttpCache\ESI + */ + public function render($uri, Request $request, array $options = array()) + { + if (!$this->esi->hasSurrogateEsiCapability($request)) { + return $this->defaultStrategy->render($uri, $request, $options); + } + + if ($uri instanceof ControllerReference) { + $uri = $this->generateProxyUri($uri, $request); + } + + $alt = isset($options['alt']) ? $options['alt'] : null; + if ($alt instanceof ControllerReference) { + $alt = $this->generateProxyUri($alt, $request); + } + + $tag = $this->esi->renderIncludeTag($uri, $alt, isset($options['ignore_errors']) ? $options['ignore_errors'] : false, isset($options['comment']) ? $options['comment'] : ''); + + return new Response($tag); + } + + /** + * {@inheritdoc} + */ + public function getName() + { + return 'esi'; + } +} diff --git a/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/RenderingStrategy/HIncludeRenderingStrategy.php b/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/RenderingStrategy/HIncludeRenderingStrategy.php new file mode 100644 index 000000000000..dd9f2d21fe0a --- /dev/null +++ b/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/RenderingStrategy/HIncludeRenderingStrategy.php @@ -0,0 +1,105 @@ +<?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\HttpKernel\RenderingStrategy; + +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\Templating\EngineInterface; +use Symfony\Component\HttpKernel\Controller\ControllerReference; +use Symfony\Component\HttpKernel\UriSigner; + +/** + * Implements the Hinclude rendering strategy. + * + * @author Fabien Potencier <fabien@symfony.com> + */ +class HIncludeRenderingStrategy extends ProxyAwareRenderingStrategy +{ + protected $templating; + + private $globalDefaultTemplate; + private $signer; + + /** + * Constructor. + * + * @param EngineInterface|\Twig_Environment $templating An EngineInterface or a \Twig_Environment instance + * @param UriSigner $signer A UriSigner instance + * @param string $globalDefaultTemplate The global default content (it can be a template name or the content) + */ + public function __construct($templating = null, UriSigner $signer = null, $globalDefaultTemplate = null) + { + if (null !== $templating && !$templating instanceof EngineInterface && !$templating instanceof \Twig_Environment) { + throw new \InvalidArgumentException('The hinclude rendering strategy needs an instance of \Twig_Environment or Symfony\Component\Templating\EngineInterface'); + } + + $this->templating = $templating; + $this->globalDefaultTemplate = $globalDefaultTemplate; + $this->signer = $signer; + } + + /** + * {@inheritdoc} + * + * Additional available options: + * + * * default: The default content (it can be a template name or the content) + */ + public function render($uri, Request $request, array $options = array()) + { + if ($uri instanceof ControllerReference) { + if (null === $this->signer) { + throw new \LogicException('You must use a proper URI when using the Hinclude rendering strategy or set a URL signer.'); + } + + $uri = $this->signer->sign($this->generateProxyUri($uri, $request)); + } + + $template = isset($options['default']) ? $options['default'] : $this->globalDefaultTemplate; + if (null !== $this->templating && $this->templateExists($template)) { + $content = $this->templating->render($template); + } else { + $content = $template; + } + + return new Response(sprintf('<hx:include src="%s">%s</hx:include>', $uri, $content)); + } + + private function templateExists($template) + { + if ($this->templating instanceof EngineInterface) { + return $this->templating->exists($template); + } + + $loader = $this->templating->getLoader(); + if ($loader instanceof \Twig_ExistsLoaderInterface) { + return $loader->exists($template); + } + + try { + $loader->getSource($template); + + return true; + } catch (\Twig_Error_Loader $e) { + } + + return false; + } + + /** + * {@inheritdoc} + */ + public function getName() + { + return 'hinclude'; + } +} diff --git a/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/RenderingStrategy/ProxyAwareRenderingStrategy.php b/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/RenderingStrategy/ProxyAwareRenderingStrategy.php new file mode 100644 index 000000000000..3c735efdeefe --- /dev/null +++ b/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/RenderingStrategy/ProxyAwareRenderingStrategy.php @@ -0,0 +1,59 @@ +<?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\HttpKernel\RenderingStrategy; + +use Symfony\Component\HttpKernel\Controller\ControllerReference; +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpKernel\EventListener\RouterProxyListener; + +/** + * Adds the possibility to generate a proxy URI for a given Controller. + * + * @author Fabien Potencier <fabien@symfony.com> + */ +abstract class ProxyAwareRenderingStrategy implements RenderingStrategyInterface +{ + private $proxyPath = '/_proxy'; + + /** + * Sets the proxy path that triggers the proxy listener + * + * @param string $path The path + * + * @see RouterProxyListener + */ + public function setProxyPath($path) + { + $this->proxyPath = $path; + } + + /** + * Generates a proxy URI for a given controller. + * + * @param ControllerReference $reference A ControllerReference instance + * @param Request $request A Request instance + * + * @return string A proxy URI + */ + protected function generateProxyUri(ControllerReference $reference, Request $request) + { + if (!isset($reference->attributes['_format'])) { + $reference->attributes['_format'] = $request->getRequestFormat(); + } + + $reference->attributes['_controller'] = $reference->controller; + + $reference->query['_path'] = http_build_query($reference->attributes, '', '&'); + + return $request->getUriForPath($this->proxyPath.'?'.http_build_query($reference->query, '', '&')); + } +} diff --git a/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/RenderingStrategy/RenderingStrategyInterface.php b/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/RenderingStrategy/RenderingStrategyInterface.php new file mode 100644 index 000000000000..b4f8b8e50b40 --- /dev/null +++ b/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/RenderingStrategy/RenderingStrategyInterface.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\HttpKernel\RenderingStrategy; + +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpKernel\Controller\ControllerReference; + +/** + * Interface implemented by all rendering strategies. + * + * @author Fabien Potencier <fabien@symfony.com> + * + * @see Symfony\Component\HttpKernel\HttpContentRenderer + */ +interface RenderingStrategyInterface +{ + /** + * Renders a URI and returns the Response content. + * + * @param string|ControllerReference $uri A URI as a string or a ControllerReference instance + * @param Request $request A Request instance + * @param array $options An array of options + * + * @return Response A Response instance + */ + public function render($uri, Request $request, array $options = array()); + + /** + * Gets the name of the strategy. + * + * @return string The strategy name + */ + public function getName(); +} diff --git a/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Tests/Controller/ControllerResolverTest.php b/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Tests/Controller/ControllerResolverTest.php index d0afdf33182f..c19af8216dda 100644 --- a/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Tests/Controller/ControllerResolverTest.php +++ b/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Tests/Controller/ControllerResolverTest.php @@ -30,7 +30,7 @@ public function testGetController() $request = Request::create('/'); $this->assertFalse($resolver->getController($request), '->getController() returns false when the request has no _controller attribute'); - $this->assertEquals(array('Unable to look for the controller as the "_controller" parameter is missing'), $logger->getLogs('warn')); + $this->assertEquals(array('Unable to look for the controller as the "_controller" parameter is missing'), $logger->getLogs('warning')); $request->attributes->set('_controller', 'Symfony\Component\HttpKernel\Tests\ControllerResolverTest::testGetController'); $controller = $resolver->getController($request); diff --git a/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Tests/Debug/ErrorHandlerTest.php b/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Tests/Debug/ErrorHandlerTest.php index fdd02eaaf595..637c7ad376a0 100644 --- a/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Tests/Debug/ErrorHandlerTest.php +++ b/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Tests/Debug/ErrorHandlerTest.php @@ -67,15 +67,11 @@ public function testHandle() restore_error_handler(); - $logger = $this->getMock('Symfony\Component\HttpKernel\Log\LoggerInterface'); + $logger = $this->getMock('Psr\Log\LoggerInterface'); $that = $this; $warnArgCheck = function($message, $context) use ($that) { $that->assertEquals('foo', $message); - $that->assertArrayHasKey('file', $context); - $that->assertEquals($context['file'], 'foo.php'); - $that->assertArrayHasKey('line', $context); - $that->assertEquals($context['line'], 12); $that->assertArrayHasKey('type', $context); $that->assertEquals($context['type'], ErrorHandler::TYPE_DEPRECATION); $that->assertArrayHasKey('stack', $context); @@ -84,7 +80,7 @@ public function testHandle() $logger ->expects($this->once()) - ->method('warn') + ->method('warning') ->will($this->returnCallback($warnArgCheck)) ; diff --git a/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Tests/Debug/TraceableEventDispatcherTest.php b/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Tests/Debug/TraceableEventDispatcherTest.php index 07faa8a688eb..e1679d977ee9 100644 --- a/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Tests/Debug/TraceableEventDispatcherTest.php +++ b/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Tests/Debug/TraceableEventDispatcherTest.php @@ -102,7 +102,7 @@ public function testGetCalledListeners() public function testLogger() { - $logger = $this->getMock('Symfony\Component\HttpKernel\Log\LoggerInterface'); + $logger = $this->getMock('Psr\Log\LoggerInterface'); $dispatcher = new EventDispatcher(); $tdispatcher = new TraceableEventDispatcher($dispatcher, new Stopwatch(), $logger); @@ -117,7 +117,7 @@ public function testLogger() public function testLoggerWithStoppedEvent() { - $logger = $this->getMock('Symfony\Component\HttpKernel\Log\LoggerInterface'); + $logger = $this->getMock('Psr\Log\LoggerInterface'); $dispatcher = new EventDispatcher(); $tdispatcher = new TraceableEventDispatcher($dispatcher, new Stopwatch(), $logger); diff --git a/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Tests/DependencyInjection/ContainerAwareHttpKernelTest.php b/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Tests/DependencyInjection/ContainerAwareHttpKernelTest.php new file mode 100644 index 000000000000..80d5ffa61a66 --- /dev/null +++ b/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Tests/DependencyInjection/ContainerAwareHttpKernelTest.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\HttpKernel\Tests; + +use Symfony\Component\HttpKernel\HttpKernelInterface; +use Symfony\Component\HttpKernel\DependencyInjection\ContainerAwareHttpKernel; +use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\EventDispatcher\EventDispatcher; + +class ContainerAwareHttpKernelTest extends \PHPUnit_Framework_TestCase +{ + protected function setUp() + { + if (!class_exists('Symfony\Component\DependencyInjection\Container')) { + $this->markTestSkipped('The "DependencyInjection" component is not available'); + } + + if (!class_exists('Symfony\Component\EventDispatcher\EventDispatcher')) { + $this->markTestSkipped('The "EventDispatcher" component is not available'); + } + + if (!class_exists('Symfony\Component\HttpFoundation\Request')) { + $this->markTestSkipped('The "HttpFoundation" component is not available'); + } + } + + /** + * @dataProvider getProviderTypes + */ + public function testHandle($type) + { + $request = new Request(); + $expected = new Response(); + + $container = $this->getMock('Symfony\Component\DependencyInjection\ContainerInterface'); + $container + ->expects($this->once()) + ->method('enterScope') + ->with($this->equalTo('request')) + ; + $container + ->expects($this->once()) + ->method('leaveScope') + ->with($this->equalTo('request')) + ; + $container + ->expects($this->once()) + ->method('set') + ->with($this->equalTo('request'), $this->equalTo($request), $this->equalTo('request')) + ; + + $dispatcher = new EventDispatcher(); + $resolver = $this->getMock('Symfony\\Component\\HttpKernel\\Controller\\ControllerResolverInterface'); + $kernel = new ContainerAwareHttpKernel($dispatcher, $container, $resolver); + + $controller = function() use ($expected) { + return $expected; + }; + + $resolver->expects($this->once()) + ->method('getController') + ->with($request) + ->will($this->returnValue($controller)); + $resolver->expects($this->once()) + ->method('getArguments') + ->with($request, $controller) + ->will($this->returnValue(array())); + + $actual = $kernel->handle($request, $type); + + $this->assertSame($expected, $actual, '->handle() returns the response'); + } + + /** + * @dataProvider getProviderTypes + */ + public function testHandleRestoresThePreviousRequestOnException($type) + { + $request = new Request(); + $expected = new \Exception(); + + $container = $this->getMock('Symfony\Component\DependencyInjection\ContainerInterface'); + $container + ->expects($this->once()) + ->method('enterScope') + ->with($this->equalTo('request')) + ; + $container + ->expects($this->once()) + ->method('leaveScope') + ->with($this->equalTo('request')) + ; + $container + ->expects($this->once()) + ->method('set') + ->with($this->equalTo('request'), $this->equalTo($request), $this->equalTo('request')) + ; + + $dispatcher = new EventDispatcher(); + $resolver = $this->getMock('Symfony\\Component\\HttpKernel\\Controller\\ControllerResolverInterface'); + $kernel = new ContainerAwareHttpKernel($dispatcher, $container, $resolver); + + $controller = function() use ($expected) { + throw $expected; + }; + + $resolver->expects($this->once()) + ->method('getController') + ->with($request) + ->will($this->returnValue($controller)); + $resolver->expects($this->once()) + ->method('getArguments') + ->with($request, $controller) + ->will($this->returnValue(array())); + + try { + $kernel->handle($request, $type); + $this->fail('->handle() suppresses the controller exception'); + } catch (\Exception $actual) { + $this->assertSame($expected, $actual, '->handle() throws the controller exception'); + } + } + + public function getProviderTypes() + { + return array( + array(HttpKernelInterface::MASTER_REQUEST), + array(HttpKernelInterface::SUB_REQUEST), + ); + } +} diff --git a/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Tests/EventListener/ExceptionListenerTest.php b/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Tests/EventListener/ExceptionListenerTest.php index a10ae9b6fbd3..41b3dec0f528 100644 --- a/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Tests/EventListener/ExceptionListenerTest.php +++ b/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Tests/EventListener/ExceptionListenerTest.php @@ -93,7 +93,7 @@ public function testHandleWithLogger($event, $event2) } $this->assertEquals(3, $logger->countErrors()); - $this->assertCount(3, $logger->getLogs('crit')); + $this->assertCount(3, $logger->getLogs('critical')); } public function provider() @@ -117,7 +117,7 @@ class TestLogger extends Logger implements DebugLoggerInterface { public function countErrors() { - return count($this->logs['crit']); + return count($this->logs['critical']); } } diff --git a/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Tests/EventListener/RouterProxyListenerTest.php b/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Tests/EventListener/RouterProxyListenerTest.php new file mode 100644 index 000000000000..f4a3356f6caa --- /dev/null +++ b/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Tests/EventListener/RouterProxyListenerTest.php @@ -0,0 +1,101 @@ +<?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\HttpKernel\Tests\EventListener; + +use Symfony\Component\HttpKernel\EventListener\RouterProxyListener; +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpKernel\HttpKernelInterface; +use Symfony\Component\HttpKernel\Event\GetResponseEvent; +use Symfony\Component\HttpKernel\UriSigner; + +class RouterProxyListenerTest extends \PHPUnit_Framework_TestCase +{ + protected function setUp() + { + if (!class_exists('Symfony\Component\EventDispatcher\EventDispatcher')) { + $this->markTestSkipped('The "EventDispatcher" component is not available'); + } + } + + public function testOnlyTriggeredOnProxyRoute() + { + $request = Request::create('http://example.com/foo?_path=foo%3Dbar%26_controller%3Dfoo'); + + $listener = new RouterProxyListener(new UriSigner('foo')); + $event = $this->createGetResponseEvent($request); + + $expected = $request->attributes->all(); + + $listener->onKernelRequest($event); + + $this->assertEquals($expected, $request->attributes->all()); + $this->assertTrue($request->query->has('_path')); + } + + /** + * @expectedException \Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException + */ + public function testAccessDeniedWithNonSafeMethods() + { + $request = Request::create('http://example.com/_proxy', 'POST'); + + $listener = new RouterProxyListener(new UriSigner('foo')); + $event = $this->createGetResponseEvent($request); + + $listener->onKernelRequest($event); + } + + /** + * @expectedException \Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException + */ + public function testAccessDeniedWithNonLocalIps() + { + $request = Request::create('http://example.com/_proxy', 'GET', array(), array(), array(), array('REMOTE_ADDR' => '10.0.0.1')); + + $listener = new RouterProxyListener(new UriSigner('foo')); + $event = $this->createGetResponseEvent($request); + + $listener->onKernelRequest($event); + } + + /** + * @expectedException \Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException + */ + public function testAccessDeniedWithWrongSignature() + { + $request = Request::create('http://example.com/_proxy', 'GET', array(), array(), array(), array('REMOTE_ADDR' => '10.0.0.1')); + + $listener = new RouterProxyListener(new UriSigner('foo')); + $event = $this->createGetResponseEvent($request); + + $listener->onKernelRequest($event); + } + + public function testWithSignature() + { + $signer = new UriSigner('foo'); + $request = Request::create($signer->sign('http://example.com/_proxy?_path=foo%3Dbar%26_controller%3Dfoo'), 'GET', array(), array(), array(), array('REMOTE_ADDR' => '10.0.0.1')); + + $listener = new RouterProxyListener($signer); + $event = $this->createGetResponseEvent($request); + + $listener->onKernelRequest($event); + + $this->assertEquals(array('foo' => 'bar', '_controller' => 'foo'), $request->attributes->get('_route_params')); + $this->assertFalse($request->query->has('_path')); + } + + private function createGetResponseEvent(Request $request) + { + return new GetResponseEvent($this->getMock('Symfony\Component\HttpKernel\HttpKernelInterface'), $request, HttpKernelInterface::MASTER_REQUEST); + } +} diff --git a/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Tests/HttpContentRendererTest.php b/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Tests/HttpContentRendererTest.php new file mode 100644 index 000000000000..38305c93d03d --- /dev/null +++ b/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Tests/HttpContentRendererTest.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\HttpKernel\Tests; + +use Symfony\Component\HttpKernel\HttpContentRenderer; +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; + +class HttpContentRendererTest extends \PHPUnit_Framework_TestCase +{ + protected function setUp() + { + if (!class_exists('Symfony\Component\EventDispatcher\EventDispatcher')) { + $this->markTestSkipped('The "EventDispatcher" component is not available'); + } + } + + /** + * @expectedException \InvalidArgumentException + */ + public function testRenderWhenStrategyDoesNotExist() + { + $renderer = new HttpContentRenderer(); + $renderer->render('/', 'foo'); + } + + /** + * @expectedException InvalidArgumentException + */ + public function testRenderWithUnknownStrategy() + { + $strategy = $this->getStrategy($this->returnValue(new Response('foo'))); + $renderer = $this->getRenderer($strategy); + + $renderer->render('/', 'bar'); + } + + /** + * @expectedException RuntimeException + * @expectedExceptionMessage Error when rendering "http://localhost/" (Status code is 404). + */ + public function testDeliverWithUnsuccessfulResponse() + { + $strategy = $this->getStrategy($this->returnValue(new Response('foo', 404))); + $renderer = $this->getRenderer($strategy); + + $renderer->render('/', 'foo'); + } + + public function testRender() + { + $strategy = $this->getStrategy($this->returnValue(new Response('foo')), array('/', Request::create('/'), array('foo' => 'foo', 'ignore_errors' => true))); + $renderer = $this->getRenderer($strategy); + + $this->assertEquals('foo', $renderer->render('/', 'foo', array('foo' => 'foo'))); + } + + /** + * @dataProvider getFixOptionsData + */ + public function testFixOptions($expected, $options) + { + $renderer = new HttpContentRenderer(); + + set_error_handler(function ($errorNumber, $message, $file, $line, $context) { return $errorNumber & E_USER_DEPRECATED; }); + $this->assertEquals($expected, $renderer->fixOptions($options)); + restore_error_handler(); + } + + public function getFixOptionsData() + { + return array( + array(array('strategy' => 'esi'), array('standalone' => true)), + array(array('strategy' => 'esi'), array('standalone' => 'esi')), + array(array('strategy' => 'hinclude'), array('standalone' => 'js')), + ); + } + + protected function getStrategy($returnValue, $arguments = array()) + { + $strategy = $this->getMock('Symfony\Component\HttpKernel\RenderingStrategy\RenderingStrategyInterface'); + $strategy + ->expects($this->any()) + ->method('getName') + ->will($this->returnValue('foo')) + ; + $e = $strategy + ->expects($this->any()) + ->method('render') + ->will($returnValue) + ; + + if ($arguments) { + call_user_func_array(array($e, 'with'), $arguments); + } + + return $strategy; + } + + protected function getRenderer($strategy) + { + $renderer = new HttpContentRenderer(); + $renderer->addStrategy($strategy); + + $event = $this->getMockBuilder('Symfony\Component\HttpKernel\Event\GetResponseEvent')->disableOriginalConstructor()->getMock(); + $event + ->expects($this->once()) + ->method('getRequest') + ->will($this->returnValue(Request::create('/'))) + ; + $renderer->onKernelRequest($event); + + return $renderer; + } +} diff --git a/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Tests/HttpKernelTest.php b/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Tests/HttpKernelTest.php index 701e7a71e641..367e3e2d41d6 100644 --- a/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Tests/HttpKernelTest.php +++ b/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Tests/HttpKernelTest.php @@ -136,7 +136,7 @@ public function testHandleWhenAListenerReturnsAResponse() } /** - * @expectedException Symfony\Component\HttpKernel\Exception\NotFoundHttpException + * @expectedException \Symfony\Component\HttpKernel\Exception\NotFoundHttpException */ public function testHandleWhenNoControllerIsFound() { diff --git a/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Tests/Logger.php b/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Tests/Logger.php index 88babf3142c4..1be77f26ab99 100644 --- a/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Tests/Logger.php +++ b/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Tests/Logger.php @@ -11,7 +11,7 @@ namespace Symfony\Component\HttpKernel\Tests; -use Symfony\Component\HttpKernel\Log\LoggerInterface; +use Psr\Log\LoggerInterface; class Logger implements LoggerInterface { @@ -22,67 +22,107 @@ public function __construct() $this->clear(); } - public function getLogs($priority = false) + public function getLogs($level = false) { - return false === $priority ? $this->logs : $this->logs[$priority]; + return false === $level ? $this->logs : $this->logs[$level]; } public function clear() { $this->logs = array( - 'emerg' => array(), + 'emergency' => array(), 'alert' => array(), - 'crit' => array(), - 'err' => array(), - 'warn' => array(), + 'critical' => array(), + 'error' => array(), + 'warning' => array(), 'notice' => array(), 'info' => array(), 'debug' => array(), ); } - public function log($message, $priority) + public function log($level, $message, array $context = array()) { - $this->logs[$priority][] = $message; + $this->logs[$level][] = $message; } - public function emerg($message, array $context = array()) + public function emergency($message, array $context = array()) { - $this->log($message, 'emerg'); + $this->log('emergency', $message, $context); } public function alert($message, array $context = array()) { - $this->log($message, 'alert'); + $this->log('alert', $message, $context); } - public function crit($message, array $context = array()) + public function critical($message, array $context = array()) { - $this->log($message, 'crit'); + $this->log('critical', $message, $context); } - public function err($message, array $context = array()) + public function error($message, array $context = array()) { - $this->log($message, 'err'); + $this->log('error', $message, $context); } - public function warn($message, array $context = array()) + public function warning($message, array $context = array()) { - $this->log($message, 'warn'); + $this->log('warning', $message, $context); } public function notice($message, array $context = array()) { - $this->log($message, 'notice'); + $this->log('notice', $message, $context); } public function info($message, array $context = array()) { - $this->log($message, 'info'); + $this->log('info', $message, $context); } public function debug($message, array $context = array()) { - $this->log($message, 'debug'); + $this->log('debug', $message, $context); + } + + /** + * @deprecated + */ + public function emerg($message, array $context = array()) + { + trigger_error('Use emergency() which is PSR-3 compatible', E_USER_DEPRECATED); + + $this->log('emergency', $message, $context); + } + + /** + * @deprecated + */ + public function crit($message, array $context = array()) + { + trigger_error('Use crit() which is PSR-3 compatible', E_USER_DEPRECATED); + + $this->log('critical', $message, $context); + } + + /** + * @deprecated + */ + public function err($message, array $context = array()) + { + trigger_error('Use err() which is PSR-3 compatible', E_USER_DEPRECATED); + + $this->log('error', $message, $context); + } + + /** + * @deprecated + */ + public function warn($message, array $context = array()) + { + trigger_error('Use warn() which is PSR-3 compatible', E_USER_DEPRECATED); + + $this->log('warning', $message, $context); } } diff --git a/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Tests/Profiler/FileProfilerStorageTest.php b/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Tests/Profiler/FileProfilerStorageTest.php index ad225129d34b..21e0bf3df9a2 100644 --- a/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Tests/Profiler/FileProfilerStorageTest.php +++ b/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Tests/Profiler/FileProfilerStorageTest.php @@ -82,4 +82,19 @@ public function testMultiRowIndexFile() } $this->assertFalse(fgetcsv($handle)); } + + public function testReadLineFromFile() + { + $r = new \ReflectionMethod(self::$storage, 'readLineFromFile'); + + $r->setAccessible(true); + + $h = tmpfile(); + + fwrite($h, "line1\n\n\nline2\n"); + fseek($h, 0, SEEK_END); + + $this->assertEquals("line2", $r->invoke(self::$storage, $h)); + $this->assertEquals("line1", $r->invoke(self::$storage, $h)); + } } diff --git a/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Tests/RenderingStrategy/DefaultRenderingStrategyTest.php b/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Tests/RenderingStrategy/DefaultRenderingStrategyTest.php new file mode 100644 index 000000000000..5d1d4c92d6e3 --- /dev/null +++ b/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Tests/RenderingStrategy/DefaultRenderingStrategyTest.php @@ -0,0 +1,117 @@ +<?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\HttpKernel\Tests\RenderingStrategy; + +use Symfony\Component\HttpKernel\Controller\ControllerReference; +use Symfony\Component\HttpKernel\HttpKernel; +use Symfony\Component\HttpKernel\RenderingStrategy\DefaultRenderingStrategy; +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\EventDispatcher\EventDispatcher; + +class DefaultRenderingStrategyTest extends \PHPUnit_Framework_TestCase +{ + protected function setUp() + { + if (!class_exists('Symfony\Component\EventDispatcher\EventDispatcher')) { + $this->markTestSkipped('The "EventDispatcher" component is not available'); + } + + if (!class_exists('Symfony\Component\HttpFoundation\Request')) { + $this->markTestSkipped('The "HttpFoundation" component is not available'); + } + } + + public function testRender() + { + $strategy = new DefaultRenderingStrategy($this->getKernel($this->returnValue(new Response('foo')))); + + $this->assertEquals('foo', $strategy->render('/', Request::create('/'))->getContent()); + } + + public function testRenderWithControllerReference() + { + $strategy = new DefaultRenderingStrategy($this->getKernel($this->returnValue(new Response('foo')))); + + $this->assertEquals('foo', $strategy->render(new ControllerReference('main_controller', array(), array()), Request::create('/'))->getContent()); + } + + /** + * @expectedException \RuntimeException + */ + public function testRenderExceptionNoIgnoreErrors() + { + $strategy = new DefaultRenderingStrategy($this->getKernel($this->throwException(new \RuntimeException('foo')))); + + $this->assertEquals('foo', $strategy->render('/', Request::create('/'))->getContent()); + } + + public function testRenderExceptionIgnoreErrors() + { + $strategy = new DefaultRenderingStrategy($this->getKernel($this->throwException(new \RuntimeException('foo')))); + + $this->assertEmpty($strategy->render('/', Request::create('/'), array('ignore_errors' => true))->getContent()); + } + + public function testRenderExceptionIgnoreErrorsWithAlt() + { + $strategy = new DefaultRenderingStrategy($this->getKernel($this->onConsecutiveCalls( + $this->throwException(new \RuntimeException('foo')), + $this->returnValue(new Response('bar')) + ))); + + $this->assertEquals('bar', $strategy->render('/', Request::create('/'), array('ignore_errors' => true, 'alt' => '/foo'))->getContent()); + } + + private function getKernel($returnValue) + { + $kernel = $this->getMock('Symfony\Component\HttpKernel\HttpKernelInterface'); + $kernel + ->expects($this->any()) + ->method('handle') + ->will($returnValue) + ; + + return $kernel; + } + + public function testExceptionInSubRequestsDoesNotMangleOutputBuffers() + { + $resolver = $this->getMock('Symfony\\Component\\HttpKernel\\Controller\\ControllerResolverInterface'); + $resolver + ->expects($this->once()) + ->method('getController') + ->will($this->returnValue(function () { + ob_start(); + echo 'bar'; + throw new \RuntimeException(); + })) + ; + $resolver + ->expects($this->once()) + ->method('getArguments') + ->will($this->returnValue(array())) + ; + + $kernel = new HttpKernel(new EventDispatcher(), $resolver); + $renderer = new DefaultRenderingStrategy($kernel); + + // simulate a main request with output buffering + ob_start(); + echo 'Foo'; + + // simulate a sub-request with output buffering and an exception + $renderer->render('/', Request::create('/'), array('ignore_errors' => true)); + + $this->assertEquals('Foo', ob_get_clean()); + } +} diff --git a/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Tests/RenderingStrategy/EsiRenderingStrategyTest.php b/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Tests/RenderingStrategy/EsiRenderingStrategyTest.php new file mode 100644 index 000000000000..99c51926e43f --- /dev/null +++ b/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Tests/RenderingStrategy/EsiRenderingStrategyTest.php @@ -0,0 +1,63 @@ +<?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\HttpKernel\Tests\RenderingStrategy; + +use Symfony\Component\HttpKernel\Controller\ControllerReference; +use Symfony\Component\HttpKernel\RenderingStrategy\EsiRenderingStrategy; +use Symfony\Component\HttpKernel\HttpCache\Esi; +use Symfony\Component\HttpFoundation\Request; + +class EsiRenderingStrategyTest extends \PHPUnit_Framework_TestCase +{ + protected function setUp() + { + if (!class_exists('Symfony\Component\HttpFoundation\Request')) { + $this->markTestSkipped('The "HttpFoundation" component is not available'); + } + } + + public function testRenderFallbackToDefaultStrategyIfNoRequest() + { + $strategy = new EsiRenderingStrategy(new Esi(), $this->getDefaultStrategy(true)); + $strategy->render('/', Request::create('/')); + } + + public function testRenderFallbackToDefaultStrategyIfEsiNotSupported() + { + $strategy = new EsiRenderingStrategy(new Esi(), $this->getDefaultStrategy(true)); + $strategy->render('/', Request::create('/')); + } + + public function testRender() + { + $strategy = new EsiRenderingStrategy(new Esi(), $this->getDefaultStrategy()); + + $request = Request::create('/'); + $request->headers->set('Surrogate-Capability', 'ESI/1.0'); + + $this->assertEquals('<esi:include src="/" />', $strategy->render('/', $request)->getContent()); + $this->assertEquals("<esi:comment text=\"This is a comment\" />\n<esi:include src=\"/\" />", $strategy->render('/', $request, array('comment' => 'This is a comment'))->getContent()); + $this->assertEquals('<esi:include src="/" alt="foo" />', $strategy->render('/', $request, array('alt' => 'foo'))->getContent()); + $this->assertEquals('<esi:include src="http://localhost/_proxy?_path=_format%3Dhtml%26_controller%3Dmain_controller" alt="http://localhost/_proxy?_path=_format%3Dhtml%26_controller%3Dalt_controller" />', $strategy->render(new ControllerReference('main_controller', array(), array()), $request, array('alt' => new ControllerReference('alt_controller', array(), array())))->getContent()); + } + + private function getDefaultStrategy($called = false) + { + $default = $this->getMockBuilder('Symfony\Component\HttpKernel\RenderingStrategy\DefaultRenderingStrategy')->disableOriginalConstructor()->getMock(); + + if ($called) { + $default->expects($this->once())->method('render'); + } + + return $default; + } +} diff --git a/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Tests/RenderingStrategy/HIncludeRenderingStrategyTest.php b/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Tests/RenderingStrategy/HIncludeRenderingStrategyTest.php new file mode 100644 index 000000000000..7a5158d3ea43 --- /dev/null +++ b/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Tests/RenderingStrategy/HIncludeRenderingStrategyTest.php @@ -0,0 +1,67 @@ +<?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\HttpKernel\Tests\RenderingStrategy; + +use Symfony\Component\HttpKernel\Controller\ControllerReference; +use Symfony\Component\HttpKernel\RenderingStrategy\HIncludeRenderingStrategy; +use Symfony\Component\HttpKernel\UriSigner; +use Symfony\Component\HttpFoundation\Request; + +class HIncludeRenderingStrategyTest extends \PHPUnit_Framework_TestCase +{ + protected function setUp() + { + if (!class_exists('Symfony\Component\HttpFoundation\Request')) { + $this->markTestSkipped('The "HttpFoundation" component is not available'); + } + } + + /** + * @expectedException \LogicException + */ + public function testRenderExceptionWhenControllerAndNoSigner() + { + $strategy = new HIncludeRenderingStrategy(); + $strategy->render(new ControllerReference('main_controller', array(), array()), Request::create('/')); + } + + public function testRenderWithControllerAndSigner() + { + $strategy = new HIncludeRenderingStrategy(null, new UriSigner('foo')); + + $this->assertEquals('<hx:include src="http://localhost/_proxy?_path=_format%3Dhtml%26_controller%3Dmain_controller&_hash=ctQ5X4vzZnFmmPiqIqnBkVr%2B%2B10%3D"></hx:include>', $strategy->render(new ControllerReference('main_controller', array(), array()), Request::create('/'))->getContent()); + } + + public function testRenderWithUri() + { + $strategy = new HIncludeRenderingStrategy(); + $this->assertEquals('<hx:include src="/foo"></hx:include>', $strategy->render('/foo', Request::create('/'))->getContent()); + + $strategy = new HIncludeRenderingStrategy(null, new UriSigner('foo')); + $this->assertEquals('<hx:include src="/foo"></hx:include>', $strategy->render('/foo', Request::create('/'))->getContent()); + } + + public function testRenderWhithDefault() + { + // only default + $strategy = new HIncludeRenderingStrategy(); + $this->assertEquals('<hx:include src="/foo">default</hx:include>', $strategy->render('/foo', Request::create('/'), array('default' => 'default'))->getContent()); + + // only global default + $strategy = new HIncludeRenderingStrategy(null, null, 'global_default'); + $this->assertEquals('<hx:include src="/foo">global_default</hx:include>', $strategy->render('/foo', Request::create('/'), array())->getContent()); + + // global default and default + $strategy = new HIncludeRenderingStrategy(null, null, 'global_default'); + $this->assertEquals('<hx:include src="/foo">default</hx:include>', $strategy->render('/foo', Request::create('/'), array('default' => 'default'))->getContent()); + } +} diff --git a/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Tests/RenderingStrategy/ProxyAwareRenderingStrategyTest.php b/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Tests/RenderingStrategy/ProxyAwareRenderingStrategyTest.php new file mode 100644 index 000000000000..51e2340117cb --- /dev/null +++ b/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Tests/RenderingStrategy/ProxyAwareRenderingStrategyTest.php @@ -0,0 +1,63 @@ +<?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\HttpKernel\Tests\RenderingStrategy; + +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpKernel\Controller\ControllerReference; +use Symfony\Component\HttpKernel\RenderingStrategy\ProxyAwareRenderingStrategy; + +class ProxyAwareRenderingStrategyTest extends \PHPUnit_Framework_TestCase +{ + /** + * @dataProvider getGenerateProxyUriData + */ + public function testGenerateProxyUri($uri, $controller) + { + $this->assertEquals($uri, $this->getStrategy()->doGenerateProxyUri($controller, Request::create('/'))); + } + + public function getGenerateProxyUriData() + { + return array( + array('http://localhost/_proxy?_path=_format%3Dhtml%26_controller%3Dcontroller', new ControllerReference('controller', array(), array())), + array('http://localhost/_proxy?_path=_format%3Dxml%26_controller%3Dcontroller', new ControllerReference('controller', array('_format' => 'xml'), array())), + array('http://localhost/_proxy?_path=foo%3Dfoo%26_format%3Djson%26_controller%3Dcontroller', new ControllerReference('controller', array('foo' => 'foo', '_format' => 'json'), array())), + array('http://localhost/_proxy?bar=bar&_path=foo%3Dfoo%26_format%3Dhtml%26_controller%3Dcontroller', new ControllerReference('controller', array('foo' => 'foo'), array('bar' => 'bar'))), + array('http://localhost/_proxy?foo=foo&_path=_format%3Dhtml%26_controller%3Dcontroller', new ControllerReference('controller', array(), array('foo' => 'foo'))), + ); + } + + public function testGenerateProxyUriWithARequest() + { + $request = Request::create('/'); + $request->attributes->set('_format', 'json'); + $controller = new ControllerReference('controller', array(), array()); + + $this->assertEquals('http://localhost/_proxy?_path=_format%3Djson%26_controller%3Dcontroller', $this->getStrategy()->doGenerateProxyUri($controller, $request)); + } + + private function getStrategy() + { + return new Strategy(); + } +} + +class Strategy extends ProxyAwareRenderingStrategy +{ + public function render($uri, Request $request, array $options = array()) {} + public function getName() {} + + public function doGenerateProxyUri(ControllerReference $reference, Request $request) + { + return parent::generateProxyUri($reference, $request); + } +} diff --git a/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Tests/UriSignerTest.php b/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Tests/UriSignerTest.php new file mode 100644 index 000000000000..8ffc2bfbbd87 --- /dev/null +++ b/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Tests/UriSignerTest.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\HttpKernel\Tests; + +use Symfony\Component\HttpKernel\UriSigner; + +class UriSignerTest extends \PHPUnit_Framework_TestCase +{ + public function testSign() + { + $signer = new UriSigner('foobar'); + + $this->assertContains('?_hash=', $signer->sign('http://example.com/foo')); + $this->assertContains('&_hash=', $signer->sign('http://example.com/foo?foo=bar')); + } + + public function testCheck() + { + $signer = new UriSigner('foobar'); + + $this->assertFalse($signer->check('http://example.com/foo?_hash=foo')); + $this->assertFalse($signer->check('http://example.com/foo?foo=bar&_hash=foo')); + $this->assertFalse($signer->check('http://example.com/foo?foo=bar&_hash=foo&bar=foo')); + + $this->assertTrue($signer->check($signer->sign('http://example.com/foo'))); + $this->assertTrue($signer->check($signer->sign('http://example.com/foo?foo=bar'))); + } +} diff --git a/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/UriSigner.php b/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/UriSigner.php new file mode 100644 index 000000000000..45825fe24605 --- /dev/null +++ b/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/UriSigner.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\HttpKernel; + +/** + * Signs URIs. + * + * @author Fabien Potencier <fabien@symfony.com> + */ +class UriSigner +{ + private $secret; + + /** + * Constructor. + * + * @param string $secret A secret + */ + public function __construct($secret) + { + $this->secret = $secret; + } + + /** + * Signs a URI. + * + * The given URI is signed by adding a _hash query string parameter + * which value depends on the URI and the secret. + * + * @param string $uri A URI to sign + * + * @return string The signed URI + */ + public function sign($uri) + { + return $uri.(false === (strpos($uri, '?')) ? '?' : '&').'_hash='.$this->computeHash($uri); + } + + /** + * Checks that a URI contains the correct hash. + * + * The _hash query string parameter must be the last one + * (as it is generated that way by the sign() method, it should + * never be a problem). + * + * @param string $uri A signed URI + * + * @return Boolean True if the URI is signed correctly, false otherwise + */ + public function check($uri) + { + if (!preg_match('/(\?|&)_hash=(.+?)$/', $uri, $matches, PREG_OFFSET_CAPTURE)) { + return false; + } + + // the naked URI is the URI without the _hash parameter (we need to keep the ? if there is some other parameters after) + $nakedUri = substr($uri, 0, $matches[0][1]).substr($uri, $matches[0][1] + strlen($matches[0][0])); + + return $this->computeHash($nakedUri) === $matches[2][0]; + } + + private function computeHash($uri) + { + return urlencode(base64_encode(hash_hmac('sha1', $uri, $this->secret, true))); + } +} diff --git a/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/composer.json b/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/composer.json index a6cf81f10eb0..9680fadd2a76 100644 --- a/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/composer.json +++ b/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/composer.json @@ -18,7 +18,8 @@ "require": { "php": ">=5.3.3", "symfony/event-dispatcher": "2.2.*", - "symfony/http-foundation": "2.2.*" + "symfony/http-foundation": "2.2.*", + "psr/log": "~1.0" }, "require-dev": { "symfony/browser-kit": "2.2.*", diff --git a/core/vendor/symfony/process/Symfony/Component/Process/.gitattributes b/core/vendor/symfony/process/Symfony/Component/Process/.gitattributes deleted file mode 100644 index 80481513cff2..000000000000 --- a/core/vendor/symfony/process/Symfony/Component/Process/.gitattributes +++ /dev/null @@ -1,2 +0,0 @@ -/Tests export-ignore -phpunit.xml.dist export-ignore diff --git a/core/vendor/symfony/process/Symfony/Component/Process/Exception/ProcessFailedException.php b/core/vendor/symfony/process/Symfony/Component/Process/Exception/ProcessFailedException.php index a4540c065710..f778a362f98c 100755 --- a/core/vendor/symfony/process/Symfony/Component/Process/Exception/ProcessFailedException.php +++ b/core/vendor/symfony/process/Symfony/Component/Process/Exception/ProcessFailedException.php @@ -30,8 +30,10 @@ public function __construct(Process $process) parent::__construct( sprintf( - 'The command "%s" failed.'."\n\nOutput:\n================\n".$process->getOutput()."\n\nError Output:\n================\n".$process->getErrorOutput(), - $process->getCommandLine() + 'The command "%s" failed.'."\n\nOutput:\n================\n%s\n\nError Output:\n================\n%s", + $process->getCommandLine(), + $process->getOutput(), + $process->getErrorOutput() ) ); diff --git a/core/vendor/symfony/process/Symfony/Component/Process/ExecutableFinder.php b/core/vendor/symfony/process/Symfony/Component/Process/ExecutableFinder.php index 087c94b0f21e..5cc99c769205 100644 --- a/core/vendor/symfony/process/Symfony/Component/Process/ExecutableFinder.php +++ b/core/vendor/symfony/process/Symfony/Component/Process/ExecutableFinder.php @@ -19,22 +19,23 @@ */ class ExecutableFinder { - private static $isWindows; - private $suffixes = array('.exe', '.bat', '.cmd', '.com'); - public function __construct() - { - if (null === self::$isWindows) { - self::$isWindows = 0 === stripos(PHP_OS, 'win'); - } - } - + /** + * Replaces default suffixes of executable. + * + * @param array $suffixes + */ public function setSuffixes(array $suffixes) { $this->suffixes = $suffixes; } + /** + * Adds new possible suffix to check for executable. + * + * @param string $suffix + */ public function addSuffix($suffix) { $this->suffixes[] = $suffix; @@ -78,7 +79,7 @@ public function find($name, $default = null, array $extraDirs = array()) } foreach ($suffixes as $suffix) { foreach ($dirs as $dir) { - if (is_file($file = $dir.DIRECTORY_SEPARATOR.$name.$suffix) && (self::$isWindows || is_executable($file))) { + if (is_file($file = $dir.DIRECTORY_SEPARATOR.$name.$suffix) && (defined('PHP_WINDOWS_VERSION_BUILD') || is_executable($file))) { return $file; } } diff --git a/core/vendor/symfony/process/Symfony/Component/Process/LICENSE b/core/vendor/symfony/process/Symfony/Component/Process/LICENSE index cdffe7aebc04..88a57f8d8da4 100644 --- a/core/vendor/symfony/process/Symfony/Component/Process/LICENSE +++ b/core/vendor/symfony/process/Symfony/Component/Process/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2004-2012 Fabien Potencier +Copyright (c) 2004-2013 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 diff --git a/core/vendor/symfony/process/Symfony/Component/Process/PhpProcess.php b/core/vendor/symfony/process/Symfony/Component/Process/PhpProcess.php index 2bd560045156..7a9fd0864be5 100644 --- a/core/vendor/symfony/process/Symfony/Component/Process/PhpProcess.php +++ b/core/vendor/symfony/process/Symfony/Component/Process/PhpProcess.php @@ -55,16 +55,9 @@ public function setPhpBinary($php) } /** - * Runs the process. - * - * @param Closure|string|array $callback A PHP callback to run whenever there is some - * output available on STDOUT or STDERR - * - * @return integer The exit status code - * - * @api + * {@inheritdoc} */ - public function run($callback = null) + public function start($callback = null) { if (null === $this->getCommandLine()) { if (false === $php = $this->executableFinder->find()) { @@ -73,6 +66,6 @@ public function run($callback = null) $this->setCommandLine($php); } - return parent::run($callback); + parent::start($callback); } } diff --git a/core/vendor/symfony/process/Symfony/Component/Process/Process.php b/core/vendor/symfony/process/Symfony/Component/Process/Process.php index ba7625560857..4af26e85a22f 100644 --- a/core/vendor/symfony/process/Symfony/Component/Process/Process.php +++ b/core/vendor/symfony/process/Symfony/Component/Process/Process.php @@ -127,7 +127,7 @@ public function __construct($commandline, $cwd = null, array $env = null, $stdin } $this->commandline = $commandline; - $this->cwd = null === $cwd ? getcwd() : $cwd; + $this->cwd = $cwd; if (null !== $env) { $this->env = array(); foreach ($env as $key => $value) { @@ -159,8 +159,8 @@ public function __destruct() * The STDOUT and STDERR are also available after the process is finished * via the getOutput() and getErrorOutput() methods. * - * @param Closure|string|array $callback A PHP callback to run whenever there is some - * output available on STDOUT or STDERR + * @param callback|null $callback A PHP callback to run whenever there is some + * output available on STDOUT or STDERR * * @return integer The exit status code * @@ -190,8 +190,8 @@ public function run($callback = null) * with true as a second parameter then the callback will get all data occurred * in (and since) the start call. * - * @param Closure|string|array $callback A PHP callback to run whenever there is some - * output available on STDOUT or STDERR + * @param callback|null $callback A PHP callback to run whenever there is some + * output available on STDOUT or STDERR * * @throws \RuntimeException When process can't be launch or is stopped * @throws \RuntimeException When process is already running @@ -318,11 +318,12 @@ public function start($callback = null) * from the output in real-time while writing the standard input to the process. * It allows to have feedback from the independent process during execution. * - * @param mixed $callback A valid PHP callback + * @param callback|null $callback A valid PHP callback * - * @return int The exitcode of the process + * @return integer The exitcode of the process * - * @throws \RuntimeException + * @throws \RuntimeException When process timed out + * @throws \RuntimeException When process stopped after receiving signal */ public function wait($callback = null) { @@ -338,10 +339,13 @@ public function wait($callback = null) $w = null; $e = null; - $n = @stream_select($r, $w, $e, $this->timeout); + if (false === $n = @stream_select($r, $w, $e, $this->timeout)) { + $lastError = error_get_last(); - if (false === $n) { - $this->pipes = array(); + // stream_select returns false when the `select` system call is interrupted by an incoming signal + if (isset($lastError['message']) && false === stripos($lastError['message'], 'interrupted system call')) { + $this->pipes = array(); + } continue; } @@ -452,8 +456,6 @@ public function getExitCode() * * @return string A string representation for the exit status code * - * @throws RuntimeException In case --enable-sigchild is activated and the sigchild compatibility mode is disabled - * * @see http://tldp.org/LDP/abs/html/exitcodes.html * @see http://en.wikipedia.org/wiki/Unix_signal */ @@ -469,8 +471,6 @@ public function getExitCodeText() * * @return Boolean true if the process ended successfully, false otherwise * - * @throws RuntimeException In case --enable-sigchild is activated and the sigchild compatibility mode is disabled - * * @api */ public function isSuccessful() @@ -573,11 +573,9 @@ public function isRunning() /** * Stops the process. * - * @param float $timeout The timeout in seconds + * @param integer|float $timeout The timeout in seconds * * @return integer The exit-code of the process - * - * @throws \RuntimeException if the process got signaled */ public function stop($timeout=10) { @@ -693,6 +691,13 @@ public function setTimeout($timeout) */ public function getWorkingDirectory() { + // This is for BC only + if (null === $this->cwd) { + // getcwd() will return false if any one of the parent directories does not have + // the readable or search mode set, even if the current directory does + return getcwd() ?: null; + } + return $this->cwd; } @@ -818,9 +823,9 @@ public function setEnhanceSigchildCompatibility($enhance) * The callbacks adds all occurred output to the specific buffer and calls * the user callback (if present) with the received output. * - * @param mixed $callback The user defined PHP callback + * @param callback|null $callback The user defined PHP callback * - * @return mixed A PHP callable + * @return callback A PHP callable */ protected function buildCallback($callback) { @@ -860,6 +865,9 @@ protected function updateStatus() } } + /** + * Updates the current error output of the process (STDERR). + */ protected function updateErrorOutput() { if (isset($this->pipes[self::STDERR]) && is_resource($this->pipes[self::STDERR])) { @@ -867,6 +875,9 @@ protected function updateErrorOutput() } } + /** + * Updates the current output of the process (STDOUT). + */ protected function updateOutput() { if (defined('PHP_WINDOWS_VERSION_BUILD') && isset($this->fileHandles[self::STDOUT]) && is_resource($this->fileHandles[self::STDOUT])) { diff --git a/core/vendor/symfony/process/Symfony/Component/Process/Tests/AbstractProcessTest.php b/core/vendor/symfony/process/Symfony/Component/Process/Tests/AbstractProcessTest.php index d83c1f341973..51d51f40b87b 100644 --- a/core/vendor/symfony/process/Symfony/Component/Process/Tests/AbstractProcessTest.php +++ b/core/vendor/symfony/process/Symfony/Component/Process/Tests/AbstractProcessTest.php @@ -11,13 +11,13 @@ namespace Symfony\Component\Process\Tests; +use Symfony\Component\Process\Process; + /** * @author Robert Schönthal <seroscho@googlemail.com> */ abstract class AbstractProcessTest extends \PHPUnit_Framework_TestCase { - protected abstract function getProcess($commandline, $cwd = null, array $env = null, $stdin = null, $timeout = 60, array $options = array()); - /** * @expectedException \InvalidArgumentException */ @@ -233,11 +233,14 @@ public function testProcessWithTermSignal() $this->markTestSkipped('Windows does not support POSIX signals'); } + // SIGTERM is only defined if pcntl extension is present + $termSignal = defined('SIGTERM') ? SIGTERM : 15; $process = $this->getProcess('php -r "while (true) {}"'); $process->start(); $process->stop(); - $this->assertEquals(SIGTERM, $process->getTermSignal()); + + $this->assertEquals($termSignal, $process->getTermSignal()); } public function testPhpDeadlock() @@ -297,4 +300,16 @@ public function methodProvider() return $defaults; } + + /** + * @param string $commandline + * @param null $cwd + * @param array $env + * @param null $stdin + * @param integer $timeout + * @param array $options + * + * @return Process + */ + abstract protected function getProcess($commandline, $cwd = null, array $env = null, $stdin = null, $timeout = 60, array $options = array()); } diff --git a/core/vendor/symfony/process/Symfony/Component/Process/Tests/PhpExecutableFinderTest.php b/core/vendor/symfony/process/Symfony/Component/Process/Tests/PhpExecutableFinderTest.php index c632e31f7483..99c4a1e7c961 100644 --- a/core/vendor/symfony/process/Symfony/Component/Process/Tests/PhpExecutableFinderTest.php +++ b/core/vendor/symfony/process/Symfony/Component/Process/Tests/PhpExecutableFinderTest.php @@ -21,7 +21,7 @@ class PhpExecutableFinderTest extends \PHPUnit_Framework_TestCase /** * tests find() with the env var PHP_PATH */ - public function testFindWithPHP_PATH() + public function testFindWithPhpPath() { if (defined('PHP_BINARY')) { $this->markTestSkipped('The PHP binary is easily available as of PHP 5.4'); diff --git a/core/vendor/symfony/process/Symfony/Component/Process/Tests/PhpProcessTest.php b/core/vendor/symfony/process/Symfony/Component/Process/Tests/PhpProcessTest.php new file mode 100644 index 000000000000..7bcdd2f05d9d --- /dev/null +++ b/core/vendor/symfony/process/Symfony/Component/Process/Tests/PhpProcessTest.php @@ -0,0 +1,21 @@ +<?php + +namespace Symfony\Component\Process\Tests; + +use Symfony\Component\Process\PhpProcess; + +class PhpProcessTest extends \PHPUnit_Framework_TestCase +{ + + public function testNonBlockingWorks() + { + $expected = 'hello world!'; + $process = new PhpProcess(<<<PHP +<?php echo '$expected'; +PHP + ); + $process->start(); + $process->wait(); + $this->assertEquals($expected, $process->getOutput()); + } +} diff --git a/core/vendor/symfony/process/Symfony/Component/Process/Tests/SigchildDisabledProcessTest.php b/core/vendor/symfony/process/Symfony/Component/Process/Tests/SigchildDisabledProcessTest.php index 4a321adf5501..67fc0025bdd2 100644 --- a/core/vendor/symfony/process/Symfony/Component/Process/Tests/SigchildDisabledProcessTest.php +++ b/core/vendor/symfony/process/Symfony/Component/Process/Tests/SigchildDisabledProcessTest.php @@ -13,15 +13,6 @@ class SigchildDisabledProcessTest extends AbstractProcessTest { - - protected function getProcess($commandline, $cwd = null, array $env = null, $stdin = null, $timeout = 60, array $options = array()) - { - $process = new ProcessInSigchildEnvironment($commandline, $cwd, $env, $stdin, $timeout, $options); - $process->setEnhanceSigchildCompatibility(false); - - return $process; - } - /** * @expectedException Symfony\Component\Process\Exception\RuntimeException */ @@ -96,4 +87,15 @@ public function testIsNotSuccessful() { parent::testIsNotSuccessful(); } + + /** + * {@inheritdoc} + */ + protected function getProcess($commandline, $cwd = null, array $env = null, $stdin = null, $timeout = 60, array $options = array()) + { + $process = new ProcessInSigchildEnvironment($commandline, $cwd, $env, $stdin, $timeout, $options); + $process->setEnhanceSigchildCompatibility(false); + + return $process; + } } diff --git a/core/vendor/symfony/process/Symfony/Component/Process/Tests/SigchildEnabledProcessTest.php b/core/vendor/symfony/process/Symfony/Component/Process/Tests/SigchildEnabledProcessTest.php index 4c04ff146b3f..fb9b6f8cc8ed 100644 --- a/core/vendor/symfony/process/Symfony/Component/Process/Tests/SigchildEnabledProcessTest.php +++ b/core/vendor/symfony/process/Symfony/Component/Process/Tests/SigchildEnabledProcessTest.php @@ -13,15 +13,6 @@ class SigchildEnabledProcessTest extends AbstractProcessTest { - - protected function getProcess($commandline, $cwd = null, array $env = null, $stdin = null, $timeout = 60, array $options = array()) - { - $process = new ProcessInSigchildEnvironment($commandline, $cwd, $env, $stdin, $timeout, $options); - $process->setEnhanceSigchildCompatibility(true); - - return $process; - } - /** * @expectedException Symfony\Component\Process\Exception\RuntimeException */ @@ -62,4 +53,14 @@ public function testExitCodeText() $this->assertInternalType('string', $process->getExitCodeText()); } + /** + * {@inheritdoc} + */ + protected function getProcess($commandline, $cwd = null, array $env = null, $stdin = null, $timeout = 60, array $options = array()) + { + $process = new ProcessInSigchildEnvironment($commandline, $cwd, $env, $stdin, $timeout, $options); + $process->setEnhanceSigchildCompatibility(true); + + return $process; + } } diff --git a/core/vendor/symfony/process/Symfony/Component/Process/Tests/SimpleProcessTest.php b/core/vendor/symfony/process/Symfony/Component/Process/Tests/SimpleProcessTest.php index 8742a69e54cf..17dea3fe5403 100644 --- a/core/vendor/symfony/process/Symfony/Component/Process/Tests/SimpleProcessTest.php +++ b/core/vendor/symfony/process/Symfony/Component/Process/Tests/SimpleProcessTest.php @@ -15,20 +15,14 @@ class SimpleProcessTest extends AbstractProcessTest { + private $enabledSigchild = false; - protected function skipIfPHPSigchild() + public function setUp() { ob_start(); phpinfo(INFO_GENERAL); - if (false !== strpos(ob_get_clean(), '--enable-sigchild')) { - $this->markTestSkipped('Your PHP has been compiled with --enable-sigchild, this test can not be executed'); - } - } - - protected function getProcess($commandline, $cwd = null, array $env = null, $stdin = null, $timeout = 60, array $options = array()) - { - return new Process($commandline, $cwd, $env, $stdin, $timeout, $options); + $this->enabledSigchild = false !== strpos(ob_get_clean(), '--enable-sigchild'); } public function testGetExitCode() @@ -84,4 +78,19 @@ public function testIsNotSuccessful() $this->skipIfPHPSigchild(); parent::testIsNotSuccessful(); } + + /** + * {@inheritdoc} + */ + protected function getProcess($commandline, $cwd = null, array $env = null, $stdin = null, $timeout = 60, array $options = array()) + { + return new Process($commandline, $cwd, $env, $stdin, $timeout, $options); + } + + private function skipIfPHPSigchild() + { + if ($this->enabledSigchild) { + $this->markTestSkipped('Your PHP has been compiled with --enable-sigchild, this test can not be executed'); + } + } } diff --git a/core/vendor/symfony/routing/Symfony/Component/Routing/.gitattributes b/core/vendor/symfony/routing/Symfony/Component/Routing/.gitattributes deleted file mode 100644 index 80481513cff2..000000000000 --- a/core/vendor/symfony/routing/Symfony/Component/Routing/.gitattributes +++ /dev/null @@ -1,2 +0,0 @@ -/Tests export-ignore -phpunit.xml.dist export-ignore diff --git a/core/vendor/symfony/routing/Symfony/Component/Routing/Annotation/Route.php b/core/vendor/symfony/routing/Symfony/Component/Routing/Annotation/Route.php index d8f4b5ae934d..abdbea27c699 100644 --- a/core/vendor/symfony/routing/Symfony/Component/Routing/Annotation/Route.php +++ b/core/vendor/symfony/routing/Symfony/Component/Routing/Annotation/Route.php @@ -20,12 +20,14 @@ */ class Route { - private $pattern; + private $path; private $name; private $requirements; private $options; private $defaults; - private $hostnamePattern; + private $host; + private $methods; + private $schemes; /** * Constructor. @@ -39,9 +41,11 @@ public function __construct(array $data) $this->requirements = array(); $this->options = array(); $this->defaults = array(); + $this->methods = array(); + $this->schemes = array(); if (isset($data['value'])) { - $data['pattern'] = $data['value']; + $data['path'] = $data['value']; unset($data['value']); } @@ -54,24 +58,40 @@ public function __construct(array $data) } } + /** + * @deprecated Deprecated in 2.2, to be removed in 3.0. Use setPath instead. + */ public function setPattern($pattern) { - $this->pattern = $pattern; + $this->path = $pattern; } + /** + * @deprecated Deprecated in 2.2, to be removed in 3.0. Use getPath instead. + */ public function getPattern() { - return $this->pattern; + return $this->path; } - public function setHostnamePattern($pattern) + public function setPath($path) { - $this->hostnamePattern = $pattern; + $this->path = $path; } - public function getHostnamePattern() + public function getPath() { - return $this->hostnamePattern; + return $this->path; + } + + public function setHost($pattern) + { + $this->host = $pattern; + } + + public function getHost() + { + return $this->host; } public function setName($name) @@ -113,4 +133,24 @@ 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; + } } diff --git a/core/vendor/symfony/routing/Symfony/Component/Routing/CHANGELOG.md b/core/vendor/symfony/routing/Symfony/Component/Routing/CHANGELOG.md index af5f7533065f..873c5f7423d1 100644 --- a/core/vendor/symfony/routing/Symfony/Component/Routing/CHANGELOG.md +++ b/core/vendor/symfony/routing/Symfony/Component/Routing/CHANGELOG.md @@ -4,6 +4,49 @@ CHANGELOG 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: + + ``` + article_edit: + pattern: /article/{id} + requirements: { '_method': 'POST|PUT', '_scheme': 'https', 'id': '\d+' } + + <route id="article_edit" pattern="/article/{id}"> + <requirement key="_method">POST|PUT</requirement> + <requirement key="_scheme">https</requirement> + <requirement key="id">\d+</requirement> + </route> + + $route = new Route(); + $route->setPattern('/article/{id}'); + $route->setRequirement('_method', 'POST|PUT'); + $route->setRequirement('_scheme', 'https'); + ``` + + After: + + ``` + article_edit: + path: /article/{id} + methods: [POST, PUT] + schemes: https + requirements: { 'id': '\d+' } + + <route id="article_edit" pattern="/article/{id}" methods="POST PUT" schemes="https"> + <requirement key="id">\d+</requirement> + </route> + + $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 @@ -79,6 +122,14 @@ CHANGELOG 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 ----- diff --git a/core/vendor/symfony/routing/Symfony/Component/Routing/CompiledRoute.php b/core/vendor/symfony/routing/Symfony/Component/Routing/CompiledRoute.php index 1ccad3c22a39..7878455427d4 100644 --- a/core/vendor/symfony/routing/Symfony/Component/Routing/CompiledRoute.php +++ b/core/vendor/symfony/routing/Symfony/Component/Routing/CompiledRoute.php @@ -23,9 +23,9 @@ class CompiledRoute private $staticPrefix; private $regex; private $pathVariables; - private $hostnameVariables; - private $hostnameRegex; - private $hostnameTokens; + private $hostVariables; + private $hostRegex; + private $hostTokens; /** * Constructor. @@ -34,20 +34,20 @@ class CompiledRoute * @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 $hostnameRegex Hostname regex - * @param array $hostnameTokens Hostname tokens - * @param array $hostnameVariables An array of hostname variables - * @param array $variables An array of variables (variables defined in the path and in the hostname patterns) + * @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, $hostnameRegex = null, array $hostnameTokens = array(), array $hostnameVariables = array(), array $variables = array()) + 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->hostnameRegex = $hostnameRegex; - $this->hostnameTokens = $hostnameTokens; - $this->hostnameVariables = $hostnameVariables; + $this->hostRegex = $hostRegex; + $this->hostTokens = $hostTokens; + $this->hostVariables = $hostVariables; $this->variables = $variables; } @@ -72,13 +72,13 @@ public function getRegex() } /** - * Returns the hostname regex + * Returns the host regex * - * @return string|null The hostname regex or null + * @return string|null The host regex or null */ - public function getHostnameRegex() + public function getHostRegex() { - return $this->hostnameRegex; + return $this->hostRegex; } /** @@ -92,13 +92,13 @@ public function getTokens() } /** - * Returns the hostname tokens. + * Returns the host tokens. * * @return array The tokens */ - public function getHostnameTokens() + public function getHostTokens() { - return $this->hostnameTokens; + return $this->hostTokens; } /** @@ -122,13 +122,13 @@ public function getPathVariables() } /** - * Returns the hostname variables. + * Returns the host variables. * * @return array The variables */ - public function getHostnameVariables() + public function getHostVariables() { - return $this->hostnameVariables; + return $this->hostVariables; } } diff --git a/core/vendor/symfony/routing/Symfony/Component/Routing/Generator/Dumper/PhpGeneratorDumper.php b/core/vendor/symfony/routing/Symfony/Component/Routing/Generator/Dumper/PhpGeneratorDumper.php index c85f0201e450..8aadde527487 100644 --- a/core/vendor/symfony/routing/Symfony/Component/Routing/Generator/Dumper/PhpGeneratorDumper.php +++ b/core/vendor/symfony/routing/Symfony/Component/Routing/Generator/Dumper/PhpGeneratorDumper.php @@ -47,7 +47,7 @@ public function dump(array $options = array()) use Symfony\Component\Routing\RequestContext; use Symfony\Component\Routing\Exception\RouteNotFoundException; -use Symfony\Component\HttpKernel\Log\LoggerInterface; +use Psr\Log\LoggerInterface; /** * {$options['class']} @@ -91,7 +91,7 @@ private function generateDeclaredRoutes() $properties[] = $route->getDefaults(); $properties[] = $route->getRequirements(); $properties[] = $compiledRoute->getTokens(); - $properties[] = $compiledRoute->getHostnameTokens(); + $properties[] = $compiledRoute->getHostTokens(); $routes .= sprintf(" '%s' => %s,\n", $name, str_replace("\n", '', var_export($properties, true))); } @@ -108,15 +108,15 @@ private function generateDeclaredRoutes() private function generateGenerateMethod() { return <<<EOF - public function generate(\$name, \$parameters = array(), \$absolute = false) + public function generate(\$name, \$parameters = array(), \$referenceType = self::ABSOLUTE_PATH) { if (!isset(self::\$declaredRoutes[\$name])) { throw new RouteNotFoundException(sprintf('Route "%s" does not exist.', \$name)); } - list(\$variables, \$defaults, \$requirements, \$tokens, \$hostnameTokens) = self::\$declaredRoutes[\$name]; + list(\$variables, \$defaults, \$requirements, \$tokens, \$hostTokens) = self::\$declaredRoutes[\$name]; - return \$this->doGenerate(\$variables, \$defaults, \$requirements, \$tokens, \$parameters, \$name, \$absolute, \$hostnameTokens); + return \$this->doGenerate(\$variables, \$defaults, \$requirements, \$tokens, \$parameters, \$name, \$referenceType, \$hostTokens); } EOF; } diff --git a/core/vendor/symfony/routing/Symfony/Component/Routing/Generator/UrlGenerator.php b/core/vendor/symfony/routing/Symfony/Component/Routing/Generator/UrlGenerator.php index aa0a3ee8f28e..f15d65b2a52d 100644 --- a/core/vendor/symfony/routing/Symfony/Component/Routing/Generator/UrlGenerator.php +++ b/core/vendor/symfony/routing/Symfony/Component/Routing/Generator/UrlGenerator.php @@ -16,10 +16,11 @@ use Symfony\Component\Routing\Exception\InvalidParameterException; use Symfony\Component\Routing\Exception\RouteNotFoundException; use Symfony\Component\Routing\Exception\MissingMandatoryParametersException; -use Symfony\Component\HttpKernel\Log\LoggerInterface; +use Psr\Log\LoggerInterface; /** - * UrlGenerator generates a URL based on a set of routes. + * 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> @@ -127,7 +128,7 @@ public function isStrictRequirements() /** * {@inheritDoc} */ - public function generate($name, $parameters = array(), $absolute = false) + public function generate($name, $parameters = array(), $referenceType = self::ABSOLUTE_PATH) { if (null === $route = $this->routes->get($name)) { throw new RouteNotFoundException(sprintf('Route "%s" does not exist.', $name)); @@ -136,21 +137,22 @@ public function generate($name, $parameters = array(), $absolute = false) // 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, $absolute, $compiledRoute->getHostnameTokens()); + return $this->doGenerate($compiledRoute->getVariables(), $route->getDefaults(), $route->getRequirements(), $compiledRoute->getTokens(), $parameters, $name, $referenceType, $compiledRoute->getHostTokens()); } /** - * @throws MissingMandatoryParametersException When route has some missing mandatory parameters - * @throws InvalidParameterException When a parameter value is not correct + * @throws MissingMandatoryParametersException When some parameters are missing that 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, $absolute, $hostnameTokens) + protected function doGenerate($variables, $defaults, $requirements, $tokens, $parameters, $name, $referenceType, $hostTokens) { $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('The "%s" route has some missing mandatory parameters ("%s").', $name, implode('", "', array_keys($diff)))); + throw new MissingMandatoryParametersException(sprintf('Some mandatory parameters are missing ("%s") to generate a URL for route "%s".', implode('", "', array_keys($diff)), $name)); } $url = ''; @@ -160,13 +162,13 @@ protected function doGenerate($variables, $defaults, $requirements, $tokens, $pa if (!$optional || !array_key_exists($token[3], $defaults) || (string) $mergedParams[$token[3]] !== (string) $defaults[$token[3]]) { // check requirement if (null !== $this->strictRequirements && !preg_match('#^'.$token[2].'$#', $mergedParams[$token[3]])) { - $message = sprintf('Parameter "%s" for route "%s" must match "%s" ("%s" given).', $token[3], $name, $token[2], $mergedParams[$token[3]]); + $message = sprintf('Parameter "%s" for route "%s" must match "%s" ("%s" given) to generate a corresponding URL.', $token[3], $name, $token[2], $mergedParams[$token[3]]); if ($this->strictRequirements) { throw new InvalidParameterException($message); } if ($this->logger) { - $this->logger->err($message); + $this->logger->error($message); } return null; @@ -186,8 +188,8 @@ protected function doGenerate($variables, $defaults, $requirements, $tokens, $pa $url = '/'; } - // do not encode the contexts base url as it is already encoded (see Symfony\Component\HttpFoundation\Request) - $url = $this->context->getBaseUrl().strtr(rawurlencode($url), $this->decodedChars); + // 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 @@ -199,50 +201,47 @@ protected function doGenerate($variables, $defaults, $requirements, $tokens, $pa $url = substr($url, 0, -1) . '%2E'; } - // add a query string if needed - $extra = array_diff_key($parameters, $variables); - if ($extra && $query = http_build_query($extra, '', '&')) { - $url .= '?'.$query; - } - + $schemeAuthority = ''; if ($host = $this->context->getHost()) { $scheme = $this->context->getScheme(); - if (isset($requirements['_scheme']) && ($req = strtolower($requirements['_scheme'])) && $scheme != $req) { - $absolute = true; + if (isset($requirements['_scheme']) && ($req = strtolower($requirements['_scheme'])) && $scheme !== $req) { + $referenceType = self::ABSOLUTE_URL; $scheme = $req; } - if ($hostnameTokens) { + if ($hostTokens) { $routeHost = ''; - foreach ($hostnameTokens as $token) { + foreach ($hostTokens as $token) { if ('variable' === $token[0]) { if (null !== $this->strictRequirements && !preg_match('#^'.$token[2].'$#', $mergedParams[$token[3]])) { - $message = sprintf('Parameter "%s" for route "%s" must match "%s" ("%s" given).', $token[3], $name, $token[2], $mergedParams[$token[3]]); + $message = sprintf('Parameter "%s" for route "%s" must match "%s" ("%s" given) to generate a corresponding URL.', $token[3], $name, $token[2], $mergedParams[$token[3]]); if ($this->strictRequirements) { throw new InvalidParameterException($message); } if ($this->logger) { - $this->logger->err($message); + $this->logger->error($message); } return null; } $routeHost = $token[1].$mergedParams[$token[3]].$routeHost; - } elseif ('text' === $token[0]) { + } else { $routeHost = $token[1].$routeHost; } } - if ($routeHost != $host) { + if ($routeHost !== $host) { $host = $routeHost; - $absolute = true; + if (self::ABSOLUTE_URL !== $referenceType) { + $referenceType = self::NETWORK_PATH; + } } } - if ($absolute) { + if (self::ABSOLUTE_URL === $referenceType || self::NETWORK_PATH === $referenceType) { $port = ''; if ('http' === $scheme && 80 != $this->context->getHttpPort()) { $port = ':'.$this->context->getHttpPort(); @@ -250,10 +249,74 @@ protected function doGenerate($variables, $defaults, $requirements, $tokens, $pa $port = ':'.$this->context->getHttpsPort(); } - $url = $scheme.'://'.$host.$port.$url; + $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_diff_key($parameters, $variables); + if ($extra && $query = http_build_query($extra, '', '&')) { + $url .= '?'.$query; + } + 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/core/vendor/symfony/routing/Symfony/Component/Routing/Generator/UrlGeneratorInterface.php b/core/vendor/symfony/routing/Symfony/Component/Routing/Generator/UrlGeneratorInterface.php index e28c79d2d6ec..8e3b2778b977 100644 --- a/core/vendor/symfony/routing/Symfony/Component/Routing/Generator/UrlGeneratorInterface.php +++ b/core/vendor/symfony/routing/Symfony/Component/Routing/Generator/UrlGeneratorInterface.php @@ -11,33 +11,77 @@ namespace Symfony\Component\Routing\Generator; -use Symfony\Component\Routing\RequestContextAwareInterface; +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> * * @api */ interface UrlGeneratorInterface extends RequestContextAwareInterface { /** - * Generates a URL from the given parameters. + * Generates an absolute URL, e.g. "http://example.com/dir/file". + */ + const ABSOLUTE_URL = true; + + /** + * Generates an absolute path, e.g. "/dir/file". + */ + const ABSOLUTE_PATH = false; + + /** + * Generates a relative path based on the current request path, e.g. "../parent-file". + * @see UrlGenerator::getRelativePath() + */ + const RELATIVE_PATH = 'relative'; + + /** + * Generates a network path, e.g. "//example.com/dir/file". + * Such reference reuses the current scheme but specifies the host. + */ + const NETWORK_PATH = 'network'; + + /** + * 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 the generator is not able to generate the url, it must throw the RouteNotFoundException - * as documented below. + * If there is no route with the given name, the generator must throw the RouteNotFoundException. * - * @param string $name The name of the route - * @param mixed $parameters An array of parameters - * @param Boolean $absolute Whether to generate an absolute URL + * @param string $name The name of the route + * @param mixed $parameters An array of parameters + * @param Boolean|string $referenceType The type of reference to be generated (one of the constants) * * @return string The generated URL * - * @throws RouteNotFoundException if route doesn't exist + * @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 * * @api */ - public function generate($name, $parameters = array(), $absolute = false); + public function generate($name, $parameters = array(), $referenceType = self::ABSOLUTE_PATH); } diff --git a/core/vendor/symfony/routing/Symfony/Component/Routing/LICENSE b/core/vendor/symfony/routing/Symfony/Component/Routing/LICENSE index cdffe7aebc04..88a57f8d8da4 100644 --- a/core/vendor/symfony/routing/Symfony/Component/Routing/LICENSE +++ b/core/vendor/symfony/routing/Symfony/Component/Routing/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2004-2012 Fabien Potencier +Copyright (c) 2004-2013 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 diff --git a/core/vendor/symfony/routing/Symfony/Component/Routing/Loader/AnnotationClassLoader.php b/core/vendor/symfony/routing/Symfony/Component/Routing/Loader/AnnotationClassLoader.php index 9b628d665882..9831d85a0967 100644 --- a/core/vendor/symfony/routing/Symfony/Component/Routing/Loader/AnnotationClassLoader.php +++ b/core/vendor/symfony/routing/Symfony/Component/Routing/Loader/AnnotationClassLoader.php @@ -28,9 +28,10 @@ * The @Route annotation can be set on the class (for global parameters), * and on each method. * - * The @Route annotation main value is the route pattern. The annotation also - * recognizes three parameters: requirements, options, and name. The name parameter - * is mandatory. Here is an example of how you should be able to use it: + * 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") @@ -108,11 +109,13 @@ public function load($class, $type = null) } $globals = array( - 'pattern' => '', - 'requirements' => array(), - 'options' => array(), - 'defaults' => array(), - 'hostname_pattern' => '', + 'path' => '', + 'requirements' => array(), + 'options' => array(), + 'defaults' => array(), + 'schemes' => array(), + 'methods' => array(), + 'host' => '', ); $class = new \ReflectionClass($class); @@ -121,8 +124,11 @@ public function load($class, $type = null) } if ($annot = $this->reader->getClassAnnotation($class, $this->routeAnnotationClass)) { - if (null !== $annot->getPattern()) { - $globals['pattern'] = $annot->getPattern(); + // for BC reasons + if (null !== $annot->getPath()) { + $globals['path'] = $annot->getPath(); + } elseif (null !== $annot->getPattern()) { + $globals['path'] = $annot->getPattern(); } if (null !== $annot->getRequirements()) { @@ -137,8 +143,16 @@ public function load($class, $type = null) $globals['defaults'] = $annot->getDefaults(); } - if (null !== $annot->getHostnamePattern()) { - $globals['hostname_pattern'] = $annot->getHostnamePattern(); + if (null !== $annot->getSchemes()) { + $globals['schemes'] = $annot->getSchemes(); + } + + if (null !== $annot->getMethods()) { + $globals['methods'] = $annot->getMethods(); + } + + if (null !== $annot->getHost()) { + $globals['host'] = $annot->getHost(); } } @@ -172,13 +186,15 @@ protected function addRoute(RouteCollection $collection, $annot, $globals, \Refl } $requirements = array_replace($globals['requirements'], $annot->getRequirements()); $options = array_replace($globals['options'], $annot->getOptions()); + $schemes = array_replace($globals['schemes'], $annot->getSchemes()); + $methods = array_replace($globals['methods'], $annot->getMethods()); - $hostnamePattern = $annot->getHostnamePattern(); - if (null === $hostnamePattern) { - $hostnamePattern = $globals['hostname_pattern']; + $host = $annot->getHost(); + if (null === $host) { + $host = $globals['host']; } - $route = new Route($globals['pattern'].$annot->getPattern(), $defaults, $requirements, $options, $hostnamePattern); + $route = new Route($globals['path'].$annot->getPath(), $defaults, $requirements, $options, $host, $schemes, $methods); $this->configureRoute($route, $class, $method, $annot); diff --git a/core/vendor/symfony/routing/Symfony/Component/Routing/Loader/XmlFileLoader.php b/core/vendor/symfony/routing/Symfony/Component/Routing/Loader/XmlFileLoader.php index 00a6012719c1..a50da26648c7 100644 --- a/core/vendor/symfony/routing/Symfony/Component/Routing/Loader/XmlFileLoader.php +++ b/core/vendor/symfony/routing/Symfony/Component/Routing/Loader/XmlFileLoader.php @@ -113,13 +113,25 @@ public function supports($resource, $type = null) */ protected function parseRoute(RouteCollection $collection, \DOMElement $node, $path) { - if ('' === ($id = $node->getAttribute('id')) || !$node->hasAttribute('pattern')) { - throw new \InvalidArgumentException(sprintf('The <route> element in file "%s" must have an "id" and a "pattern" attribute.', $path)); + if ('' === ($id = $node->getAttribute('id')) || (!$node->hasAttribute('pattern') && !$node->hasAttribute('path'))) { + throw new \InvalidArgumentException(sprintf('The <route> element in file "%s" must have an "id" and a "path" attribute.', $path)); } + if ($node->hasAttribute('pattern')) { + if ($node->hasAttribute('path')) { + throw new \InvalidArgumentException(sprintf('The <route> element in file "%s" cannot define both a "path" and a "pattern" attribute. Use only "path".', $path)); + } + + $node->setAttribute('path', $node->getAttribute('pattern')); + $node->removeAttribute('pattern'); + } + + $schemes = array_filter(explode(' ', $node->getAttribute('schemes'))); + $methods = array_filter(explode(' ', $node->getAttribute('methods'))); + list($defaults, $requirements, $options) = $this->parseConfigs($node, $path); - $route = new Route($node->getAttribute('pattern'), $defaults, $requirements, $options, $node->getAttribute('hostname-pattern')); + $route = new Route($node->getAttribute('path'), $defaults, $requirements, $options, $node->getAttribute('host'), $schemes, $methods); $collection->add($id, $route); } @@ -141,7 +153,9 @@ protected function parseImport(RouteCollection $collection, \DOMElement $node, $ $type = $node->getAttribute('type'); $prefix = $node->getAttribute('prefix'); - $hostnamePattern = $node->hasAttribute('hostname-pattern') ? $node->getAttribute('hostname-pattern') : null; + $host = $node->hasAttribute('host') ? $node->getAttribute('host') : null; + $schemes = $node->hasAttribute('schemes') ? array_filter(explode(' ', $node->getAttribute('schemes'))) : null; + $methods = $node->hasAttribute('methods') ? array_filter(explode(' ', $node->getAttribute('methods'))) : null; list($defaults, $requirements, $options) = $this->parseConfigs($node, $path); @@ -150,8 +164,14 @@ protected function parseImport(RouteCollection $collection, \DOMElement $node, $ $subCollection = $this->import($resource, ('' !== $type ? $type : null), false, $file); /* @var $subCollection RouteCollection */ $subCollection->addPrefix($prefix); - if (null !== $hostnamePattern) { - $subCollection->setHostnamePattern($hostnamePattern); + if (null !== $host) { + $subCollection->setHost($host); + } + if (null !== $schemes) { + $subCollection->setSchemes($schemes); + } + if (null !== $methods) { + $subCollection->setMethods($methods); } $subCollection->addDefaults($defaults); $subCollection->addRequirements($requirements); diff --git a/core/vendor/symfony/routing/Symfony/Component/Routing/Loader/YamlFileLoader.php b/core/vendor/symfony/routing/Symfony/Component/Routing/Loader/YamlFileLoader.php index 4d91cd5cd3bc..a3cf2f1c008b 100644 --- a/core/vendor/symfony/routing/Symfony/Component/Routing/Loader/YamlFileLoader.php +++ b/core/vendor/symfony/routing/Symfony/Component/Routing/Loader/YamlFileLoader.php @@ -28,7 +28,7 @@ class YamlFileLoader extends FileLoader { private static $availableKeys = array( - 'resource', 'type', 'prefix', 'pattern', 'hostname_pattern', 'defaults', 'requirements', 'options', + 'resource', 'type', 'prefix', 'pattern', 'path', 'host', 'schemes', 'methods', 'defaults', 'requirements', 'options', ); /** @@ -63,6 +63,15 @@ public function load($file, $type = null) } foreach ($config as $name => $config) { + if (isset($config['pattern'])) { + if (isset($config['path'])) { + throw new \InvalidArgumentException(sprintf('The file "%s" cannot define both a "path" and a "pattern" attribute. Use only "path".', $path)); + } + + $config['path'] = $config['pattern']; + unset($config['pattern']); + } + $this->validate($config, $name, $path); if (isset($config['resource'])) { @@ -98,9 +107,11 @@ protected function parseRoute(RouteCollection $collection, $name, array $config, $defaults = isset($config['defaults']) ? $config['defaults'] : array(); $requirements = isset($config['requirements']) ? $config['requirements'] : array(); $options = isset($config['options']) ? $config['options'] : array(); - $hostnamePattern = isset($config['hostname_pattern']) ? $config['hostname_pattern'] : null; + $host = isset($config['host']) ? $config['host'] : ''; + $schemes = isset($config['schemes']) ? $config['schemes'] : array(); + $methods = isset($config['methods']) ? $config['methods'] : array(); - $route = new Route($config['pattern'], $defaults, $requirements, $options, $hostnamePattern); + $route = new Route($config['path'], $defaults, $requirements, $options, $host, $schemes, $methods); $collection->add($name, $route); } @@ -120,15 +131,23 @@ protected function parseImport(RouteCollection $collection, array $config, $path $defaults = isset($config['defaults']) ? $config['defaults'] : array(); $requirements = isset($config['requirements']) ? $config['requirements'] : array(); $options = isset($config['options']) ? $config['options'] : array(); - $hostnamePattern = isset($config['hostname_pattern']) ? $config['hostname_pattern'] : null; + $host = isset($config['host']) ? $config['host'] : null; + $schemes = isset($config['schemes']) ? $config['schemes'] : null; + $methods = isset($config['methods']) ? $config['methods'] : null; $this->setCurrentDir(dirname($path)); $subCollection = $this->import($config['resource'], $type, false, $file); /* @var $subCollection RouteCollection */ $subCollection->addPrefix($prefix); - if (null !== $hostnamePattern) { - $subCollection->setHostnamePattern($hostnamePattern); + if (null !== $host) { + $subCollection->setHost($host); + } + if (null !== $schemes) { + $subCollection->setSchemes($schemes); + } + if (null !== $methods) { + $subCollection->setMethods($methods); } $subCollection->addDefaults($defaults); $subCollection->addRequirements($requirements); @@ -158,9 +177,9 @@ protected function validate($config, $name, $path) $path, $name, implode('", "', $extraKeys), implode('", "', self::$availableKeys) )); } - if (isset($config['resource']) && isset($config['pattern'])) { + if (isset($config['resource']) && isset($config['path'])) { throw new \InvalidArgumentException(sprintf( - 'The routing file "%s" must not specify both the "resource" key and the "pattern" key for "%s". Choose between an import and a route definition.', + '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 )); } @@ -170,9 +189,9 @@ protected function validate($config, $name, $path) $name, $path )); } - if (!isset($config['resource']) && !isset($config['pattern'])) { + if (!isset($config['resource']) && !isset($config['path'])) { throw new \InvalidArgumentException(sprintf( - 'You must define a "pattern" for the route "%s" in file "%s".', + 'You must define a "path" for the route "%s" in file "%s".', $name, $path )); } diff --git a/core/vendor/symfony/routing/Symfony/Component/Routing/Loader/schema/routing/routing-1.0.xsd b/core/vendor/symfony/routing/Symfony/Component/Routing/Loader/schema/routing/routing-1.0.xsd index 3143b3ac72a9..bbd918c3f516 100644 --- a/core/vendor/symfony/routing/Symfony/Component/Routing/Loader/schema/routing/routing-1.0.xsd +++ b/core/vendor/symfony/routing/Symfony/Component/Routing/Loader/schema/routing/routing-1.0.xsd @@ -17,6 +17,16 @@ <xsd:element name="routes" type="routes" /> + <xsd:simpleType name="word"> + <xsd:restriction base="xsd:string"> + <xsd:pattern value="([a-zA-Z]){3,}"/> + </xsd:restriction> + </xsd:simpleType> + + <xsd:simpleType name="stringlist"> + <xsd:list itemType="word"/> + </xsd:simpleType> + <xsd:complexType name="routes"> <xsd:choice minOccurs="0" maxOccurs="unbounded"> <xsd:element name="import" type="import" /> @@ -36,8 +46,11 @@ <xsd:group ref="configs" minOccurs="0" maxOccurs="unbounded" /> <xsd:attribute name="id" type="xsd:string" use="required" /> - <xsd:attribute name="pattern" type="xsd:string" use="required" /> - <xsd:attribute name="hostname-pattern" type="xsd:string" /> + <xsd:attribute name="path" type="xsd:string" /> + <xsd:attribute name="pattern" type="xsd:string" /> + <xsd:attribute name="host" type="xsd:string" /> + <xsd:attribute name="schemes" type="stringlist" /> + <xsd:attribute name="methods" type="stringlist" /> </xsd:complexType> <xsd:complexType name="import"> @@ -46,7 +59,9 @@ <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="hostname-pattern" type="xsd:string" /> + <xsd:attribute name="host" type="xsd:string" /> + <xsd:attribute name="schemes" type="stringlist" /> + <xsd:attribute name="methods" type="stringlist" /> </xsd:complexType> <xsd:complexType name="element"> diff --git a/core/vendor/symfony/routing/Symfony/Component/Routing/Matcher/Dumper/ApacheMatcherDumper.php b/core/vendor/symfony/routing/Symfony/Component/Routing/Matcher/Dumper/ApacheMatcherDumper.php index e46b506b10cb..804da19d54ec 100644 --- a/core/vendor/symfony/routing/Symfony/Component/Routing/Matcher/Dumper/ApacheMatcherDumper.php +++ b/core/vendor/symfony/routing/Symfony/Component/Routing/Matcher/Dumper/ApacheMatcherDumper.php @@ -46,30 +46,30 @@ public function dump(array $options = array()) $rules = array("# skip \"real\" requests\nRewriteCond %{REQUEST_FILENAME} -f\nRewriteRule .* - [QSA,L]"); $methodVars = array(); - $hostnameRegexUnique = 0; - $prevHostnameRegex = ''; + $hostRegexUnique = 0; + $prevHostRegex = ''; foreach ($this->getRoutes()->all() as $name => $route) { $compiledRoute = $route->compile(); - $hostnameRegex = $compiledRoute->getHostnameRegex(); + $hostRegex = $compiledRoute->getHostRegex(); - if (null !== $hostnameRegex && $prevHostnameRegex !== $hostnameRegex) { - $prevHostnameRegex = $hostnameRegex; - $hostnameRegexUnique++; + if (null !== $hostRegex && $prevHostRegex !== $hostRegex) { + $prevHostRegex = $hostRegex; + $hostRegexUnique++; $rule = array(); - $regex = $this->regexToApacheRegex($hostnameRegex); + $regex = $this->regexToApacheRegex($hostRegex); $regex = self::escape($regex, ' ', '\\'); $rule[] = sprintf('RewriteCond %%{HTTP:Host} %s', $regex); $variables = array(); - $variables[] = sprintf('E=__ROUTING_hostname_%s:1', $hostnameRegexUnique); + $variables[] = sprintf('E=__ROUTING_host_%s:1', $hostRegexUnique); - foreach ($compiledRoute->getHostnameVariables() as $i => $variable) { - $variables[] = sprintf('E=__ROUTING_hostname_%s_%s:%%%d', $hostnameRegexUnique, $variable, $i+1); + foreach ($compiledRoute->getHostVariables() as $i => $variable) { + $variables[] = sprintf('E=__ROUTING_host_%s_%s:%%%d', $hostRegexUnique, $variable, $i+1); } $variables = implode(',', $variables); @@ -79,7 +79,7 @@ public function dump(array $options = array()) $rules[] = implode("\n", $rule); } - $rules[] = $this->dumpRoute($name, $route, $options, $hostnameRegexUnique); + $rules[] = $this->dumpRoute($name, $route, $options, $hostRegexUnique); if ($req = $route->getRequirement('_method')) { $methods = explode('|', strtoupper($req)); @@ -109,11 +109,11 @@ public function dump(array $options = array()) * @param string $name Route name * @param Route $route The route * @param array $options Options - * @param bool $hostnameRegexUnique Unique identifier for the hostname regex + * @param bool $hostRegexUnique Unique identifier for the host regex * * @return string The compiled route */ - private function dumpRoute($name, $route, array $options, $hostnameRegexUnique) + private function dumpRoute($name, $route, array $options, $hostRegexUnique) { $compiledRoute = $route->compile(); @@ -126,8 +126,8 @@ private function dumpRoute($name, $route, array $options, $hostnameRegexUnique) $hasTrailingSlash = (!$methods || in_array('HEAD', $methods)) && '/$' === substr($regex, -2) && '^/$' !== $regex; $variables = array('E=_ROUTING_route:'.$name); - foreach ($compiledRoute->getHostnameVariables() as $variable) { - $variables[] = sprintf('E=_ROUTING_param_%s:%%{ENV:__ROUTING_hostname_%s_%s}', $variable, $hostnameRegexUnique, $variable); + foreach ($compiledRoute->getHostVariables() as $variable) { + $variables[] = sprintf('E=_ROUTING_param_%s:%%{ENV:__ROUTING_host_%s_%s}', $variable, $hostRegexUnique, $variable); } foreach ($compiledRoute->getPathVariables() as $i => $variable) { $variables[] = 'E=_ROUTING_param_'.$variable.':%'.($i + 1); @@ -151,8 +151,8 @@ private function dumpRoute($name, $route, array $options, $hostnameRegexUnique) $allow[] = 'E=_ROUTING_allow_'.$method.':1'; } - if ($hostnameRegex = $compiledRoute->getHostnameRegex()) { - $rule[] = sprintf("RewriteCond %%{ENV:__ROUTING_hostname_%s} =1", $hostnameRegexUnique); + if ($hostRegex = $compiledRoute->getHostRegex()) { + $rule[] = sprintf("RewriteCond %%{ENV:__ROUTING_host_%s} =1", $hostRegexUnique); } $rule[] = "RewriteCond %{REQUEST_URI} $regex"; @@ -163,8 +163,8 @@ private function dumpRoute($name, $route, array $options, $hostnameRegexUnique) // redirect with trailing slash appended if ($hasTrailingSlash) { - if ($hostnameRegex = $compiledRoute->getHostnameRegex()) { - $rule[] = sprintf("RewriteCond %%{ENV:__ROUTING_hostname_%s} =1", $hostnameRegexUnique); + if ($hostRegex = $compiledRoute->getHostRegex()) { + $rule[] = sprintf("RewriteCond %%{ENV:__ROUTING_host_%s} =1", $hostRegexUnique); } $rule[] = 'RewriteCond %{REQUEST_URI} '.substr($regex, 0, -2).'$'; @@ -173,8 +173,8 @@ private function dumpRoute($name, $route, array $options, $hostnameRegexUnique) // the main rule - if ($hostnameRegex = $compiledRoute->getHostnameRegex()) { - $rule[] = sprintf("RewriteCond %%{ENV:__ROUTING_hostname_%s} =1", $hostnameRegexUnique); + if ($hostRegex = $compiledRoute->getHostRegex()) { + $rule[] = sprintf("RewriteCond %%{ENV:__ROUTING_host_%s} =1", $hostRegexUnique); } $rule[] = "RewriteCond %{REQUEST_URI} $regex"; diff --git a/core/vendor/symfony/routing/Symfony/Component/Routing/Matcher/Dumper/PhpMatcherDumper.php b/core/vendor/symfony/routing/Symfony/Component/Routing/Matcher/Dumper/PhpMatcherDumper.php index 8fb232ea09ff..dc17ffbe984a 100644 --- a/core/vendor/symfony/routing/Symfony/Component/Routing/Matcher/Dumper/PhpMatcherDumper.php +++ b/core/vendor/symfony/routing/Symfony/Component/Routing/Matcher/Dumper/PhpMatcherDumper.php @@ -109,19 +109,19 @@ public function match(\$pathinfo) */ private function compileRoutes(RouteCollection $routes, $supportsRedirections) { - $fetchedHostname = false; + $fetchedHost = false; - $groups = $this->groupRoutesByHostnameRegex($routes); + $groups = $this->groupRoutesByHostRegex($routes); $code = ''; foreach ($groups as $collection) { - if (null !== $regex = $collection->getAttribute('hostname_regex')) { - if (!$fetchedHostname) { - $code .= " \$hostname = \$this->context->getHost();\n\n"; - $fetchedHostname = true; + if (null !== $regex = $collection->getAttribute('host_regex')) { + if (!$fetchedHost) { + $code .= " \$host = \$this->context->getHost();\n\n"; + $fetchedHost = true; } - $code .= sprintf(" if (preg_match(%s, \$hostname, \$hostnameMatches)) {\n", var_export($regex, true)); + $code .= sprintf(" if (preg_match(%s, \$host, \$hostMatches)) {\n", var_export($regex, true)); } $tree = $this->buildPrefixTree($collection); @@ -198,7 +198,7 @@ private function compileRoute(Route $route, $name, $supportsRedirections, $paren $conditions = array(); $hasTrailingSlash = false; $matches = false; - $hostnameMatches = false; + $hostMatches = false; $methods = array(); if ($req = $route->getRequirement('_method')) { @@ -233,8 +233,8 @@ private function compileRoute(Route $route, $name, $supportsRedirections, $paren $matches = true; } - if ($compiledRoute->getHostnameVariables()) { - $hostnameMatches = true; + if ($compiledRoute->getHostVariables()) { + $hostMatches = true; } $conditions = implode(' && ', $conditions); @@ -295,10 +295,10 @@ private function compileRoute(Route $route, $name, $supportsRedirections, $paren } // optimize parameters array - if ($matches || $hostnameMatches) { + if ($matches || $hostMatches) { $vars = array(); - if ($hostnameMatches) { - $vars[] = '$hostnameMatches'; + if ($hostMatches) { + $vars[] = '$hostMatches'; } if ($matches) { $vars[] = '$matches'; @@ -323,27 +323,27 @@ private function compileRoute(Route $route, $name, $supportsRedirections, $paren } /** - * Groups consecutive routes having the same hostname regex. + * Groups consecutive routes having the same host regex. * - * The result is a collection of collections of routes having the same hostname 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 hostname regex in sub-collections + * @return DumperCollection A collection with routes grouped by host regex in sub-collections */ - private function groupRoutesByHostnameRegex(RouteCollection $routes) + private function groupRoutesByHostRegex(RouteCollection $routes) { $groups = new DumperCollection(); $currentGroup = new DumperCollection(); - $currentGroup->setAttribute('hostname_regex', null); + $currentGroup->setAttribute('host_regex', null); $groups->add($currentGroup); foreach ($routes as $name => $route) { - $hostnameRegex = $route->compile()->getHostnameRegex(); - if ($currentGroup->getAttribute('hostname_regex') !== $hostnameRegex) { + $hostRegex = $route->compile()->getHostRegex(); + if ($currentGroup->getAttribute('host_regex') !== $hostRegex) { $currentGroup = new DumperCollection(); - $currentGroup->setAttribute('hostname_regex', $hostnameRegex); + $currentGroup->setAttribute('host_regex', $hostRegex); $groups->add($currentGroup); } $currentGroup->add(new DumperRoute($name, $route)); diff --git a/core/vendor/symfony/routing/Symfony/Component/Routing/Matcher/TraceableUrlMatcher.php b/core/vendor/symfony/routing/Symfony/Component/Routing/Matcher/TraceableUrlMatcher.php index 6ef846dd69a2..584d37e9a731 100644 --- a/core/vendor/symfony/routing/Symfony/Component/Routing/Matcher/TraceableUrlMatcher.php +++ b/core/vendor/symfony/routing/Symfony/Component/Routing/Matcher/TraceableUrlMatcher.php @@ -48,16 +48,16 @@ protected function matchCollection($pathinfo, RouteCollection $routes) if (!preg_match($compiledRoute->getRegex(), $pathinfo, $matches)) { // does it match without any requirements? - $r = new Route($route->getPattern(), $route->getDefaults(), array(), $route->getOptions()); + $r = new Route($route->getPath(), $route->getDefaults(), array(), $route->getOptions()); $cr = $r->compile(); if (!preg_match($cr->getRegex(), $pathinfo)) { - $this->addTrace(sprintf('Pattern "%s" does not match', $route->getPattern()), self::ROUTE_DOES_NOT_MATCH, $name, $route); + $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->getPattern(), $route->getDefaults(), array($n => $regex), $route->getOptions()); + $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)) { @@ -104,10 +104,10 @@ protected function matchCollection($pathinfo, RouteCollection $routes) private function addTrace($log, $level = self::ROUTE_DOES_NOT_MATCH, $name = null, $route = null) { $this->traces[] = array( - 'log' => $log, - 'name' => $name, - 'level' => $level, - 'pattern' => null !== $route ? $route->getPattern() : null, + 'log' => $log, + 'name' => $name, + 'level' => $level, + 'path' => null !== $route ? $route->getPath() : null, ); } } diff --git a/core/vendor/symfony/routing/Symfony/Component/Routing/Matcher/UrlMatcher.php b/core/vendor/symfony/routing/Symfony/Component/Routing/Matcher/UrlMatcher.php index c0fea2d7e7d5..db18ec4e7b25 100644 --- a/core/vendor/symfony/routing/Symfony/Component/Routing/Matcher/UrlMatcher.php +++ b/core/vendor/symfony/routing/Symfony/Component/Routing/Matcher/UrlMatcher.php @@ -116,8 +116,8 @@ protected function matchCollection($pathinfo, RouteCollection $routes) continue; } - $hostnameMatches = array(); - if ($compiledRoute->getHostnameRegex() && !preg_match($compiledRoute->getHostnameRegex(), $this->context->getHost(), $hostnameMatches)) { + $hostMatches = array(); + if ($compiledRoute->getHostRegex() && !preg_match($compiledRoute->getHostRegex(), $this->context->getHost(), $hostMatches)) { continue; } @@ -145,7 +145,7 @@ protected function matchCollection($pathinfo, RouteCollection $routes) continue; } - return $this->getAttributes($route, $name, array_replace($matches, $hostnameMatches)); + return $this->getAttributes($route, $name, array_replace($matches, $hostMatches)); } } diff --git a/core/vendor/symfony/routing/Symfony/Component/Routing/RequestContext.php b/core/vendor/symfony/routing/Symfony/Component/Routing/RequestContext.php index 1f9cf3c02c92..132ecc743cee 100644 --- a/core/vendor/symfony/routing/Symfony/Component/Routing/RequestContext.php +++ b/core/vendor/symfony/routing/Symfony/Component/Routing/RequestContext.php @@ -23,6 +23,7 @@ class RequestContext { private $baseUrl; + private $pathInfo; private $method; private $host; private $scheme; @@ -43,10 +44,11 @@ class RequestContext * @param string $scheme The HTTP scheme * @param integer $httpPort The HTTP port * @param integer $httpsPort The HTTPS port + * @param string $path The path * * @api */ - public function __construct($baseUrl = '', $method = 'GET', $host = 'localhost', $scheme = 'http', $httpPort = 80, $httpsPort = 443) + public function __construct($baseUrl = '', $method = 'GET', $host = 'localhost', $scheme = 'http', $httpPort = 80, $httpsPort = 443, $path = '/') { $this->baseUrl = $baseUrl; $this->method = strtoupper($method); @@ -54,11 +56,13 @@ public function __construct($baseUrl = '', $method = 'GET', $host = 'localhost', $this->scheme = strtolower($scheme); $this->httpPort = $httpPort; $this->httpsPort = $httpsPort; + $this->pathInfo = $path; } 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()); @@ -88,6 +92,26 @@ public function setBaseUrl($baseUrl) $this->baseUrl = $baseUrl; } + /** + * 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 + */ + public function setPathInfo($pathInfo) + { + $this->pathInfo = $pathInfo; + } + /** * Gets the HTTP method. * diff --git a/core/vendor/symfony/routing/Symfony/Component/Routing/Route.php b/core/vendor/symfony/routing/Symfony/Component/Routing/Route.php index 241c8ef36ead..478d4e12a062 100644 --- a/core/vendor/symfony/routing/Symfony/Component/Routing/Route.php +++ b/core/vendor/symfony/routing/Symfony/Component/Routing/Route.php @@ -15,6 +15,7 @@ * A Route describes a route and its parameters. * * @author Fabien Potencier <fabien@symfony.com> + * @author Tobias Schultze <http://tobion.de> * * @api */ @@ -23,14 +24,24 @@ class Route implements \Serializable /** * @var string */ - private $pattern = '/'; + private $path = '/'; /** * @var string */ - private $hostnamePattern = ''; + private $host = ''; - /** + /** + * @var array + */ + private $schemes = array(); + + /** + * @var array + */ + private $methods = array(); + + /** * @var array */ private $defaults = array(); @@ -50,8 +61,6 @@ class Route implements \Serializable */ private $compiled; - private static $compilers = array(); - /** * Constructor. * @@ -59,52 +68,68 @@ class Route implements \Serializable * * * compiler_class: A class name able to compile this route instance (RouteCompiler by default) * - * @param string $pattern 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 $hostnamePattern The hostname pattern to match + * @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|array $schemes A required URI scheme or an array of restricted schemes + * @param string|array $methods A required HTTP method or an array of restricted methods * * @api */ - public function __construct($pattern, array $defaults = array(), array $requirements = array(), array $options = array(), $hostnamePattern = '') + public function __construct($path, array $defaults = array(), array $requirements = array(), array $options = array(), $host = '', $schemes = array(), $methods = array()) { - $this->setPattern($pattern); + $this->setPath($path); $this->setDefaults($defaults); $this->setRequirements($requirements); $this->setOptions($options); - $this->setHostnamePattern($hostnamePattern); + $this->setHost($host); + // The conditions make sure that an initial empty $schemes/$methods does not override the corresponding requirement. + // They can be removed when the BC layer is removed. + if ($schemes) { + $this->setSchemes($schemes); + } + if ($methods) { + $this->setMethods($methods); + } } public function serialize() { return serialize(array( - 'pattern' => $this->pattern, - 'hostnamePattern' => $this->hostnamePattern, - 'defaults' => $this->defaults, + 'path' => $this->path, + 'host' => $this->host, + 'defaults' => $this->defaults, 'requirements' => $this->requirements, - 'options' => $this->options, + 'options' => $this->options, + 'schemes' => $this->schemes, + 'methods' => $this->methods, )); } public function unserialize($data) { $data = unserialize($data); - $this->pattern = $data['pattern']; - $this->hostnamePattern = $data['hostnamePattern']; + $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']; } /** * Returns the pattern for the path. * * @return string The pattern + * + * @deprecated Deprecated in 2.2, to be removed in 3.0. Use getPath instead. */ public function getPattern() { - return $this->pattern; + return $this->path; } /** @@ -112,40 +137,142 @@ public function getPattern() * * This method implements a fluent interface. * - * @param string $pattern The pattern + * @param string $pattern The path pattern * * @return Route The current Route instance + * + * @deprecated Deprecated in 2.2, to be removed in 3.0. Use setPath instead. */ public function setPattern($pattern) + { + return $this->setPath($pattern); + } + + /** + * 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 Route The current Route instance + */ + 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->pattern = '/' . ltrim(trim($pattern), '/'); + $this->path = '/' . ltrim(trim($pattern), '/'); $this->compiled = null; return $this; } /** - * Returns the hostname pattern. + * Returns the pattern for the host. * - * @return string The pattern + * @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 Route The current Route instance + */ + 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 array 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|array $schemes The scheme or an array of schemes + * + * @return Route The current Route instance + */ + public function setSchemes($schemes) + { + $this->schemes = array_map('strtolower', (array) $schemes); + + // this is to keep BC and will be removed in a future version + if ($this->schemes) { + $this->requirements['_scheme'] = implode('|', $this->schemes); + } else { + unset($this->requirements['_scheme']); + } + + $this->compiled = null; + + return $this; + } + + /** + * Returns the uppercased HTTP methods this route is restricted to. + * So an empty array means that any method is allowed. + * + * @return array The schemes */ - public function getHostnamePattern() + public function getMethods() { - return $this->hostnamePattern; + return $this->methods; } /** - * Sets the hostname pattern. + * Sets the HTTP methods (e.g. 'POST') this route is restricted to. + * So an empty array means that any method is allowed. * - * @param string $pattern The pattern + * This method implements a fluent interface. + * + * @param string|array $methods The method or an array of methods * * @return Route The current Route instance */ - public function setHostnamePattern($pattern) + public function setMethods($methods) { - $this->hostnamePattern = (string) $pattern; + $this->methods = array_map('strtoupper', (array) $methods); + + // this is to keep BC and will be removed in a future version + if ($this->methods) { + $this->requirements['_method'] = implode('|', $this->methods); + } else { + unset($this->requirements['_method']); + } + $this->compiled = null; return $this; @@ -421,6 +548,9 @@ public function setRequirement($key, $regex) * * @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() @@ -431,11 +561,7 @@ public function compile() $class = $this->getOption('compiler_class'); - if (!isset(self::$compilers[$class])) { - self::$compilers[$class] = new $class; - } - - return $this->compiled = self::$compilers[$class]->compile($this); + return $this->compiled = $class::compile($this); } private function sanitizeRequirement($key, $regex) @@ -456,6 +582,13 @@ private function sanitizeRequirement($key, $regex) throw new \InvalidArgumentException(sprintf('Routing requirement for "%s" cannot be empty.', $key)); } + // this is to keep BC and will be removed in a future version + if ('_scheme' === $key) { + $this->setSchemes(explode('|', $regex)); + } elseif ('_method' === $key) { + $this->setMethods(explode('|', $regex)); + } + return $regex; } } diff --git a/core/vendor/symfony/routing/Symfony/Component/Routing/RouteCollection.php b/core/vendor/symfony/routing/Symfony/Component/Routing/RouteCollection.php index 4df6f7d145ed..e53606da5f19 100644 --- a/core/vendor/symfony/routing/Symfony/Component/Routing/RouteCollection.php +++ b/core/vendor/symfony/routing/Symfony/Component/Routing/RouteCollection.php @@ -235,7 +235,7 @@ public function addPrefix($prefix, array $defaults = array(), array $requirement $options = func_num_args() > 3 ? func_get_arg(3) : array(); foreach ($this->routes as $route) { - $route->setPattern('/' . $prefix . $route->getPattern()); + $route->setPath('/' . $prefix . $route->getPath()); $route->addDefaults($defaults); $route->addRequirements($requirements); $route->addOptions($options); @@ -255,16 +255,16 @@ public function getPrefix() } /** - * Sets the hostname pattern on all routes. + * 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 setHostnamePattern($pattern, array $defaults = array(), array $requirements = array()) + public function setHost($pattern, array $defaults = array(), array $requirements = array()) { foreach ($this->routes as $route) { - $route->setHostnamePattern($pattern); + $route->setHost($pattern); $route->addDefaults($defaults); $route->addRequirements($requirements); } @@ -318,6 +318,30 @@ public function addOptions(array $options) } } + /** + * Sets the schemes (e.g. 'https') all child routes are restricted to. + * + * @param string|array $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|array $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. * diff --git a/core/vendor/symfony/routing/Symfony/Component/Routing/RouteCompiler.php b/core/vendor/symfony/routing/Symfony/Component/Routing/RouteCompiler.php index 991ce0985ba2..25e4029f045f 100644 --- a/core/vendor/symfony/routing/Symfony/Component/Routing/RouteCompiler.php +++ b/core/vendor/symfony/routing/Symfony/Component/Routing/RouteCompiler.php @@ -35,30 +35,30 @@ class RouteCompiler implements RouteCompilerInterface * @throws \DomainException If a variable name is numeric because PHP raises an error for such * subpatterns in PCRE and thus would break matching, e.g. "(?P<123>.+)". */ - public function compile(Route $route) + public static function compile(Route $route) { $staticPrefix = null; - $hostnameVariables = array(); + $hostVariables = array(); $pathVariables = array(); $variables = array(); $tokens = array(); $regex = null; - $hostnameRegex = null; - $hostnameTokens = array(); + $hostRegex = null; + $hostTokens = array(); - if ('' !== $hostnamePattern = $route->getHostnamePattern()) { - $result = $this->compilePattern($route, $hostnamePattern, true); + if ('' !== $host = $route->getHost()) { + $result = self::compilePattern($route, $host, true); - $hostnameVariables = $result['variables']; - $variables = array_merge($variables, $hostnameVariables); + $hostVariables = $result['variables']; + $variables = array_merge($variables, $hostVariables); - $hostnameTokens = $result['tokens']; - $hostnameRegex = $result['regex']; + $hostTokens = $result['tokens']; + $hostRegex = $result['regex']; } - $pattern = $route->getPattern(); + $path = $route->getPath(); - $result = $this->compilePattern($route, $pattern, false); + $result = self::compilePattern($route, $path, false); $staticPrefix = $result['staticPrefix']; @@ -73,20 +73,20 @@ public function compile(Route $route) $regex, $tokens, $pathVariables, - $hostnameRegex, - $hostnameTokens, - $hostnameVariables, + $hostRegex, + $hostTokens, + $hostVariables, array_unique($variables) ); } - private function compilePattern(Route $route, $pattern, $isHostname) + private static function compilePattern(Route $route, $pattern, $isHost) { $tokens = array(); $variables = array(); $matches = array(); $pos = 0; - $defaultSeparator = $isHostname ? '.' : '/'; + $defaultSeparator = $isHost ? '.' : '/'; // 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. @@ -122,7 +122,7 @@ private function compilePattern(Route $route, $pattern, $isHostname) // 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 = $this->findNextSeparator($followingPattern); + $nextSeparator = self::findNextSeparator($followingPattern); $regexp = sprintf( '[^%s%s]+', preg_quote($defaultSeparator, self::REGEX_DELIMITER), @@ -148,7 +148,7 @@ private function compilePattern(Route $route, $pattern, $isHostname) // find the first optional token $firstOptional = INF; - if (!$isHostname) { + if (!$isHost) { for ($i = count($tokens) - 1; $i >= 0; $i--) { $token = $tokens[$i]; if ('variable' === $token[0] && $route->hasDefault($token[3])) { @@ -162,7 +162,7 @@ private function compilePattern(Route $route, $pattern, $isHostname) // compute the matching regexp $regexp = ''; for ($i = 0, $nbToken = count($tokens); $i < $nbToken; $i++) { - $regexp .= $this->computeRegexp($tokens, $i, $firstOptional); + $regexp .= self::computeRegexp($tokens, $i, $firstOptional); } return array( @@ -180,7 +180,7 @@ private function compilePattern(Route $route, $pattern, $isHostname) * * @return string The next static character that functions as separator (or empty string when none available) */ - private function findNextSeparator($pattern) + private static function findNextSeparator($pattern) { if ('' == $pattern) { // return empty string if pattern is empty or false (false which can be returned by substr) @@ -201,7 +201,7 @@ private function findNextSeparator($pattern) * * @return string The regexp pattern for a single token */ - private function computeRegexp(array $tokens, $index, $firstOptional) + private static function computeRegexp(array $tokens, $index, $firstOptional) { $token = $tokens[$index]; if ('text' === $token[0]) { diff --git a/core/vendor/symfony/routing/Symfony/Component/Routing/RouteCompilerInterface.php b/core/vendor/symfony/routing/Symfony/Component/Routing/RouteCompilerInterface.php index f72e9e5ef423..e6f8ee6deacc 100644 --- a/core/vendor/symfony/routing/Symfony/Component/Routing/RouteCompilerInterface.php +++ b/core/vendor/symfony/routing/Symfony/Component/Routing/RouteCompilerInterface.php @@ -24,6 +24,9 @@ interface RouteCompilerInterface * @param Route $route A Route instance * * @return CompiledRoute A CompiledRoute instance + * + * @throws \LogicException If the Route cannot be compiled because the + * path or host pattern is invalid */ - public function compile(Route $route); + public static function compile(Route $route); } diff --git a/core/vendor/symfony/routing/Symfony/Component/Routing/Router.php b/core/vendor/symfony/routing/Symfony/Component/Routing/Router.php index 68d73ab24db4..fe638792b115 100644 --- a/core/vendor/symfony/routing/Symfony/Component/Routing/Router.php +++ b/core/vendor/symfony/routing/Symfony/Component/Routing/Router.php @@ -13,7 +13,7 @@ use Symfony\Component\Config\Loader\LoaderInterface; use Symfony\Component\Config\ConfigCache; -use Symfony\Component\HttpKernel\Log\LoggerInterface; +use Psr\Log\LoggerInterface; use Symfony\Component\Routing\Generator\ConfigurableRequirementsInterface; use Symfony\Component\Routing\Generator\UrlGeneratorInterface; use Symfony\Component\Routing\Matcher\UrlMatcherInterface; @@ -202,9 +202,9 @@ public function getContext() /** * {@inheritdoc} */ - public function generate($name, $parameters = array(), $absolute = false) + public function generate($name, $parameters = array(), $referenceType = self::ABSOLUTE_PATH) { - return $this->getGenerator()->generate($name, $parameters, $absolute); + return $this->getGenerator()->generate($name, $parameters, $referenceType); } /** diff --git a/core/vendor/symfony/routing/Symfony/Component/Routing/Tests/Annotation/RouteTest.php b/core/vendor/symfony/routing/Symfony/Component/Routing/Tests/Annotation/RouteTest.php index e1da00270056..b58869f7afc6 100644 --- a/core/vendor/symfony/routing/Symfony/Component/Routing/Tests/Annotation/RouteTest.php +++ b/core/vendor/symfony/routing/Symfony/Component/Routing/Tests/Annotation/RouteTest.php @@ -36,11 +36,14 @@ public function getValidParameters() { return array( array('value', '/Blog', 'getPattern'), + array('value', '/Blog', 'getPath'), array('requirements', array('_method' => 'GET'), 'getRequirements'), array('options', array('compiler_class' => 'RouteCompiler'), 'getOptions'), array('name', 'blog_index', 'getName'), array('defaults', array('_controller' => 'MyBlogBundle:Blog:index'), 'getDefaults'), - array('hostname_pattern', array('{locale}.example.com'), 'getHostnamePattern') + array('schemes', array('https'), 'getSchemes'), + array('methods', array('GET', 'POST'), 'getMethods'), + array('host', array('{locale}.example.com'), 'getHost') ); } } diff --git a/core/vendor/symfony/routing/Symfony/Component/Routing/Tests/Fixtures/dumper/url_matcher1.apache b/core/vendor/symfony/routing/Symfony/Component/Routing/Tests/Fixtures/dumper/url_matcher1.apache index 4b9c11d4d061..26a561cc9118 100644 --- a/core/vendor/symfony/routing/Symfony/Component/Routing/Tests/Fixtures/dumper/url_matcher1.apache +++ b/core/vendor/symfony/routing/Symfony/Component/Routing/Tests/Fixtures/dumper/url_matcher1.apache @@ -77,39 +77,39 @@ RewriteCond %{REQUEST_URI} ^/test/(te\\\ st)$ RewriteRule .* app.php [QSA,L,E=_ROUTING_route:baz9,E=_ROUTING_param_baz:%1] RewriteCond %{HTTP:Host} ^a\.example\.com$ -RewriteRule .? - [E=__ROUTING_hostname_1:1] +RewriteRule .? - [E=__ROUTING_host_1:1] # route1 -RewriteCond %{ENV:__ROUTING_hostname_1} =1 +RewriteCond %{ENV:__ROUTING_host_1} =1 RewriteCond %{REQUEST_URI} ^/route1$ RewriteRule .* app.php [QSA,L,E=_ROUTING_route:route1] # route2 -RewriteCond %{ENV:__ROUTING_hostname_1} =1 +RewriteCond %{ENV:__ROUTING_host_1} =1 RewriteCond %{REQUEST_URI} ^/c2/route2$ RewriteRule .* app.php [QSA,L,E=_ROUTING_route:route2] RewriteCond %{HTTP:Host} ^b\.example\.com$ -RewriteRule .? - [E=__ROUTING_hostname_2:1] +RewriteRule .? - [E=__ROUTING_host_2:1] # route3 -RewriteCond %{ENV:__ROUTING_hostname_2} =1 +RewriteCond %{ENV:__ROUTING_host_2} =1 RewriteCond %{REQUEST_URI} ^/c2/route3$ RewriteRule .* app.php [QSA,L,E=_ROUTING_route:route3] RewriteCond %{HTTP:Host} ^a\.example\.com$ -RewriteRule .? - [E=__ROUTING_hostname_3:1] +RewriteRule .? - [E=__ROUTING_host_3:1] # route4 -RewriteCond %{ENV:__ROUTING_hostname_3} =1 +RewriteCond %{ENV:__ROUTING_host_3} =1 RewriteCond %{REQUEST_URI} ^/route4$ RewriteRule .* app.php [QSA,L,E=_ROUTING_route:route4] RewriteCond %{HTTP:Host} ^c\.example\.com$ -RewriteRule .? - [E=__ROUTING_hostname_4:1] +RewriteRule .? - [E=__ROUTING_host_4:1] # route5 -RewriteCond %{ENV:__ROUTING_hostname_4} =1 +RewriteCond %{ENV:__ROUTING_host_4} =1 RewriteCond %{REQUEST_URI} ^/route5$ RewriteRule .* app.php [QSA,L,E=_ROUTING_route:route5] @@ -118,33 +118,33 @@ RewriteCond %{REQUEST_URI} ^/route6$ RewriteRule .* app.php [QSA,L,E=_ROUTING_route:route6] RewriteCond %{HTTP:Host} ^([^\.]++)\.example\.com$ -RewriteRule .? - [E=__ROUTING_hostname_5:1,E=__ROUTING_hostname_5_var1:%1] +RewriteRule .? - [E=__ROUTING_host_5:1,E=__ROUTING_host_5_var1:%1] # route11 -RewriteCond %{ENV:__ROUTING_hostname_5} =1 +RewriteCond %{ENV:__ROUTING_host_5} =1 RewriteCond %{REQUEST_URI} ^/route11$ -RewriteRule .* app.php [QSA,L,E=_ROUTING_route:route11,E=_ROUTING_param_var1:%{ENV:__ROUTING_hostname_5_var1}] +RewriteRule .* app.php [QSA,L,E=_ROUTING_route:route11,E=_ROUTING_param_var1:%{ENV:__ROUTING_host_5_var1}] # route12 -RewriteCond %{ENV:__ROUTING_hostname_5} =1 +RewriteCond %{ENV:__ROUTING_host_5} =1 RewriteCond %{REQUEST_URI} ^/route12$ -RewriteRule .* app.php [QSA,L,E=_ROUTING_route:route12,E=_ROUTING_param_var1:%{ENV:__ROUTING_hostname_5_var1},E=_ROUTING_default_var1:val] +RewriteRule .* app.php [QSA,L,E=_ROUTING_route:route12,E=_ROUTING_param_var1:%{ENV:__ROUTING_host_5_var1},E=_ROUTING_default_var1:val] # route13 -RewriteCond %{ENV:__ROUTING_hostname_5} =1 +RewriteCond %{ENV:__ROUTING_host_5} =1 RewriteCond %{REQUEST_URI} ^/route13/([^/]++)$ -RewriteRule .* app.php [QSA,L,E=_ROUTING_route:route13,E=_ROUTING_param_var1:%{ENV:__ROUTING_hostname_5_var1},E=_ROUTING_param_name:%1] +RewriteRule .* app.php [QSA,L,E=_ROUTING_route:route13,E=_ROUTING_param_var1:%{ENV:__ROUTING_host_5_var1},E=_ROUTING_param_name:%1] # route14 -RewriteCond %{ENV:__ROUTING_hostname_5} =1 +RewriteCond %{ENV:__ROUTING_host_5} =1 RewriteCond %{REQUEST_URI} ^/route14/([^/]++)$ -RewriteRule .* app.php [QSA,L,E=_ROUTING_route:route14,E=_ROUTING_param_var1:%{ENV:__ROUTING_hostname_5_var1},E=_ROUTING_param_name:%1,E=_ROUTING_default_var1:val] +RewriteRule .* app.php [QSA,L,E=_ROUTING_route:route14,E=_ROUTING_param_var1:%{ENV:__ROUTING_host_5_var1},E=_ROUTING_param_name:%1,E=_ROUTING_default_var1:val] RewriteCond %{HTTP:Host} ^c\.example\.com$ -RewriteRule .? - [E=__ROUTING_hostname_6:1] +RewriteRule .? - [E=__ROUTING_host_6:1] # route15 -RewriteCond %{ENV:__ROUTING_hostname_6} =1 +RewriteCond %{ENV:__ROUTING_host_6} =1 RewriteCond %{REQUEST_URI} ^/route15/([^/]++)$ RewriteRule .* app.php [QSA,L,E=_ROUTING_route:route15,E=_ROUTING_param_name:%1] diff --git a/core/vendor/symfony/routing/Symfony/Component/Routing/Tests/Fixtures/dumper/url_matcher1.php b/core/vendor/symfony/routing/Symfony/Component/Routing/Tests/Fixtures/dumper/url_matcher1.php index bb4e623ed979..e5f7665c81bc 100644 --- a/core/vendor/symfony/routing/Symfony/Component/Routing/Tests/Fixtures/dumper/url_matcher1.php +++ b/core/vendor/symfony/routing/Symfony/Component/Routing/Tests/Fixtures/dumper/url_matcher1.php @@ -193,9 +193,9 @@ public function match($pathinfo) } - $hostname = $this->context->getHost(); + $host = $this->context->getHost(); - if (preg_match('#^a\\.example\\.com$#s', $hostname, $hostnameMatches)) { + if (preg_match('#^a\\.example\\.com$#s', $host, $hostMatches)) { // route1 if ($pathinfo === '/route1') { return array('_route' => 'route1'); @@ -208,7 +208,7 @@ public function match($pathinfo) } - if (preg_match('#^b\\.example\\.com$#s', $hostname, $hostnameMatches)) { + if (preg_match('#^b\\.example\\.com$#s', $host, $hostMatches)) { // route3 if ($pathinfo === '/c2/route3') { return array('_route' => 'route3'); @@ -216,7 +216,7 @@ public function match($pathinfo) } - if (preg_match('#^a\\.example\\.com$#s', $hostname, $hostnameMatches)) { + if (preg_match('#^a\\.example\\.com$#s', $host, $hostMatches)) { // route4 if ($pathinfo === '/route4') { return array('_route' => 'route4'); @@ -224,7 +224,7 @@ public function match($pathinfo) } - if (preg_match('#^c\\.example\\.com$#s', $hostname, $hostnameMatches)) { + if (preg_match('#^c\\.example\\.com$#s', $host, $hostMatches)) { // route5 if ($pathinfo === '/route5') { return array('_route' => 'route5'); @@ -237,33 +237,33 @@ public function match($pathinfo) return array('_route' => 'route6'); } - if (preg_match('#^(?P<var1>[^\\.]++)\\.example\\.com$#s', $hostname, $hostnameMatches)) { + if (preg_match('#^(?P<var1>[^\\.]++)\\.example\\.com$#s', $host, $hostMatches)) { if (0 === strpos($pathinfo, '/route1')) { // route11 if ($pathinfo === '/route11') { - return $this->mergeDefaults(array_replace($hostnameMatches, array('_route' => 'route11')), array ()); + return $this->mergeDefaults(array_replace($hostMatches, array('_route' => 'route11')), array ()); } // route12 if ($pathinfo === '/route12') { - return $this->mergeDefaults(array_replace($hostnameMatches, array('_route' => 'route12')), array ( 'var1' => 'val',)); + return $this->mergeDefaults(array_replace($hostMatches, array('_route' => 'route12')), array ( 'var1' => 'val',)); } // route13 if (0 === strpos($pathinfo, '/route13') && preg_match('#^/route13/(?P<name>[^/]++)$#s', $pathinfo, $matches)) { - return $this->mergeDefaults(array_replace($hostnameMatches, $matches, array('_route' => 'route13')), array ()); + return $this->mergeDefaults(array_replace($hostMatches, $matches, array('_route' => 'route13')), array ()); } // route14 if (0 === strpos($pathinfo, '/route14') && preg_match('#^/route14/(?P<name>[^/]++)$#s', $pathinfo, $matches)) { - return $this->mergeDefaults(array_replace($hostnameMatches, $matches, array('_route' => 'route14')), array ( 'var1' => 'val',)); + return $this->mergeDefaults(array_replace($hostMatches, $matches, array('_route' => 'route14')), array ( 'var1' => 'val',)); } } } - if (preg_match('#^c\\.example\\.com$#s', $hostname, $hostnameMatches)) { + if (preg_match('#^c\\.example\\.com$#s', $host, $hostMatches)) { // route15 if (0 === strpos($pathinfo, '/route15') && preg_match('#^/route15/(?P<name>[^/]++)$#s', $pathinfo, $matches)) { return $this->mergeDefaults(array_replace($matches, array('_route' => 'route15')), array ()); diff --git a/core/vendor/symfony/routing/Symfony/Component/Routing/Tests/Fixtures/dumper/url_matcher2.php b/core/vendor/symfony/routing/Symfony/Component/Routing/Tests/Fixtures/dumper/url_matcher2.php index 2bd38122a088..ad157909b8c0 100644 --- a/core/vendor/symfony/routing/Symfony/Component/Routing/Tests/Fixtures/dumper/url_matcher2.php +++ b/core/vendor/symfony/routing/Symfony/Component/Routing/Tests/Fixtures/dumper/url_matcher2.php @@ -205,9 +205,9 @@ public function match($pathinfo) } - $hostname = $this->context->getHost(); + $host = $this->context->getHost(); - if (preg_match('#^a\\.example\\.com$#s', $hostname, $hostnameMatches)) { + if (preg_match('#^a\\.example\\.com$#s', $host, $hostMatches)) { // route1 if ($pathinfo === '/route1') { return array('_route' => 'route1'); @@ -220,7 +220,7 @@ public function match($pathinfo) } - if (preg_match('#^b\\.example\\.com$#s', $hostname, $hostnameMatches)) { + if (preg_match('#^b\\.example\\.com$#s', $host, $hostMatches)) { // route3 if ($pathinfo === '/c2/route3') { return array('_route' => 'route3'); @@ -228,7 +228,7 @@ public function match($pathinfo) } - if (preg_match('#^a\\.example\\.com$#s', $hostname, $hostnameMatches)) { + if (preg_match('#^a\\.example\\.com$#s', $host, $hostMatches)) { // route4 if ($pathinfo === '/route4') { return array('_route' => 'route4'); @@ -236,7 +236,7 @@ public function match($pathinfo) } - if (preg_match('#^c\\.example\\.com$#s', $hostname, $hostnameMatches)) { + if (preg_match('#^c\\.example\\.com$#s', $host, $hostMatches)) { // route5 if ($pathinfo === '/route5') { return array('_route' => 'route5'); @@ -249,33 +249,33 @@ public function match($pathinfo) return array('_route' => 'route6'); } - if (preg_match('#^(?P<var1>[^\\.]++)\\.example\\.com$#s', $hostname, $hostnameMatches)) { + if (preg_match('#^(?P<var1>[^\\.]++)\\.example\\.com$#s', $host, $hostMatches)) { if (0 === strpos($pathinfo, '/route1')) { // route11 if ($pathinfo === '/route11') { - return $this->mergeDefaults(array_replace($hostnameMatches, array('_route' => 'route11')), array ()); + return $this->mergeDefaults(array_replace($hostMatches, array('_route' => 'route11')), array ()); } // route12 if ($pathinfo === '/route12') { - return $this->mergeDefaults(array_replace($hostnameMatches, array('_route' => 'route12')), array ( 'var1' => 'val',)); + return $this->mergeDefaults(array_replace($hostMatches, array('_route' => 'route12')), array ( 'var1' => 'val',)); } // route13 if (0 === strpos($pathinfo, '/route13') && preg_match('#^/route13/(?P<name>[^/]++)$#s', $pathinfo, $matches)) { - return $this->mergeDefaults(array_replace($hostnameMatches, $matches, array('_route' => 'route13')), array ()); + return $this->mergeDefaults(array_replace($hostMatches, $matches, array('_route' => 'route13')), array ()); } // route14 if (0 === strpos($pathinfo, '/route14') && preg_match('#^/route14/(?P<name>[^/]++)$#s', $pathinfo, $matches)) { - return $this->mergeDefaults(array_replace($hostnameMatches, $matches, array('_route' => 'route14')), array ( 'var1' => 'val',)); + return $this->mergeDefaults(array_replace($hostMatches, $matches, array('_route' => 'route14')), array ( 'var1' => 'val',)); } } } - if (preg_match('#^c\\.example\\.com$#s', $hostname, $hostnameMatches)) { + if (preg_match('#^c\\.example\\.com$#s', $host, $hostMatches)) { // route15 if (0 === strpos($pathinfo, '/route15') && preg_match('#^/route15/(?P<name>[^/]++)$#s', $pathinfo, $matches)) { return $this->mergeDefaults(array_replace($matches, array('_route' => 'route15')), array ()); diff --git a/core/vendor/symfony/routing/Symfony/Component/Routing/Tests/Fixtures/namespaceprefix.xml b/core/vendor/symfony/routing/Symfony/Component/Routing/Tests/Fixtures/namespaceprefix.xml index efc4da9b37bc..79ec6e916922 100644 --- a/core/vendor/symfony/routing/Symfony/Component/Routing/Tests/Fixtures/namespaceprefix.xml +++ b/core/vendor/symfony/routing/Symfony/Component/Routing/Tests/Fixtures/namespaceprefix.xml @@ -4,7 +4,7 @@ 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" pattern="/blog/{slug}" hostname-pattern="{_locale}.example.com"> + <r:route id="blog_show" pattern="/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> diff --git a/core/vendor/symfony/routing/Symfony/Component/Routing/Tests/Fixtures/validpattern.xml b/core/vendor/symfony/routing/Symfony/Component/Routing/Tests/Fixtures/validpattern.xml index 079116399c46..eb3aea78b67a 100644 --- a/core/vendor/symfony/routing/Symfony/Component/Routing/Tests/Fixtures/validpattern.xml +++ b/core/vendor/symfony/routing/Symfony/Component/Routing/Tests/Fixtures/validpattern.xml @@ -4,7 +4,7 @@ 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" pattern="/blog/{slug}" hostname-pattern="{locale}.example.com"> + <route id="blog_show" pattern="/blog/{slug}" host="{locale}.example.com"> <default key="_controller">MyBundle:Blog:show</default> <requirement key="_method">GET</requirement> <requirement key="locale">\w+</requirement> diff --git a/core/vendor/symfony/routing/Symfony/Component/Routing/Tests/Fixtures/validpattern.yml b/core/vendor/symfony/routing/Symfony/Component/Routing/Tests/Fixtures/validpattern.yml index 8fad8a0923a4..d78a3e44e7b1 100644 --- a/core/vendor/symfony/routing/Symfony/Component/Routing/Tests/Fixtures/validpattern.yml +++ b/core/vendor/symfony/routing/Symfony/Component/Routing/Tests/Fixtures/validpattern.yml @@ -1,7 +1,7 @@ blog_show: - pattern: /blog/{slug} - defaults: { _controller: MyBlogBundle:Blog:show } - hostname_pattern: "{locale}.example.com" - requirements: { '_method': 'GET', 'locale': '\w+' } + pattern: /blog/{slug} + defaults: { _controller: MyBlogBundle:Blog:show } + host : "{locale}.example.com" + requirements: { '_method': 'GET', 'locale': '\w+' } options: compiler_class: RouteCompiler diff --git a/core/vendor/symfony/routing/Symfony/Component/Routing/Tests/Fixtures/validresource.xml b/core/vendor/symfony/routing/Symfony/Component/Routing/Tests/Fixtures/validresource.xml index b3747864fbe5..dd457dc82114 100644 --- a/core/vendor/symfony/routing/Symfony/Component/Routing/Tests/Fixtures/validresource.xml +++ b/core/vendor/symfony/routing/Symfony/Component/Routing/Tests/Fixtures/validresource.xml @@ -4,7 +4,7 @@ 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}" hostname-pattern="{locale}.example.com"> + <import resource="validpattern.xml" prefix="/{foo}" host="{locale}.example.com"> <default key="foo">123</default> <requirement key="foo">\d+</requirement> <option key="foo">bar</option> diff --git a/core/vendor/symfony/routing/Symfony/Component/Routing/Tests/Fixtures/validresource.yml b/core/vendor/symfony/routing/Symfony/Component/Routing/Tests/Fixtures/validresource.yml index 35a45398ff14..1f5644e04b02 100644 --- a/core/vendor/symfony/routing/Symfony/Component/Routing/Tests/Fixtures/validresource.yml +++ b/core/vendor/symfony/routing/Symfony/Component/Routing/Tests/Fixtures/validresource.yml @@ -1,7 +1,7 @@ blog_show: - resource: validpattern.yml - prefix: /{foo} - defaults: { 'foo': '123' } - requirements: { 'foo': '\d+' } - options: { 'foo': 'bar' } - hostname_pattern: "{locale}.example.com" + resource: validpattern.yml + prefix: /{foo} + defaults: { 'foo': '123' } + requirements: { 'foo': '\d+' } + options: { 'foo': 'bar' } + host: "{locale}.example.com" diff --git a/core/vendor/symfony/routing/Symfony/Component/Routing/Tests/Generator/Dumper/PhpGeneratorDumperTest.php b/core/vendor/symfony/routing/Symfony/Component/Routing/Tests/Generator/Dumper/PhpGeneratorDumperTest.php index 6a86736abbb1..ab5f4cdae0aa 100644 --- a/core/vendor/symfony/routing/Symfony/Component/Routing/Tests/Generator/Dumper/PhpGeneratorDumperTest.php +++ b/core/vendor/symfony/routing/Symfony/Component/Routing/Tests/Generator/Dumper/PhpGeneratorDumperTest.php @@ -89,7 +89,7 @@ public function testDumpWithoutRoutes() } /** - * @expectedException Symfony\Component\Routing\Exception\RouteNotFoundException + * @expectedException \Symfony\Component\Routing\Exception\RouteNotFoundException */ public function testGenerateNonExistingRoute() { diff --git a/core/vendor/symfony/routing/Symfony/Component/Routing/Tests/Generator/UrlGeneratorTest.php b/core/vendor/symfony/routing/Symfony/Component/Routing/Tests/Generator/UrlGeneratorTest.php index a3f50b6aca13..0728503b0632 100644 --- a/core/vendor/symfony/routing/Symfony/Component/Routing/Tests/Generator/UrlGeneratorTest.php +++ b/core/vendor/symfony/routing/Symfony/Component/Routing/Tests/Generator/UrlGeneratorTest.php @@ -14,6 +14,7 @@ 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 \PHPUnit_Framework_TestCase @@ -75,7 +76,7 @@ public function testRelativeUrlWithNullParameter() } /** - * @expectedException Symfony\Component\Routing\Exception\InvalidParameterException + * @expectedException \Symfony\Component\Routing\Exception\InvalidParameterException */ public function testRelativeUrlWithNullParameterButNotOptional() { @@ -161,7 +162,7 @@ public function testGlobalParameterHasHigherPriorityThanDefault() } /** - * @expectedException Symfony\Component\Routing\Exception\RouteNotFoundException + * @expectedException \Symfony\Component\Routing\Exception\RouteNotFoundException */ public function testGenerateWithoutRoutes() { @@ -170,7 +171,7 @@ public function testGenerateWithoutRoutes() } /** - * @expectedException Symfony\Component\Routing\Exception\MissingMandatoryParametersException + * @expectedException \Symfony\Component\Routing\Exception\MissingMandatoryParametersException */ public function testGenerateForRouteWithoutMandatoryParameter() { @@ -179,7 +180,7 @@ public function testGenerateForRouteWithoutMandatoryParameter() } /** - * @expectedException Symfony\Component\Routing\Exception\InvalidParameterException + * @expectedException \Symfony\Component\Routing\Exception\InvalidParameterException */ public function testGenerateForRouteWithInvalidOptionalParameter() { @@ -188,7 +189,7 @@ public function testGenerateForRouteWithInvalidOptionalParameter() } /** - * @expectedException Symfony\Component\Routing\Exception\InvalidParameterException + * @expectedException \Symfony\Component\Routing\Exception\InvalidParameterException */ public function testGenerateForRouteWithInvalidParameter() { @@ -206,14 +207,14 @@ public function testGenerateForRouteWithInvalidOptionalParameterNonStrict() public function testGenerateForRouteWithInvalidOptionalParameterNonStrictWithLogger() { - if (!interface_exists('Symfony\Component\HttpKernel\Log\LoggerInterface')) { - $this->markTestSkipped('The "HttpKernel" component is not available'); + if (!interface_exists('Psr\Log\LoggerInterface')) { + $this->markTestSkipped('The "psr/log" package is not available'); } $routes = $this->getRoutes('test', new Route('/testing/{foo}', array('foo' => '1'), array('foo' => 'd+'))); - $logger = $this->getMock('Symfony\Component\HttpKernel\Log\LoggerInterface'); + $logger = $this->getMock('Psr\Log\LoggerInterface'); $logger->expects($this->once()) - ->method('err'); + ->method('error'); $generator = $this->getGenerator($routes, array(), $logger); $generator->setStrictRequirements(false); $this->assertNull($generator->generate('test', array('foo' => 'bar'), true)); @@ -228,7 +229,7 @@ public function testGenerateForRouteWithInvalidParameterButDisabledRequirementsC } /** - * @expectedException Symfony\Component\Routing\Exception\InvalidParameterException + * @expectedException \Symfony\Component\Routing\Exception\InvalidParameterException */ public function testGenerateForRouteWithInvalidMandatoryParameter() { @@ -237,7 +238,7 @@ public function testGenerateForRouteWithInvalidMandatoryParameter() } /** - * @expectedException Symfony\Component\Routing\Exception\InvalidParameterException + * @expectedException \Symfony\Component\Routing\Exception\InvalidParameterException */ public function testRequiredParamAndEmptyPassed() { @@ -366,7 +367,7 @@ public function testDefaultRequirementOfVariable() } /** - * @expectedException Symfony\Component\Routing\Exception\InvalidParameterException + * @expectedException \Symfony\Component\Routing\Exception\InvalidParameterException */ public function testDefaultRequirementOfVariableDisallowsSlash() { @@ -375,30 +376,29 @@ public function testDefaultRequirementOfVariableDisallowsSlash() } /** - * @expectedException Symfony\Component\Routing\Exception\InvalidParameterException + * @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 testWithHostnameDifferentFromContext() + public function testWithHostDifferentFromContext() { $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)->generate('test', array('name' =>'Fabien', 'locale' => 'fr'))); + $this->assertEquals('//fr.example.com/app.php/Fabien', $this->getGenerator($routes)->generate('test', array('name' =>'Fabien', 'locale' => 'fr'))); } - public function testWithHostnameSameAsContext() + 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 testWithHostnameSameAsContextAndAbsolute() + public function testWithHostSameAsContextAndAbsolute() { $routes = $this->getRoutes('test', new Route('/{name}', array(), array(), array(), '{locale}.example.com')); @@ -406,33 +406,33 @@ public function testWithHostnameSameAsContextAndAbsolute() } /** - * @expectedException Symfony\Component\Routing\Exception\InvalidParameterException + * @expectedException \Symfony\Component\Routing\Exception\InvalidParameterException */ - public function testUrlWithInvalidParameterInHostname() + 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'), false); } /** - * @expectedException Symfony\Component\Routing\Exception\InvalidParameterException + * @expectedException \Symfony\Component\Routing\Exception\InvalidParameterException */ - public function testUrlWithInvalidParameterInHostnameWhenParamHasADefaultValue() + 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'), false); } /** - * @expectedException Symfony\Component\Routing\Exception\InvalidParameterException + * @expectedException \Symfony\Component\Routing\Exception\InvalidParameterException */ - public function testUrlWithInvalidParameterEqualsDefaultValueInHostname() + 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'), false); } - public function testUrlWithInvalidParameterInHostnameInNonStrictMode() + public function testUrlWithInvalidParameterInHostInNonStrictMode() { $routes = $this->getRoutes('test', new Route('/', array(), array('foo' => 'bar'), array(), '{foo}.example.com')); $generator = $this->getGenerator($routes); @@ -440,6 +440,172 @@ public function testUrlWithInvalidParameterInHostnameInNonStrictMode() $this->assertNull($generator->generate('test', array('foo' => 'baz'), false)); } + public function testGenerateNetworkPath() + { + $routes = $this->getRoutes('test', new Route('/{name}', array(), array('_scheme' => 'http'), array(), '{locale}.example.com')); + + $this->assertSame('//fr.example.com/app.php/Fabien', $this->getGenerator($routes)->generate('test', + array('name' =>'Fabien', 'locale' => 'fr'), UrlGeneratorInterface::NETWORK_PATH), 'network path with different host' + ); + $this->assertSame('//fr.example.com/app.php/Fabien?query=string', $this->getGenerator($routes, array('host' => 'fr.example.com'))->generate('test', + array('name' =>'Fabien', 'locale' => 'fr', 'query' => 'string'), UrlGeneratorInterface::NETWORK_PATH), 'network path although host same as context' + ); + $this->assertSame('http://fr.example.com/app.php/Fabien', $this->getGenerator($routes, array('scheme' => 'https'))->generate('test', + array('name' =>'Fabien', 'locale' => 'fr'), UrlGeneratorInterface::NETWORK_PATH), 'absolute URL because scheme requirement does not match context' + ); + $this->assertSame('http://fr.example.com/app.php/Fabien', $this->getGenerator($routes)->generate('test', + array('name' =>'Fabien', 'locale' => 'fr'), UrlGeneratorInterface::ABSOLUTE_URL), 'absolute URL with same scheme because it is requested' + ); + } + + public function testGenerateRelativePath() + { + $routes = new RouteCollection(); + $routes->add('article', new Route('/{author}/{article}/')); + $routes->add('comments', new Route('/{author}/{article}/comments')); + $routes->add('host', new Route('/{article}', array(), array(), array(), '{author}.example.com')); + $routes->add('scheme', new Route('/{author}', array(), array('_scheme' => 'https'))); + $routes->add('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', $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/' + ), + ); + } + protected function getGenerator(RouteCollection $routes, array $parameters = array(), $logger = null) { $context = new RequestContext('/app.php'); diff --git a/core/vendor/symfony/routing/Symfony/Component/Routing/Tests/Loader/AnnotationClassLoaderTest.php b/core/vendor/symfony/routing/Symfony/Component/Routing/Tests/Loader/AnnotationClassLoaderTest.php index 9f5597541b4b..31c43f58c69b 100644 --- a/core/vendor/symfony/routing/Symfony/Component/Routing/Tests/Loader/AnnotationClassLoaderTest.php +++ b/core/vendor/symfony/routing/Symfony/Component/Routing/Tests/Loader/AnnotationClassLoaderTest.php @@ -89,10 +89,12 @@ public function testLoad($className, $routeDatas = array(), $methodArgs = array( { $routeDatas = array_replace(array( 'name' => 'route', - 'pattern' => '/', + 'path' => '/', 'requirements' => array(), 'options' => array(), 'defaults' => array(), + 'schemes' => array(), + 'methods' => array(), ), $routeDatas); $this->reader @@ -103,7 +105,7 @@ public function testLoad($className, $routeDatas = array(), $methodArgs = array( $routeCollection = $this->loader->load($className); $route = $routeCollection->get($routeDatas['name']); - $this->assertSame($routeDatas['pattern'], $route->getPattern(), '->load preserves pattern annotation'); + $this->assertSame($routeDatas['path'], $route->getPath(), '->load preserves path annotation'); $this->assertSame($routeDatas['requirements'],$route->getRequirements(), '->load preserves requirements annotation'); $this->assertCount(0, array_intersect($route->getOptions(), $routeDatas['options']), '->load preserves options annotation'); $this->assertSame(array_replace($routeDatas['defaults'], $methodArgs), $route->getDefaults(), '->load preserves defaults annotation'); diff --git a/core/vendor/symfony/routing/Symfony/Component/Routing/Tests/Loader/PhpFileLoaderTest.php b/core/vendor/symfony/routing/Symfony/Component/Routing/Tests/Loader/PhpFileLoaderTest.php index 3ff425d98139..6cb24568527b 100644 --- a/core/vendor/symfony/routing/Symfony/Component/Routing/Tests/Loader/PhpFileLoaderTest.php +++ b/core/vendor/symfony/routing/Symfony/Component/Routing/Tests/Loader/PhpFileLoaderTest.php @@ -43,10 +43,10 @@ public function testLoadWithRoute() $this->assertEquals(1, count($routes), 'One route is loaded'); $this->assertContainsOnly('Symfony\Component\Routing\Route', $routes); $route = $routes['blog_show']; - $this->assertEquals('/blog/{slug}', $route->getPattern()); + $this->assertEquals('/blog/{slug}', $route->getPath()); $this->assertEquals('MyBlogBundle:Blog:show', $route->getDefault('_controller')); $this->assertEquals('GET', $route->getRequirement('_method')); - $this->assertEquals('{locale}.example.com', $route->getHostnamePattern()); + $this->assertEquals('{locale}.example.com', $route->getHost()); $this->assertEquals('RouteCompiler', $route->getOption('compiler_class')); } } diff --git a/core/vendor/symfony/routing/Symfony/Component/Routing/Tests/Loader/XmlFileLoaderTest.php b/core/vendor/symfony/routing/Symfony/Component/Routing/Tests/Loader/XmlFileLoaderTest.php index 17e33ef29720..e40468247d07 100644 --- a/core/vendor/symfony/routing/Symfony/Component/Routing/Tests/Loader/XmlFileLoaderTest.php +++ b/core/vendor/symfony/routing/Symfony/Component/Routing/Tests/Loader/XmlFileLoaderTest.php @@ -44,11 +44,11 @@ public function testLoadWithRoute() $this->assertEquals(1, count($routes), 'One route is loaded'); $this->assertContainsOnly('Symfony\Component\Routing\Route', $routes); $route = $routes['blog_show']; - $this->assertEquals('/blog/{slug}', $route->getPattern()); + $this->assertEquals('/blog/{slug}', $route->getPath()); $this->assertEquals('MyBundle:Blog:show', $route->getDefault('_controller')); $this->assertEquals('GET', $route->getRequirement('_method')); $this->assertEquals('\w+', $route->getRequirement('locale')); - $this->assertEquals('{locale}.example.com', $route->getHostnamePattern()); + $this->assertEquals('{locale}.example.com', $route->getHost()); $this->assertEquals('RouteCompiler', $route->getOption('compiler_class')); } @@ -59,11 +59,11 @@ public function testLoadWithNamespacePrefix() $this->assertCount(1, $routeCollection, 'One route is loaded'); $route = $routeCollection->get('blog_show'); - $this->assertEquals('/blog/{slug}', $route->getPattern()); + $this->assertEquals('/blog/{slug}', $route->getPath()); $this->assertEquals('MyBundle:Blog:show', $route->getDefault('_controller')); $this->assertEquals('\w+', $route->getRequirement('slug')); $this->assertEquals('en|fr|de', $route->getRequirement('_locale')); - $this->assertEquals('{_locale}.example.com', $route->getHostnamePattern()); + $this->assertEquals('{_locale}.example.com', $route->getHost()); $this->assertEquals('RouteCompiler', $route->getOption('compiler_class')); } @@ -75,12 +75,12 @@ public function testLoadWithImport() $this->assertEquals(1, count($routes), 'One route is loaded'); $this->assertContainsOnly('Symfony\Component\Routing\Route', $routes); - $this->assertEquals('/{foo}/blog/{slug}', $routes['blog_show']->getPattern()); + $this->assertEquals('/{foo}/blog/{slug}', $routes['blog_show']->getPath()); $this->assertEquals('MyBundle:Blog:show', $routes['blog_show']->getDefault('_controller')); $this->assertEquals('123', $routes['blog_show']->getDefault('foo')); $this->assertEquals('\d+', $routes['blog_show']->getRequirement('foo')); $this->assertEquals('bar', $routes['blog_show']->getOption('foo')); - $this->assertEquals('{locale}.example.com', $routes['blog_show']->getHostnamePattern()); + $this->assertEquals('{locale}.example.com', $routes['blog_show']->getHost()); } /** diff --git a/core/vendor/symfony/routing/Symfony/Component/Routing/Tests/Loader/YamlFileLoaderTest.php b/core/vendor/symfony/routing/Symfony/Component/Routing/Tests/Loader/YamlFileLoaderTest.php index f99e789486ad..bb055de4e732 100644 --- a/core/vendor/symfony/routing/Symfony/Component/Routing/Tests/Loader/YamlFileLoaderTest.php +++ b/core/vendor/symfony/routing/Symfony/Component/Routing/Tests/Loader/YamlFileLoaderTest.php @@ -70,7 +70,7 @@ public function testLoadSpecialRouteName() $route = $routeCollection->get('#$péß^a|'); $this->assertInstanceOf('Symfony\Component\Routing\Route', $route); - $this->assertSame('/true', $route->getPattern()); + $this->assertSame('/true', $route->getPath()); } public function testLoadWithPattern() @@ -82,11 +82,11 @@ public function testLoadWithPattern() $this->assertEquals(1, count($routes), 'One route is loaded'); $this->assertContainsOnly('Symfony\Component\Routing\Route', $routes); $route = $routes['blog_show']; - $this->assertEquals('/blog/{slug}', $route->getPattern()); + $this->assertEquals('/blog/{slug}', $route->getPath()); $this->assertEquals('MyBlogBundle:Blog:show', $route->getDefault('_controller')); $this->assertEquals('GET', $route->getRequirement('_method')); $this->assertEquals('\w+', $route->getRequirement('locale')); - $this->assertEquals('{locale}.example.com', $route->getHostnamePattern()); + $this->assertEquals('{locale}.example.com', $route->getHost()); $this->assertEquals('RouteCompiler', $route->getOption('compiler_class')); } @@ -98,11 +98,11 @@ public function testLoadWithResource() $this->assertEquals(1, count($routes), 'One route is loaded'); $this->assertContainsOnly('Symfony\Component\Routing\Route', $routes); - $this->assertEquals('/{foo}/blog/{slug}', $routes['blog_show']->getPattern()); + $this->assertEquals('/{foo}/blog/{slug}', $routes['blog_show']->getPath()); $this->assertEquals('MyBlogBundle:Blog:show', $routes['blog_show']->getDefault('_controller')); $this->assertEquals('123', $routes['blog_show']->getDefault('foo')); $this->assertEquals('\d+', $routes['blog_show']->getRequirement('foo')); $this->assertEquals('bar', $routes['blog_show']->getOption('foo')); - $this->assertEquals('{locale}.example.com', $routes['blog_show']->getHostnamePattern()); + $this->assertEquals('{locale}.example.com', $routes['blog_show']->getHost()); } } diff --git a/core/vendor/symfony/routing/Symfony/Component/Routing/Tests/Matcher/Dumper/ApacheMatcherDumperTest.php b/core/vendor/symfony/routing/Symfony/Component/Routing/Tests/Matcher/Dumper/ApacheMatcherDumperTest.php index e72976f047ab..da72d6b3a91f 100644 --- a/core/vendor/symfony/routing/Symfony/Component/Routing/Tests/Matcher/Dumper/ApacheMatcherDumperTest.php +++ b/core/vendor/symfony/routing/Symfony/Component/Routing/Tests/Matcher/Dumper/ApacheMatcherDumperTest.php @@ -163,7 +163,7 @@ private function getRouteCollection() $collection->addCollection($collection1); - // hostname and variables + // host and variables $collection1 = new RouteCollection(); diff --git a/core/vendor/symfony/routing/Symfony/Component/Routing/Tests/Matcher/Dumper/DumperPrefixCollectionTest.php b/core/vendor/symfony/routing/Symfony/Component/Routing/Tests/Matcher/Dumper/DumperPrefixCollectionTest.php index 9ba140bf8c7d..398798a7d28a 100644 --- a/core/vendor/symfony/routing/Symfony/Component/Routing/Tests/Matcher/Dumper/DumperPrefixCollectionTest.php +++ b/core/vendor/symfony/routing/Symfony/Component/Routing/Tests/Matcher/Dumper/DumperPrefixCollectionTest.php @@ -105,7 +105,7 @@ private function collectionToString(DumperCollection $collection, $prefix) $string .= sprintf("%s|-coll %s\n", $prefix, $route->getPrefix()); $string .= $this->collectionToString($route, $prefix.'| '); } else { - $string .= sprintf("%s|-route %s %s\n", $prefix, $route->getName(), $route->getRoute()->getPattern()); + $string .= sprintf("%s|-route %s %s\n", $prefix, $route->getName(), $route->getRoute()->getPath()); } } diff --git a/core/vendor/symfony/routing/Symfony/Component/Routing/Tests/Matcher/Dumper/PhpMatcherDumperTest.php b/core/vendor/symfony/routing/Symfony/Component/Routing/Tests/Matcher/Dumper/PhpMatcherDumperTest.php index e04310cc9a70..4764df617da4 100644 --- a/core/vendor/symfony/routing/Symfony/Component/Routing/Tests/Matcher/Dumper/PhpMatcherDumperTest.php +++ b/core/vendor/symfony/routing/Symfony/Component/Routing/Tests/Matcher/Dumper/PhpMatcherDumperTest.php @@ -155,7 +155,7 @@ public function getRouteCollections() $collection1->add('foo4', new Route('/{foo}')); $collection->addCollection($collection1, '/aba'); - // prefix and hostname + // prefix and host $collection1 = new RouteCollection(); @@ -181,7 +181,7 @@ public function getRouteCollections() $collection->addCollection($collection1); - // hostname and variables + // host and variables $collection1 = new RouteCollection(); diff --git a/core/vendor/symfony/routing/Symfony/Component/Routing/Tests/Matcher/RedirectableUrlMatcherTest.php b/core/vendor/symfony/routing/Symfony/Component/Routing/Tests/Matcher/RedirectableUrlMatcherTest.php index b8ab2647ffd0..2ad4fc8725a8 100644 --- a/core/vendor/symfony/routing/Symfony/Component/Routing/Tests/Matcher/RedirectableUrlMatcherTest.php +++ b/core/vendor/symfony/routing/Symfony/Component/Routing/Tests/Matcher/RedirectableUrlMatcherTest.php @@ -28,7 +28,7 @@ public function testRedirectWhenNoSlash() } /** - * @expectedException Symfony\Component\Routing\Exception\ResourceNotFoundException + * @expectedException \Symfony\Component\Routing\Exception\ResourceNotFoundException */ public function testRedirectWhenNoSlashForNonSafeMethod() { diff --git a/core/vendor/symfony/routing/Symfony/Component/Routing/Tests/Matcher/UrlMatcherTest.php b/core/vendor/symfony/routing/Symfony/Component/Routing/Tests/Matcher/UrlMatcherTest.php index 18e11ebcfb6d..fee6fe2b6f8a 100644 --- a/core/vendor/symfony/routing/Symfony/Component/Routing/Tests/Matcher/UrlMatcherTest.php +++ b/core/vendor/symfony/routing/Symfony/Component/Routing/Tests/Matcher/UrlMatcherTest.php @@ -295,7 +295,7 @@ public function testDefaultRequirementOfVariable() } /** - * @expectedException Symfony\Component\Routing\Exception\ResourceNotFoundException + * @expectedException \Symfony\Component\Routing\Exception\ResourceNotFoundException */ public function testDefaultRequirementOfVariableDisallowsSlash() { @@ -307,7 +307,7 @@ public function testDefaultRequirementOfVariableDisallowsSlash() } /** - * @expectedException Symfony\Component\Routing\Exception\ResourceNotFoundException + * @expectedException \Symfony\Component\Routing\Exception\ResourceNotFoundException */ public function testDefaultRequirementOfVariableDisallowsNextSeparator() { @@ -319,7 +319,7 @@ public function testDefaultRequirementOfVariableDisallowsNextSeparator() } /** - * @expectedException Symfony\Component\Routing\Exception\ResourceNotFoundException + * @expectedException \Symfony\Component\Routing\Exception\ResourceNotFoundException */ public function testSchemeRequirement() { @@ -354,7 +354,7 @@ public function testCannotRelyOnPrefix() $this->assertEquals(array('_route' => 'bar'), $matcher->match('/new')); } - public function testWithHostname() + public function testWithHost() { $coll = new RouteCollection(); $coll->add('foo', new Route('/foo/{foo}', array(), array(), array(), '{locale}.example.com')); @@ -363,12 +363,12 @@ public function testWithHostname() $this->assertEquals(array('foo' => 'bar', '_route' => 'foo', 'locale' => 'en'), $matcher->match('/foo/bar')); } - public function testWithHostnameOnRouteCollection() + 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->setHostnamePattern('{locale}.example.com'); + $coll->setHost('{locale}.example.com'); $matcher = new UrlMatcher($coll, new RequestContext('', 'GET', 'en.example.com')); $this->assertEquals(array('foo' => 'bar', '_route' => 'foo', 'locale' => 'en'), $matcher->match('/foo/bar')); @@ -378,9 +378,9 @@ public function testWithHostnameOnRouteCollection() } /** - * @expectedException Symfony\Component\Routing\Exception\ResourceNotFoundException + * @expectedException \Symfony\Component\Routing\Exception\ResourceNotFoundException */ - public function testWithOutHostnameHostnameDoesNotMatch() + public function testWithOutHostHostDoesNotMatch() { $coll = new RouteCollection(); $coll->add('foo', new Route('/foo/{foo}', array(), array(), array(), '{locale}.example.com')); diff --git a/core/vendor/symfony/routing/Symfony/Component/Routing/Tests/RouteCollectionTest.php b/core/vendor/symfony/routing/Symfony/Component/Routing/Tests/RouteCollectionTest.php index de1d9b1f39c8..65f9967e6a1a 100644 --- a/core/vendor/symfony/routing/Symfony/Component/Routing/Tests/RouteCollectionTest.php +++ b/core/vendor/symfony/routing/Symfony/Component/Routing/Tests/RouteCollectionTest.php @@ -33,7 +33,7 @@ public function testOverriddenRoute() $collection->add('foo', new Route('/foo')); $collection->add('foo', new Route('/foo1')); - $this->assertEquals('/foo1', $collection->get('foo')->getPattern()); + $this->assertEquals('/foo1', $collection->get('foo')->getPath()); } public function testDeepOverriddenRoute() @@ -50,8 +50,8 @@ public function testDeepOverriddenRoute() $collection1->addCollection($collection2); $collection->addCollection($collection1); - $this->assertEquals('/foo2', $collection1->get('foo')->getPattern()); - $this->assertEquals('/foo2', $collection->get('foo')->getPattern()); + $this->assertEquals('/foo2', $collection1->get('foo')->getPath()); + $this->assertEquals('/foo2', $collection->get('foo')->getPath()); } public function testIteratorWithOverriddenRoutes() @@ -63,7 +63,7 @@ public function testIteratorWithOverriddenRoutes() $collection1->add('foo', new Route('/foo1')); $collection->addCollection($collection1); - $this->assertEquals('/foo1', $this->getFirstNamedRoute($collection, 'foo')->getPattern()); + $this->assertEquals('/foo1', $this->getFirstNamedRoute($collection, 'foo')->getPath()); } public function testCount() @@ -110,7 +110,7 @@ public function testAddCollection() $collection1 = new RouteCollection(); $collection1->add('foo', $foo1 = new Route('/foo1')); $collection->addCollection($collection1, '/{foo}', array('foo' => 'foo'), array('foo' => '\d+'), array('foo' => 'bar')); - $this->assertEquals('/{foo}/foo1', $collection->get('foo')->getPattern(), '->addCollection() can add a prefix to all merged routes'); + $this->assertEquals('/{foo}/foo1', $collection->get('foo')->getPath(), '->addCollection() can add a prefix to all merged routes'); $this->assertEquals(array('foo' => 'foo'), $collection->get('foo')->getDefaults(), '->addCollection() can add a prefix to all merged routes'); $this->assertEquals(array('foo' => '\d+'), $collection->get('foo')->getRequirements(), '->addCollection() can add a prefix to all merged routes'); $this->assertEquals( @@ -137,8 +137,8 @@ public function testAddPrefix() $collection->addPrefix(' / '); $this->assertSame('', $collection->getPrefix(), '->addPrefix() trims the prefix and a single slash has no effect'); $collection->addPrefix('/{admin}', array('admin' => 'admin'), array('admin' => '\d+'), array('foo' => 'bar')); - $this->assertEquals('/{admin}/foo', $collection->get('foo')->getPattern(), '->addPrefix() adds a prefix to all routes'); - $this->assertEquals('/{admin}/bar', $collection->get('bar')->getPattern(), '->addPrefix() adds a prefix to all routes'); + $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'); @@ -155,8 +155,8 @@ public function testAddPrefix() $this->assertEquals('/0/{admin}', $collection->getPrefix(), '->addPrefix() ensures a prefix must start with a slash and must not end with a slash'); $collection->addPrefix('/ /'); $this->assertSame('/ /0/{admin}', $collection->getPrefix(), '->addPrefix() can handle spaces if desired'); - $this->assertSame('/ /0/{admin}/foo', $collection->get('foo')->getPattern(), 'the route pattern is in synch with the collection prefix'); - $this->assertSame('/ /0/{admin}/bar', $collection->get('bar')->getPattern(), 'the route pattern in a sub-collection is in synch with the collection prefix'); + $this->assertSame('/ /0/{admin}/foo', $collection->get('foo')->getPath(), 'the route path is in synch with the collection prefix'); + $this->assertSame('/ /0/{admin}/bar', $collection->get('bar')->getPath(), 'the route path in a sub-collection is in synch with the collection prefix'); } public function testAddPrefixOverridesDefaultsAndRequirements() @@ -224,7 +224,7 @@ public function testGet() $this->assertNull($collection1->get(0), '->get() does not disclose internal child RouteCollection'); } - public function testSetHostnamePattern() + public function testSetHost() { $collection = new RouteCollection(); $routea = new Route('/a'); @@ -232,9 +232,9 @@ public function testSetHostnamePattern() $collection->add('a', $routea); $collection->add('b', $routeb); - $collection->setHostnamePattern('{locale}.example.com'); + $collection->setHost('{locale}.example.com'); - $this->assertEquals('{locale}.example.com', $routea->getHostnamePattern()); - $this->assertEquals('{locale}.example.com', $routeb->getHostnamePattern()); + $this->assertEquals('{locale}.example.com', $routea->getHost()); + $this->assertEquals('{locale}.example.com', $routeb->getHost()); } } diff --git a/core/vendor/symfony/routing/Symfony/Component/Routing/Tests/RouteCompilerTest.php b/core/vendor/symfony/routing/Symfony/Component/Routing/Tests/RouteCompilerTest.php index 42d8976455f5..430cae7c7ccd 100644 --- a/core/vendor/symfony/routing/Symfony/Component/Routing/Tests/RouteCompilerTest.php +++ b/core/vendor/symfony/routing/Symfony/Component/Routing/Tests/RouteCompilerTest.php @@ -181,9 +181,9 @@ public function getNumericVariableNames() } /** - * @dataProvider provideCompileWithHostnameData + * @dataProvider provideCompileWithHostData */ - public function testCompileWithHostname($name, $arguments, $prefix, $regex, $variables, $pathVariables, $tokens, $hostnameRegex, $hostnameVariables, $hostnameTokens) + public function testCompileWithHost($name, $arguments, $prefix, $regex, $variables, $pathVariables, $tokens, $hostRegex, $hostVariables, $hostTokens) { $r = new \ReflectionClass('Symfony\\Component\\Routing\\Route'); $route = $r->newInstanceArgs($arguments); @@ -194,16 +194,16 @@ public function testCompileWithHostname($name, $arguments, $prefix, $regex, $var $this->assertEquals($variables, $compiled->getVariables(), $name.' (variables)'); $this->assertEquals($pathVariables, $compiled->getPathVariables(), $name.' (path variables)'); $this->assertEquals($tokens, $compiled->getTokens(), $name.' (tokens)'); - $this->assertEquals($hostnameRegex, str_replace(array("\n", ' '), '', $compiled->getHostnameRegex()), $name.' (hostname regex)'); - $this->assertEquals($hostnameVariables, $compiled->getHostnameVariables(), $name.' (hostname variables)'); - $this->assertEquals($hostnameTokens, $compiled->getHostnameTokens(), $name.' (hostname 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 provideCompileWithHostnameData() + public function provideCompileWithHostData() { return array( array( - 'Route with hostname pattern', + 'Route with host pattern', array('/hello', array(), array(), array(), 'www.example.com'), '/hello', '#^/hello$#s', array(), array(), array( array('text', '/hello'), @@ -213,7 +213,7 @@ public function provideCompileWithHostnameData() ), ), array( - 'Route with hostname pattern and some variables', + 'Route with host pattern and some variables', array('/hello/{name}', array(), array(), array(), 'www.example.{tld}'), '/hello', '#^/hello/(?P<name>[^/]++)$#s', array('tld', 'name'), array('name'), array( array('variable', '/', '[^/]++', 'name'), @@ -225,7 +225,7 @@ public function provideCompileWithHostnameData() ), ), array( - 'Route with variable at beginning of hostname', + 'Route with variable at beginning of host', array('/hello', array(), array(), array(), '{locale}.example.{tld}'), '/hello', '#^/hello$#s', array('locale', 'tld'), array(), array( array('text', '/hello'), @@ -237,7 +237,7 @@ public function provideCompileWithHostnameData() ), ), array( - 'Route with hostname variables that has a default value', + 'Route with host variables that has a default value', array('/hello', array('locale' => 'a', 'tld' => 'b'), array(), array(), '{locale}.example.{tld}'), '/hello', '#^/hello$#s', array('locale', 'tld'), array(), array( array('text', '/hello'), diff --git a/core/vendor/symfony/routing/Symfony/Component/Routing/Tests/RouteTest.php b/core/vendor/symfony/routing/Symfony/Component/Routing/Tests/RouteTest.php index c89ad5d830cb..31f1066feda1 100644 --- a/core/vendor/symfony/routing/Symfony/Component/Routing/Tests/RouteTest.php +++ b/core/vendor/symfony/routing/Symfony/Component/Routing/Tests/RouteTest.php @@ -18,25 +18,33 @@ class RouteTest extends \PHPUnit_Framework_TestCase public function testConstructor() { $route = new Route('/{foo}', array('foo' => 'bar'), array('foo' => '\d+'), array('foo' => 'bar'), '{locale}.example.com'); - $this->assertEquals('/{foo}', $route->getPattern(), '__construct() takes a pattern as its first argument'); + $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->getHostnamePattern(), '__construct() takes a hostname pattern as its fifth 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')); + $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'); + + $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 testPattern() + public function testPath() { $route = new Route('/{foo}'); - $route->setPattern('/{bar}'); - $this->assertEquals('/{bar}', $route->getPattern(), '->setPattern() sets the pattern'); - $route->setPattern(''); - $this->assertEquals('/', $route->getPattern(), '->setPattern() adds a / at the beginning of the pattern if needed'); - $route->setPattern('bar'); - $this->assertEquals('/bar', $route->getPattern(), '->setPattern() adds a / at the beginning of the pattern if needed'); - $this->assertEquals($route, $route->setPattern(''), '->setPattern() implements a fluent interface'); - $route->setPattern('//path'); - $this->assertEquals('/path', $route->getPattern(), '->setPattern() does not allow two slashes "//" at the beginning of the pattern as it would be confused with a network path when generating the path from the route'); + $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 slahes "//" 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() @@ -85,7 +93,7 @@ public function testRequirements() $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 pattern'); + $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+')); @@ -98,7 +106,7 @@ public function testRequirement() { $route = new Route('/{foo}'); $route->setRequirement('foo', '^\d+$'); - $this->assertEquals('\d+', $route->getRequirement('foo'), '->setRequirement() removes ^ and $ from the pattern'); + $this->assertEquals('\d+', $route->getRequirement('foo'), '->setRequirement() removes ^ and $ from the path'); } /** @@ -122,11 +130,55 @@ public function getInvalidRequirements() ); } - public function testHostnamePattern() + 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()'); + $route->setSchemes('hTTp'); + $this->assertEquals(array('http'), $route->getSchemes(), '->setSchemes() accepts a single scheme string and lowercases it'); + $route->setSchemes(array('HttpS', 'hTTp')); + $this->assertEquals(array('https', 'http'), $route->getSchemes(), '->setSchemes() accepts an array of schemes and lowercases them'); + } + + public function testSchemeIsBC() + { + $route = new Route('/'); + $route->setRequirement('_scheme', 'http|https'); + $this->assertEquals('http|https', $route->getRequirement('_scheme')); + $this->assertEquals(array('http', 'https'), $route->getSchemes()); + $route->setSchemes(array('hTTp')); + $this->assertEquals('http', $route->getRequirement('_scheme')); + $route->setSchemes(array()); + $this->assertNull($route->getRequirement('_scheme')); + } + + 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 testMethodIsBC() { $route = new Route('/'); - $route->setHostnamePattern('{locale}.example.net'); - $this->assertEquals('{locale}.example.net', $route->getHostnamePattern(), '->setHostnamePattern() sets the hostname pattern'); + $route->setRequirement('_method', 'GET|POST'); + $this->assertEquals('GET|POST', $route->getRequirement('_method')); + $this->assertEquals(array('GET', 'POST'), $route->getMethods()); + $route->setMethods(array('gEt')); + $this->assertEquals('GET', $route->getRequirement('_method')); + $route->setMethods(array()); + $this->assertNull($route->getRequirement('_method')); } public function testCompile() diff --git a/core/vendor/symfony/routing/Symfony/Component/Routing/composer.json b/core/vendor/symfony/routing/Symfony/Component/Routing/composer.json index d3f653b761c8..d29f645424d3 100644 --- a/core/vendor/symfony/routing/Symfony/Component/Routing/composer.json +++ b/core/vendor/symfony/routing/Symfony/Component/Routing/composer.json @@ -22,7 +22,8 @@ "symfony/config": "2.2.*", "symfony/yaml": "2.2.*", "symfony/http-kernel": "2.2.*", - "doctrine/common": ">=2.2,<2.4-dev" + "doctrine/common": ">=2.2,<2.4-dev", + "psr/log": "~1.0" }, "suggest": { "symfony/config": "2.2.*", diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/AllValidator.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/AllValidator.php index c38f19a6669c..622a90b041c4 100644 --- a/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/AllValidator.php +++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/AllValidator.php @@ -35,11 +35,13 @@ public function validate($value, Constraint $constraint) throw new UnexpectedTypeException($value, 'array or Traversable'); } + $walker = $this->context->getGraphWalker(); $group = $this->context->getGroup(); + $propertyPath = $this->context->getPropertyPath(); foreach ($value as $key => $element) { foreach ($constraint->constraints as $constr) { - $this->context->validateValue($element, $constr, '['.$key.']', $group); + $walker->walkConstraint($constr, $element, $group, $propertyPath.'['.$key.']'); } } } diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/CollectionValidator.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/CollectionValidator.php index 9249b705311b..13551f47fc52 100644 --- a/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/CollectionValidator.php +++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/CollectionValidator.php @@ -36,7 +36,9 @@ public function validate($value, Constraint $constraint) throw new UnexpectedTypeException($value, 'array or Traversable and ArrayAccess'); } + $walker = $this->context->getGraphWalker(); $group = $this->context->getGroup(); + $propertyPath = $this->context->getPropertyPath(); foreach ($constraint->fields as $field => $fieldConstraint) { if ( @@ -45,10 +47,10 @@ public function validate($value, Constraint $constraint) ($value instanceof \ArrayAccess && $value->offsetExists($field)) ) { foreach ($fieldConstraint->constraints as $constr) { - $this->context->validateValue($value[$field], $constr, '['.$field.']', $group); + $walker->walkConstraint($constr, $value[$field], $group, $propertyPath.'['.$field.']'); } } elseif (!$fieldConstraint instanceof Optional && !$constraint->allowMissingFields) { - $this->context->addViolationAt('['.$field.']', $constraint->missingFieldsMessage, array( + $this->context->addViolationAtSubPath('['.$field.']', $constraint->missingFieldsMessage, array( '{{ field }}' => $field ), null); } @@ -57,7 +59,7 @@ public function validate($value, Constraint $constraint) if (!$constraint->allowExtraFields) { foreach ($value as $field => $fieldValue) { if (!isset($constraint->fields[$field])) { - $this->context->addViolationAt('['.$field.']', $constraint->extraFieldsMessage, array( + $this->context->addViolationAtSubPath('['.$field.']', $constraint->extraFieldsMessage, array( '{{ field }}' => $field ), $fieldValue); } diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Mapping/ClassMetadata.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Mapping/ClassMetadata.php index 8ce479b3dd32..4fa272327088 100644 --- a/core/vendor/symfony/validator/Symfony/Component/Validator/Mapping/ClassMetadata.php +++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Mapping/ClassMetadata.php @@ -111,7 +111,7 @@ public function accept(ValidationVisitorInterface $visitor, $value, $group, $pro foreach ($this->getConstrainedProperties() as $property) { foreach ($this->getMemberMetadatas($property) as $member) { - $member->accept($visitor, $member->getPropertyValue($value), $group, $pathPrefix.$property, $propagatedGroup); + $member->accept($visitor, $member->getValue($value), $group, $pathPrefix.$property, $propagatedGroup); } } } diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/AllValidatorTest.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/AllValidatorTest.php index eaa9044e9ef5..86d8573dddf6 100644 --- a/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/AllValidatorTest.php +++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/AllValidatorTest.php @@ -12,39 +12,59 @@ namespace Symfony\Component\Validator\Tests\Constraints; use Symfony\Component\Validator\ExecutionContext; -use Symfony\Component\Validator\Constraints\Range; -use Symfony\Component\Validator\Constraints\NotNull; +use Symfony\Component\Validator\Constraints\Min; +use Symfony\Component\Validator\Constraints\Max; use Symfony\Component\Validator\Constraints\All; use Symfony\Component\Validator\Constraints\AllValidator; class AllValidatorTest extends \PHPUnit_Framework_TestCase { + protected $walker; protected $context; protected $validator; protected function setUp() { + $this->walker = $this->getMock('Symfony\Component\Validator\GraphWalker', array(), array(), '', false); $this->context = $this->getMock('Symfony\Component\Validator\ExecutionContext', array(), array(), '', false); $this->validator = new AllValidator(); $this->validator->initialize($this->context); + $this->context->expects($this->any()) + ->method('getGraphWalker') + ->will($this->returnValue($this->walker)); $this->context->expects($this->any()) ->method('getGroup') ->will($this->returnValue('MyGroup')); + $this->context->expects($this->any()) + ->method('getPropertyPath') + ->will($this->returnValue('foo.bar')); } protected function tearDown() { $this->validator = null; + $this->walker = null; $this->context = null; } + public function deprecationErrorHandler($errorNumber, $message, $file, $line, $context) + { + if ($errorNumber & E_USER_DEPRECATED) { + return true; + } + + return \PHPUnit_Util_ErrorHandler::handleError($errorNumber, $message, $file, $line); + } + public function testNullIsValid() { $this->context->expects($this->never()) ->method('addViolation'); - $this->validator->validate(null, new All(new Range(array('min' => 4)))); + set_error_handler(array($this, "deprecationErrorHandler")); + $this->validator->validate(null, new All(new Min(4))); + restore_error_handler(); } /** @@ -52,7 +72,9 @@ public function testNullIsValid() */ public function testThrowsExceptionIfNotTraversable() { - $this->validator->validate('foo.barbar', new All(new Range(array('min' => 4)))); + set_error_handler(array($this, "deprecationErrorHandler")); + $this->validator->validate('foo.barbar', new All(new Min(4))); + restore_error_handler(); } /** @@ -60,14 +82,16 @@ public function testThrowsExceptionIfNotTraversable() */ public function testWalkSingleConstraint($array) { - $constraint = new Range(array('min' => 4)); + set_error_handler(array($this, "deprecationErrorHandler")); + $constraint = new Min(4); + restore_error_handler(); - $i = 1; + $i = 0; foreach ($array as $key => $value) { - $this->context->expects($this->at($i++)) - ->method('validateValue') - ->with($value, $constraint, '['.$key.']', 'MyGroup'); + $this->walker->expects($this->at($i++)) + ->method('walkConstraint') + ->with($constraint, $value, 'MyGroup', 'foo.bar['.$key.']'); } $this->context->expects($this->never()) @@ -81,19 +105,21 @@ public function testWalkSingleConstraint($array) */ public function testWalkMultipleConstraints($array) { - $constraint1 = new Range(array('min' => 4)); - $constraint2 = new NotNull(); + set_error_handler(array($this, "deprecationErrorHandler")); + $constraint1 = new Min(4); + $constraint2 = new Max(6); + restore_error_handler(); $constraints = array($constraint1, $constraint2); - $i = 1; + $i = 0; foreach ($array as $key => $value) { - $this->context->expects($this->at($i++)) - ->method('validateValue') - ->with($value, $constraint1, '['.$key.']', 'MyGroup'); - $this->context->expects($this->at($i++)) - ->method('validateValue') - ->with($value, $constraint2, '['.$key.']', 'MyGroup'); + $this->walker->expects($this->at($i++)) + ->method('walkConstraint') + ->with($constraint1, $value, 'MyGroup', 'foo.bar['.$key.']'); + $this->walker->expects($this->at($i++)) + ->method('walkConstraint') + ->with($constraint2, $value, 'MyGroup', 'foo.bar['.$key.']'); } $this->context->expects($this->never()) diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/CollectionValidatorTest.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/CollectionValidatorTest.php index 2593ee91cd19..d01f83091564 100644 --- a/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/CollectionValidatorTest.php +++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/CollectionValidatorTest.php @@ -12,7 +12,7 @@ namespace Symfony\Component\Validator\Tests\Constraints; use Symfony\Component\Validator\ExecutionContext; -use Symfony\Component\Validator\Constraints\Range; +use Symfony\Component\Validator\Constraints\Min; use Symfony\Component\Validator\Constraints\NotNull; use Symfony\Component\Validator\Constraints\Collection\Required; use Symfony\Component\Validator\Constraints\Collection\Optional; @@ -21,48 +21,74 @@ abstract class CollectionValidatorTest extends \PHPUnit_Framework_TestCase { + protected $walker; protected $context; protected $validator; protected function setUp() { + $this->walker = $this->getMock('Symfony\Component\Validator\GraphWalker', array(), array(), '', false); $this->context = $this->getMock('Symfony\Component\Validator\ExecutionContext', array(), array(), '', false); $this->validator = new CollectionValidator(); $this->validator->initialize($this->context); + $this->context->expects($this->any()) + ->method('getGraphWalker') + ->will($this->returnValue($this->walker)); $this->context->expects($this->any()) ->method('getGroup') ->will($this->returnValue('MyGroup')); + $this->context->expects($this->any()) + ->method('getPropertyPath') + ->will($this->returnValue('foo.bar')); } protected function tearDown() { + $this->walker = null; $this->context = null; $this->validator = null; } + public function deprecationErrorHandler($errorNumber, $message, $file, $line, $context) + { + if ($errorNumber & E_USER_DEPRECATED) { + return true; + } + + return \PHPUnit_Util_ErrorHandler::handleError($errorNumber, $message, $file, $line); + } + abstract protected function prepareTestData(array $contents); public function testNullIsValid() { + set_error_handler(array($this, "deprecationErrorHandler")); + $this->context->expects($this->never()) - ->method('addViolationAt'); + ->method('addViolationAtSubPath'); $this->validator->validate(null, new Collection(array('fields' => array( - 'foo' => new Range(array('min' => 4)), + 'foo' => new Min(4), )))); + + restore_error_handler(); } public function testFieldsAsDefaultOption() { + set_error_handler(array($this, "deprecationErrorHandler")); + $data = $this->prepareTestData(array('foo' => 'foobar')); $this->context->expects($this->never()) - ->method('addViolationAt'); + ->method('addViolationAtSubPath'); $this->validator->validate($data, new Collection(array( - 'foo' => new Range(array('min' => 4)), + 'foo' => new Min(4), ))); + + restore_error_handler(); } /** @@ -70,31 +96,37 @@ public function testFieldsAsDefaultOption() */ public function testThrowsExceptionIfNotTraversable() { + set_error_handler(array($this, "deprecationErrorHandler")); + $this->validator->validate('foobar', new Collection(array('fields' => array( - 'foo' => new Range(array('min' => 4)), + 'foo' => new Min(4), )))); + + restore_error_handler(); } public function testWalkSingleConstraint() { - $constraint = new Range(array('min' => 4)); + set_error_handler(array($this, "deprecationErrorHandler")); + $constraint = new Min(4); + restore_error_handler(); $array = array( 'foo' => 3, 'bar' => 5, ); - $i = 1; + $i = 0; foreach ($array as $key => $value) { - $this->context->expects($this->at($i++)) - ->method('validateValue') - ->with($value, $constraint, '['.$key.']', 'MyGroup'); + $this->walker->expects($this->at($i++)) + ->method('walkConstraint') + ->with($constraint, $value, 'MyGroup', 'foo.bar['.$key.']'); } $data = $this->prepareTestData($array); $this->context->expects($this->never()) - ->method('addViolationAt'); + ->method('addViolationAtSubPath'); $this->validator->validate($data, new Collection(array( 'fields' => array( @@ -106,29 +138,31 @@ public function testWalkSingleConstraint() public function testWalkMultipleConstraints() { + set_error_handler(array($this, "deprecationErrorHandler")); $constraints = array( - new Range(array('min' => 4)), + new Min(4), new NotNull(), ); + restore_error_handler(); $array = array( 'foo' => 3, 'bar' => 5, ); - $i = 1; + $i = 0; foreach ($array as $key => $value) { foreach ($constraints as $constraint) { - $this->context->expects($this->at($i++)) - ->method('validateValue') - ->with($value, $constraint, '['.$key.']', 'MyGroup'); + $this->walker->expects($this->at($i++)) + ->method('walkConstraint') + ->with($constraint, $value, 'MyGroup', 'foo.bar['.$key.']'); } } $data = $this->prepareTestData($array); $this->context->expects($this->never()) - ->method('addViolationAt'); + ->method('addViolationAtSubPath'); $this->validator->validate($data, new Collection(array( 'fields' => array( @@ -140,46 +174,56 @@ public function testWalkMultipleConstraints() public function testExtraFieldsDisallowed() { + set_error_handler(array($this, "deprecationErrorHandler")); + $data = $this->prepareTestData(array( 'foo' => 5, 'baz' => 6, )); $this->context->expects($this->once()) - ->method('addViolationAt') + ->method('addViolationAtSubPath') ->with('[baz]', 'myMessage', array( '{{ field }}' => 'baz' )); $this->validator->validate($data, new Collection(array( 'fields' => array( - 'foo' => new Range(array('min' => 4)), + 'foo' => new Min(4), ), 'extraFieldsMessage' => 'myMessage', ))); + + restore_error_handler(); } // bug fix public function testNullNotConsideredExtraField() { + set_error_handler(array($this, "deprecationErrorHandler")); + $data = $this->prepareTestData(array( 'foo' => null, )); $constraint = new Collection(array( 'fields' => array( - 'foo' => new Range(array('min' => 4)), + 'foo' => new Min(4), ), )); $this->context->expects($this->never()) - ->method('addViolationAt'); + ->method('addViolationAtSubPath'); $this->validator->validate($data, $constraint); + + restore_error_handler(); } public function testExtraFieldsAllowed() { + set_error_handler(array($this, "deprecationErrorHandler")); + $data = $this->prepareTestData(array( 'foo' => 5, 'bar' => 6, @@ -187,52 +231,62 @@ public function testExtraFieldsAllowed() $constraint = new Collection(array( 'fields' => array( - 'foo' => new Range(array('min' => 4)), + 'foo' => new Min(4), ), 'allowExtraFields' => true, )); $this->context->expects($this->never()) - ->method('addViolationAt'); + ->method('addViolationAtSubPath'); $this->validator->validate($data, $constraint); + + restore_error_handler(); } public function testMissingFieldsDisallowed() { + set_error_handler(array($this, "deprecationErrorHandler")); + $data = $this->prepareTestData(array()); $constraint = new Collection(array( 'fields' => array( - 'foo' => new Range(array('min' => 4)), + 'foo' => new Min(4), ), 'missingFieldsMessage' => 'myMessage', )); $this->context->expects($this->once()) - ->method('addViolationAt') + ->method('addViolationAtSubPath') ->with('[foo]', 'myMessage', array( '{{ field }}' => 'foo', )); $this->validator->validate($data, $constraint); + + restore_error_handler(); } public function testMissingFieldsAllowed() { + set_error_handler(array($this, "deprecationErrorHandler")); + $data = $this->prepareTestData(array()); $constraint = new Collection(array( 'fields' => array( - 'foo' => new Range(array('min' => 4)), + 'foo' => new Min(4), ), 'allowMissingFields' => true, )); $this->context->expects($this->never()) - ->method('addViolationAt'); + ->method('addViolationAtSubPath'); $this->validator->validate($data, $constraint); + + restore_error_handler(); } public function testOptionalFieldPresent() @@ -242,7 +296,7 @@ public function testOptionalFieldPresent() )); $this->context->expects($this->never()) - ->method('addViolationAt'); + ->method('addViolationAtSubPath'); $this->validator->validate($data, new Collection(array( 'foo' => new Optional(), @@ -254,7 +308,7 @@ public function testOptionalFieldNotPresent() $data = $this->prepareTestData(array()); $this->context->expects($this->never()) - ->method('addViolationAt'); + ->method('addViolationAtSubPath'); $this->validator->validate($data, new Collection(array( 'foo' => new Optional(), @@ -263,52 +317,59 @@ public function testOptionalFieldNotPresent() public function testOptionalFieldSingleConstraint() { + set_error_handler(array($this, "deprecationErrorHandler")); + $array = array( 'foo' => 5, ); - $constraint = new Range(array('min' => 4)); + $constraint = new Min(4); - $this->context->expects($this->once()) - ->method('validateValue') - ->with($array['foo'], $constraint, '[foo]', 'MyGroup'); + $this->walker->expects($this->once()) + ->method('walkConstraint') + ->with($constraint, $array['foo'], 'MyGroup', 'foo.bar[foo]'); $this->context->expects($this->never()) - ->method('addViolationAt'); + ->method('addViolationAtSubPath'); $data = $this->prepareTestData($array); $this->validator->validate($data, new Collection(array( 'foo' => new Optional($constraint), ))); + + restore_error_handler(); } public function testOptionalFieldMultipleConstraints() { + set_error_handler(array($this, "deprecationErrorHandler")); + $array = array( 'foo' => 5, ); $constraints = array( new NotNull(), - new Range(array('min' => 4)), + new Min(4), ); - $i = 1; - foreach ($constraints as $constraint) { - $this->context->expects($this->at($i++)) - ->method('validateValue') - ->with($array['foo'], $constraint, '[foo]', 'MyGroup'); + foreach ($constraints as $i => $constraint) { + $this->walker->expects($this->at($i)) + ->method('walkConstraint') + ->with($constraint, $array['foo'], 'MyGroup', 'foo.bar[foo]'); } $this->context->expects($this->never()) - ->method('addViolationAt'); + ->method('addViolationAtSubPath'); $data = $this->prepareTestData($array); $this->validator->validate($data, new Collection(array( 'foo' => new Optional($constraints), ))); + + restore_error_handler(); } public function testRequiredFieldPresent() @@ -318,7 +379,7 @@ public function testRequiredFieldPresent() )); $this->context->expects($this->never()) - ->method('addViolationAt'); + ->method('addViolationAtSubPath'); $this->validator->validate($data, new Collection(array( 'foo' => new Required(), @@ -330,83 +391,94 @@ public function testRequiredFieldNotPresent() $data = $this->prepareTestData(array()); $this->context->expects($this->once()) - ->method('addViolationAt') + ->method('addViolationAtSubPath') ->with('[foo]', 'myMessage', array( '{{ field }}' => 'foo', )); $this->validator->validate($data, new Collection(array( 'fields' => array( - 'foo' => new Required(), - ), + 'foo' => new Required(), + ), 'missingFieldsMessage' => 'myMessage', ))); } public function testRequiredFieldSingleConstraint() { + set_error_handler(array($this, "deprecationErrorHandler")); + $array = array( 'foo' => 5, ); - $constraint = new Range(array('min' => 4)); + $constraint = new Min(4); - $this->context->expects($this->once()) - ->method('validateValue') - ->with($array['foo'], $constraint, '[foo]', 'MyGroup'); + $this->walker->expects($this->once()) + ->method('walkConstraint') + ->with($constraint, $array['foo'], 'MyGroup', 'foo.bar[foo]'); $this->context->expects($this->never()) - ->method('addViolationAt'); + ->method('addViolationAtSubPath'); $data = $this->prepareTestData($array); $this->validator->validate($data, new Collection(array( 'foo' => new Required($constraint), ))); + + restore_error_handler(); } public function testRequiredFieldMultipleConstraints() { + set_error_handler(array($this, "deprecationErrorHandler")); + $array = array( 'foo' => 5, ); $constraints = array( new NotNull(), - new Range(array('min' => 4)), + new Min(4), ); - $i = 1; - foreach ($constraints as $constraint) { - $this->context->expects($this->at($i++)) - ->method('validateValue') - ->with($array['foo'], $constraint, '[foo]', 'MyGroup'); + foreach ($constraints as $i => $constraint) { + $this->walker->expects($this->at($i)) + ->method('walkConstraint') + ->with($constraint, $array['foo'], 'MyGroup', 'foo.bar[foo]'); } $this->context->expects($this->never()) - ->method('addViolationAt'); + ->method('addViolationAtSubPath'); $data = $this->prepareTestData($array); $this->validator->validate($array, new Collection(array( 'foo' => new Required($constraints), ))); + + restore_error_handler(); } public function testObjectShouldBeLeftUnchanged() { + set_error_handler(array($this, "deprecationErrorHandler")); + $value = new \ArrayObject(array( 'foo' => 3 )); $this->validator->validate($value, new Collection(array( 'fields' => array( - 'foo' => new Range(array('min' => 2)), + 'foo' => new Min(2), ) ))); $this->assertEquals(array( 'foo' => 3 ), (array) $value); + + restore_error_handler(); } } diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/MaxLengthValidatorTest.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/MaxLengthValidatorTest.php index 56f3d054acba..f62033190b18 100644 --- a/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/MaxLengthValidatorTest.php +++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/MaxLengthValidatorTest.php @@ -21,8 +21,6 @@ class MaxLengthValidatorTest extends \PHPUnit_Framework_TestCase protected function setUp() { - set_error_handler(array($this, "deprecationErrorHandler")); - $this->context = $this->getMock('Symfony\Component\Validator\ExecutionContext', array(), array(), '', false); $this->validator = new MaxLengthValidator(); $this->validator->initialize($this->context); @@ -30,21 +28,10 @@ protected function setUp() protected function tearDown() { - restore_error_handler(); - $this->context = null; $this->validator = null; } - public function deprecationErrorHandler($errorNumber, $message, $file, $line, $context) - { - if ($errorNumber & E_USER_DEPRECATED) { - return true; - } - - return \PHPUnit_Util_ErrorHandler::handleError($errorNumber, $message, $file, $line); - } - public function testNullIsValid() { $this->context->expects($this->never()) diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/MaxValidatorTest.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/MaxValidatorTest.php index 41c3a39e6118..3ee95eeb6910 100644 --- a/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/MaxValidatorTest.php +++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/MaxValidatorTest.php @@ -21,8 +21,6 @@ class MaxValidatorTest extends \PHPUnit_Framework_TestCase protected function setUp() { - set_error_handler(array($this, "deprecationErrorHandler")); - $this->context = $this->getMock('Symfony\Component\Validator\ExecutionContext', array(), array(), '', false); $this->validator = new MaxValidator(); $this->validator->initialize($this->context); @@ -30,21 +28,10 @@ protected function setUp() protected function tearDown() { - restore_error_handler(); - $this->context = null; $this->validator = null; } - public function deprecationErrorHandler($errorNumber, $message, $file, $line, $context) - { - if ($errorNumber & E_USER_DEPRECATED) { - return true; - } - - return \PHPUnit_Util_ErrorHandler::handleError($errorNumber, $message, $file, $line); - } - public function testNullIsValid() { $this->context->expects($this->never()) diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/MinLengthValidatorTest.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/MinLengthValidatorTest.php index 7975b2339777..3973291db3dd 100644 --- a/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/MinLengthValidatorTest.php +++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/MinLengthValidatorTest.php @@ -21,8 +21,6 @@ class MinLengthValidatorTest extends \PHPUnit_Framework_TestCase protected function setUp() { - set_error_handler(array($this, "deprecationErrorHandler")); - $this->context = $this->getMock('Symfony\Component\Validator\ExecutionContext', array(), array(), '', false); $this->validator = new MinLengthValidator(); $this->validator->initialize($this->context); @@ -30,21 +28,10 @@ protected function setUp() protected function tearDown() { - restore_error_handler(); - $this->context = null; $this->validator = null; } - public function deprecationErrorHandler($errorNumber, $message, $file, $line, $context) - { - if ($errorNumber & E_USER_DEPRECATED) { - return true; - } - - return \PHPUnit_Util_ErrorHandler::handleError($errorNumber, $message, $file, $line); - } - public function testNullIsValid() { $this->context->expects($this->never()) diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/MinValidatorTest.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/MinValidatorTest.php index 64c770afbbc0..f760190b2d53 100644 --- a/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/MinValidatorTest.php +++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/MinValidatorTest.php @@ -21,27 +21,11 @@ class MinValidatorTest extends \PHPUnit_Framework_TestCase protected function setUp() { - set_error_handler(array($this, "deprecationErrorHandler")); - $this->context = $this->getMock('Symfony\Component\Validator\ExecutionContext', array(), array(), '', false); $this->validator = new MinValidator(); $this->validator->initialize($this->context); } - protected function tearDown() - { - restore_error_handler(); - } - - public function deprecationErrorHandler($errorNumber, $message, $file, $line, $context) - { - if ($errorNumber & E_USER_DEPRECATED) { - return true; - } - - return \PHPUnit_Util_ErrorHandler::handleError($errorNumber, $message, $file, $line); - } - public function testNullIsValid() { $this->context->expects($this->never()) diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/ExecutionContextTest.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/ExecutionContextTest.php index 9283aa6776df..467bdaaed75a 100644 --- a/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/ExecutionContextTest.php +++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/ExecutionContextTest.php @@ -64,15 +64,6 @@ protected function tearDown() $this->context = null; } - public function deprecationErrorHandler($errorNumber, $message, $file, $line, $context) - { - if ($errorNumber & E_USER_DEPRECATED) { - return true; - } - - return \PHPUnit_Util_ErrorHandler::handleError($errorNumber, $message, $file, $line); - } - public function testInit() { $this->assertCount(0, $this->context->getViolations()); @@ -85,36 +76,30 @@ public function testInit() ->will($this->returnValue('GRAPHWALKER')); // BC - set_error_handler(array($this, "deprecationErrorHandler")); $this->assertNull($this->context->getCurrentClass()); $this->assertNull($this->context->getCurrentProperty()); $this->assertSame('GRAPHWALKER', $this->context->getGraphWalker()); $this->assertSame($this->metadataFactory, $this->context->getMetadataFactory()); - restore_error_handler(); } public function testInitWithClassMetadata() { // BC - set_error_handler(array($this, "deprecationErrorHandler")); $this->metadata = new ClassMetadata(__NAMESPACE__ . '\ExecutionContextTest_TestClass'); $this->context = new ExecutionContext($this->globalContext, $this->translator, self::TRANS_DOMAIN, $this->metadata, 'currentValue', 'Group', 'foo.bar'); $this->assertSame(__NAMESPACE__ . '\ExecutionContextTest_TestClass', $this->context->getCurrentClass()); $this->assertNull($this->context->getCurrentProperty()); - restore_error_handler(); } public function testInitWithPropertyMetadata() { // BC - set_error_handler(array($this, "deprecationErrorHandler")); $this->metadata = new PropertyMetadata(__NAMESPACE__ . '\ExecutionContextTest_TestClass', 'myProperty'); $this->context = new ExecutionContext($this->globalContext, $this->translator, self::TRANS_DOMAIN, $this->metadata, 'currentValue', 'Group', 'foo.bar'); $this->assertSame(__NAMESPACE__ . '\ExecutionContextTest_TestClass', $this->context->getCurrentClass()); $this->assertSame('myProperty', $this->context->getCurrentProperty()); - restore_error_handler(); } public function testClone() @@ -214,9 +199,7 @@ public function testAddViolationAtPath() ->will($this->returnValue('Translated error')); // override preconfigured property path - set_error_handler(array($this, "deprecationErrorHandler")); $this->context->addViolationAtPath('bar.baz', 'Error', array('foo' => 'bar'), 'invalid'); - restore_error_handler(); $this->assertEquals(new ConstraintViolationList(array( new ConstraintViolation( @@ -237,9 +220,7 @@ public function testAddViolationAtPathUsesPreconfiguredValueIfNotPassed() ->with('Error', array()) ->will($this->returnValue('Translated error')); - set_error_handler(array($this, "deprecationErrorHandler")); $this->context->addViolationAtPath('bar.baz', 'Error'); - restore_error_handler(); $this->assertEquals(new ConstraintViolationList(array( new ConstraintViolation( @@ -265,10 +246,8 @@ public function testAddViolationAtPathUsesPassedNullValue() ->will($this->returnValue('Translated choice error')); // passed null value should override preconfigured value "invalid" - set_error_handler(array($this, "deprecationErrorHandler")); $this->context->addViolationAtPath('bar.baz', 'Error', array('foo' => 'bar'), null); $this->context->addViolationAtPath('bar.baz', 'Choice error', array('foo' => 'bar'), null, 3); - restore_error_handler(); $this->assertEquals(new ConstraintViolationList(array( new ConstraintViolation( @@ -299,9 +278,7 @@ public function testAddViolationAt() ->will($this->returnValue('Translated error')); // override preconfigured property path - set_error_handler(array($this, "deprecationErrorHandler")); $this->context->addViolationAt('bam.baz', 'Error', array('foo' => 'bar'), 'invalid'); - restore_error_handler(); $this->assertEquals(new ConstraintViolationList(array( new ConstraintViolation( @@ -322,9 +299,7 @@ public function testAddViolationAtUsesPreconfiguredValueIfNotPassed() ->with('Error', array()) ->will($this->returnValue('Translated error')); - set_error_handler(array($this, "deprecationErrorHandler")); $this->context->addViolationAt('bam.baz', 'Error'); - restore_error_handler(); $this->assertEquals(new ConstraintViolationList(array( new ConstraintViolation( @@ -350,10 +325,8 @@ public function testAddViolationAtUsesPassedNullValue() ->will($this->returnValue('Translated choice error')); // passed null value should override preconfigured value "invalid" - set_error_handler(array($this, "deprecationErrorHandler")); $this->context->addViolationAt('bam.baz', 'Error', array('foo' => 'bar'), null); $this->context->addViolationAt('bam.baz', 'Choice error', array('foo' => 'bar'), null, 2); - restore_error_handler(); $this->assertEquals(new ConstraintViolationList(array( new ConstraintViolation( diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/Entity.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/Entity.php index 002b6ed1d4ad..15f73c5eca2b 100644 --- a/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/Entity.php +++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/Entity.php @@ -21,12 +21,12 @@ class Entity extends EntityParent implements EntityInterface { /** * @Assert\NotNull - * @Assert\Range(min=3) - * @Assert\All({@Assert\NotNull, @Assert\Range(min=3)}), - * @Assert\All(constraints={@Assert\NotNull, @Assert\Range(min=3)}) + * @Assert\Min(3) + * @Assert\All({@Assert\NotNull, @Assert\Min(3)}), + * @Assert\All(constraints={@Assert\NotNull, @Assert\Min(3)}) * @Assert\Collection(fields={ - * "foo" = {@Assert\NotNull, @Assert\Range(min=3)}, - * "bar" = @Assert\Range(min=5) + * "foo" = {@Assert\NotNull, @Assert\Min(3)}, + * "bar" = @Assert\Min(5) * }) * @Assert\Choice(choices={"A", "B"}, message="Must be one of %choices%") */ diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/GraphWalkerTest.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/GraphWalkerTest.php index cafcc7aa50d5..1f8d6213c0a1 100644 --- a/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/GraphWalkerTest.php +++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/GraphWalkerTest.php @@ -53,8 +53,6 @@ class GraphWalkerTest extends \PHPUnit_Framework_TestCase protected function setUp() { - set_error_handler(array($this, "deprecationErrorHandler")); - $this->metadataFactory = new FakeMetadataFactory(); $this->visitor = new ValidationVisitor('Root', $this->metadataFactory, new ConstraintValidatorFactory(), new DefaultTranslator()); $this->walker = $this->visitor->getGraphWalker(); @@ -64,23 +62,12 @@ protected function setUp() protected function tearDown() { - restore_error_handler(); - $this->metadataFactory = null; $this->visitor = null; $this->walker = null; $this->metadata = null; } - public function deprecationErrorHandler($errorNumber, $message, $file, $line, $context) - { - if ($errorNumber & E_USER_DEPRECATED) { - return true; - } - - return \PHPUnit_Util_ErrorHandler::handleError($errorNumber, $message, $file, $line); - } - public function testWalkObjectPassesCorrectClassAndProperty() { $this->metadata->addConstraint(new ConstraintA()); diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/GetterMetadataTest.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/GetterMetadataTest.php index d38225aa2e06..99303e9f0974 100644 --- a/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/GetterMetadataTest.php +++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/GetterMetadataTest.php @@ -25,7 +25,7 @@ public function testInvalidPropertyName() new GetterMetadata(self::CLASSNAME, 'foobar'); } - public function testGetPropertyValueFromPublicGetter() + public function testGetValueFromPublicGetter() { // private getters don't work yet because ReflectionMethod::setAccessible() // does not exists yet in a stable PHP release @@ -33,6 +33,6 @@ public function testGetPropertyValueFromPublicGetter() $entity = new Entity('foobar'); $metadata = new GetterMetadata(self::CLASSNAME, 'internal'); - $this->assertEquals('foobar from getter', $metadata->getPropertyValue($entity)); + $this->assertEquals('foobar from getter', $metadata->getValue($entity)); } } diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/Loader/AnnotationLoaderTest.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/Loader/AnnotationLoaderTest.php index 22a39c582e78..ce444acafb9a 100644 --- a/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/Loader/AnnotationLoaderTest.php +++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/Loader/AnnotationLoaderTest.php @@ -15,7 +15,7 @@ use Symfony\Component\Validator\Constraints\All; use Symfony\Component\Validator\Constraints\Collection; use Symfony\Component\Validator\Constraints\NotNull; -use Symfony\Component\Validator\Constraints\Range; +use Symfony\Component\Validator\Constraints\Min; use Symfony\Component\Validator\Constraints\Choice; use Symfony\Component\Validator\Mapping\ClassMetadata; use Symfony\Component\Validator\Mapping\Loader\AnnotationLoader; @@ -58,12 +58,12 @@ public function testLoadClassMetadata() $expected->setGroupSequence(array('Foo', 'Entity')); $expected->addConstraint(new ConstraintA()); $expected->addPropertyConstraint('firstName', new NotNull()); - $expected->addPropertyConstraint('firstName', new Range(array('min' => 3))); - $expected->addPropertyConstraint('firstName', new All(array(new NotNull(), new Range(array('min' => 3))))); - $expected->addPropertyConstraint('firstName', new All(array('constraints' => array(new NotNull(), new Range(array('min' => 3)))))); + $expected->addPropertyConstraint('firstName', new Min(3)); + $expected->addPropertyConstraint('firstName', new All(array(new NotNull(), new Min(3)))); + $expected->addPropertyConstraint('firstName', new All(array('constraints' => array(new NotNull(), new Min(3))))); $expected->addPropertyConstraint('firstName', new Collection(array('fields' => array( - 'foo' => array(new NotNull(), new Range(array('min' => 3))), - 'bar' => new Range(array('min' => 5)), + 'foo' => array(new NotNull(), new Min(3)), + 'bar' => new Min(5), )))); $expected->addPropertyConstraint('firstName', new Choice(array( 'message' => 'Must be one of %choices%', @@ -122,12 +122,12 @@ public function testLoadClassMetadataAndMerge() $expected->setGroupSequence(array('Foo', 'Entity')); $expected->addConstraint(new ConstraintA()); $expected->addPropertyConstraint('firstName', new NotNull()); - $expected->addPropertyConstraint('firstName', new Range(array('min' => 3))); - $expected->addPropertyConstraint('firstName', new All(array(new NotNull(), new Range(array('min' => 3))))); - $expected->addPropertyConstraint('firstName', new All(array('constraints' => array(new NotNull(), new Range(array('min' => 3)))))); + $expected->addPropertyConstraint('firstName', new Min(3)); + $expected->addPropertyConstraint('firstName', new All(array(new NotNull(), new Min(3)))); + $expected->addPropertyConstraint('firstName', new All(array('constraints' => array(new NotNull(), new Min(3))))); $expected->addPropertyConstraint('firstName', new Collection(array('fields' => array( - 'foo' => array(new NotNull(), new Range(array('min' => 3))), - 'bar' => new Range(array('min' => 5)), + 'foo' => array(new NotNull(), new Min(3)), + 'bar' => new Min(5), )))); $expected->addPropertyConstraint('firstName', new Choice(array( 'message' => 'Must be one of %choices%', diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/Loader/XmlFileLoaderTest.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/Loader/XmlFileLoaderTest.php index 22478e606d0e..428fe6b31768 100644 --- a/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/Loader/XmlFileLoaderTest.php +++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/Loader/XmlFileLoaderTest.php @@ -14,7 +14,7 @@ use Symfony\Component\Validator\Constraints\All; use Symfony\Component\Validator\Constraints\Collection; use Symfony\Component\Validator\Constraints\NotNull; -use Symfony\Component\Validator\Constraints\Range; +use Symfony\Component\Validator\Constraints\Min; use Symfony\Component\Validator\Constraints\Choice; use Symfony\Component\Validator\Mapping\ClassMetadata; use Symfony\Component\Validator\Mapping\Loader\XmlFileLoader; @@ -51,13 +51,13 @@ public function testLoadClassMetadata() $expected->addConstraint(new ConstraintA()); $expected->addConstraint(new ConstraintB()); $expected->addPropertyConstraint('firstName', new NotNull()); - $expected->addPropertyConstraint('firstName', new Range(array('min' => 3))); + $expected->addPropertyConstraint('firstName', new Min(3)); $expected->addPropertyConstraint('firstName', new Choice(array('A', 'B'))); - $expected->addPropertyConstraint('firstName', new All(array(new NotNull(), new Range(array('min' => 3))))); - $expected->addPropertyConstraint('firstName', new All(array('constraints' => array(new NotNull(), new Range(array('min' => 3)))))); + $expected->addPropertyConstraint('firstName', new All(array(new NotNull(), new Min(3)))); + $expected->addPropertyConstraint('firstName', new All(array('constraints' => array(new NotNull(), new Min(3))))); $expected->addPropertyConstraint('firstName', new Collection(array('fields' => array( - 'foo' => array(new NotNull(), new Range(array('min' => 3))), - 'bar' => array(new Range(array('min' => 5))), + 'foo' => array(new NotNull(), new Min(3)), + 'bar' => array(new Min(5)), )))); $expected->addPropertyConstraint('firstName', new Choice(array( 'message' => 'Must be one of %choices%', diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/Loader/YamlFileLoaderTest.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/Loader/YamlFileLoaderTest.php index 9e31cbb37d22..a175817f8695 100644 --- a/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/Loader/YamlFileLoaderTest.php +++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/Loader/YamlFileLoaderTest.php @@ -14,7 +14,7 @@ use Symfony\Component\Validator\Constraints\All; use Symfony\Component\Validator\Constraints\Collection; use Symfony\Component\Validator\Constraints\NotNull; -use Symfony\Component\Validator\Constraints\Range; +use Symfony\Component\Validator\Constraints\Min; use Symfony\Component\Validator\Constraints\Choice; use Symfony\Component\Validator\Mapping\ClassMetadata; use Symfony\Component\Validator\Mapping\Loader\YamlFileLoader; @@ -76,13 +76,13 @@ public function testLoadClassMetadata() $expected->addConstraint(new ConstraintA()); $expected->addConstraint(new ConstraintB()); $expected->addPropertyConstraint('firstName', new NotNull()); - $expected->addPropertyConstraint('firstName', new Range(array('min' => 3))); + $expected->addPropertyConstraint('firstName', new Min(3)); $expected->addPropertyConstraint('firstName', new Choice(array('A', 'B'))); - $expected->addPropertyConstraint('firstName', new All(array(new NotNull(), new Range(array('min' => 3))))); - $expected->addPropertyConstraint('firstName', new All(array('constraints' => array(new NotNull(), new Range(array('min' => 3)))))); + $expected->addPropertyConstraint('firstName', new All(array(new NotNull(), new Min(3)))); + $expected->addPropertyConstraint('firstName', new All(array('constraints' => array(new NotNull(), new Min(3))))); $expected->addPropertyConstraint('firstName', new Collection(array('fields' => array( - 'foo' => array(new NotNull(), new Range(array('min' => 3))), - 'bar' => array(new Range(array('min' => 5))), + 'foo' => array(new NotNull(), new Min(3)), + 'bar' => array(new Min(5)), )))); $expected->addPropertyConstraint('firstName', new Choice(array( 'message' => 'Must be one of %choices%', diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/Loader/constraint-mapping.xml b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/Loader/constraint-mapping.xml index 73398bd48be3..e815dcea55df 100644 --- a/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/Loader/constraint-mapping.xml +++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/Loader/constraint-mapping.xml @@ -29,9 +29,7 @@ <constraint name="NotNull" /> <!-- Constraint with single value --> - <constraint name="Range"> - <option name="min">3</option> - </constraint> + <constraint name="Min">3</constraint> <!-- Constraint with multiple values --> <constraint name="Choice"> @@ -42,19 +40,14 @@ <!-- Constraint with child constraints --> <constraint name="All"> <constraint name="NotNull" /> - <constraint name="Range"> - <option name="min">3</option> - </constraint> - + <constraint name="Min">3</constraint> </constraint> <!-- Option with child constraints --> <constraint name="All"> <option name="constraints"> <constraint name="NotNull" /> - <constraint name="Range"> - <option name="min">3</option> - </constraint> + <constraint name="Min">3</constraint> </option> </constraint> @@ -63,14 +56,10 @@ <option name="fields"> <value key="foo"> <constraint name="NotNull" /> - <constraint name="Range"> - <option name="min">3</option> - </constraint> + <constraint name="Min">3</constraint> </value> <value key="bar"> - <constraint name="Range"> - <option name="min">5</option> - </constraint> + <constraint name="Min">5</constraint> </value> </option> </constraint> diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/Loader/constraint-mapping.yml b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/Loader/constraint-mapping.yml index 38188dc5d976..b910c88a9a2f 100644 --- a/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/Loader/constraint-mapping.yml +++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/Loader/constraint-mapping.yml @@ -17,31 +17,26 @@ Symfony\Component\Validator\Tests\Fixtures\Entity: # Constraint without value - NotNull: ~ # Constraint with single value - - Range: - min: 3 + - Min: 3 # Constraint with multiple values - Choice: [A, B] # Constraint with child constraints - All: - NotNull: ~ - - Range: - min: 3 + - Min: 3 # Option with child constraints - All: constraints: - NotNull: ~ - - Range: - min: 3 + - Min: 3 # Value with child constraints - Collection: fields: foo: - NotNull: ~ - - Range: - min: 3 + - Min: 3 bar: - - Range: - min: 5 + - Min: 5 # Constraint with options - Choice: { choices: [A, B], message: Must be one of %choices% } dummy: diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/PropertyMetadataTest.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/PropertyMetadataTest.php index aeabefc5bc45..0dc1bb6b31a8 100644 --- a/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/PropertyMetadataTest.php +++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/PropertyMetadataTest.php @@ -25,11 +25,11 @@ public function testInvalidPropertyName() new PropertyMetadata(self::CLASSNAME, 'foobar'); } - public function testGetPropertyValueFromPrivateProperty() + public function testGetValueFromPrivateProperty() { $entity = new Entity('foobar'); $metadata = new PropertyMetadata(self::CLASSNAME, 'internal'); - $this->assertEquals('foobar', $metadata->getPropertyValue($entity)); + $this->assertEquals('foobar', $metadata->getValue($entity)); } } diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/ValidatorBuilderTest.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/ValidatorBuilderTest.php index d2c87db094c5..d77d9207049d 100644 --- a/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/ValidatorBuilderTest.php +++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/ValidatorBuilderTest.php @@ -31,15 +31,6 @@ protected function tearDown() $this->builder = null; } - public function deprecationErrorHandler($errorNumber, $message, $file, $line, $context) - { - if ($errorNumber & E_USER_DEPRECATED) { - return true; - } - - return \PHPUnit_Util_ErrorHandler::handleError($errorNumber, $message, $file, $line); - } - public function testAddObjectInitializer() { $this->assertSame($this->builder, $this->builder->addObjectInitializer( @@ -98,11 +89,9 @@ public function testDisableAnnotationMapping() public function testSetMetadataFactory() { - set_error_handler(array($this, "deprecationErrorHandler")); $this->assertSame($this->builder, $this->builder->setMetadataFactory( $this->getMock('Symfony\Component\Validator\Mapping\ClassMetadataFactoryInterface')) ); - restore_error_handler(); } public function testSetMetadataCache() diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/ValidatorContextTest.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/ValidatorContextTest.php index d5540c3b1e41..212a12cb478e 100644 --- a/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/ValidatorContextTest.php +++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/ValidatorContextTest.php @@ -22,27 +22,14 @@ class ValidatorContextTest extends \PHPUnit_Framework_TestCase protected function setUp() { - set_error_handler(array($this, "deprecationErrorHandler")); - $this->context = new ValidatorContext(); } protected function tearDown() { - restore_error_handler(); - $this->context = null; } - public function deprecationErrorHandler($errorNumber, $message, $file, $line, $context) - { - if ($errorNumber & E_USER_DEPRECATED) { - return true; - } - - return \PHPUnit_Util_ErrorHandler::handleError($errorNumber, $message, $file, $line); - } - public function testSetClassMetadataFactory() { $factory = $this->getMock('Symfony\Component\Validator\Mapping\ClassMetadataFactoryInterface'); diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/ValidatorFactoryTest.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/ValidatorFactoryTest.php index 392f8073f9e2..8ab61cd58132 100644 --- a/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/ValidatorFactoryTest.php +++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/ValidatorFactoryTest.php @@ -32,29 +32,16 @@ class ValidatorFactoryTest extends \PHPUnit_Framework_TestCase protected function setUp() { - set_error_handler(array($this, "deprecationErrorHandler")); - $this->defaultContext = new ValidatorContext(); $this->factory = new ValidatorFactory($this->defaultContext); } protected function tearDown() { - restore_error_handler(); - $this->defaultContext = null; $this->factory = null; } - public function deprecationErrorHandler($errorNumber, $message, $file, $line, $context) - { - if ($errorNumber & E_USER_DEPRECATED) { - return true; - } - - return \PHPUnit_Util_ErrorHandler::handleError($errorNumber, $message, $file, $line); - } - public function testOverrideClassMetadataFactory() { $factory1 = $this->getMock('Symfony\Component\Validator\Mapping\ClassMetadataFactoryInterface'); diff --git a/core/vendor/symfony/yaml/Symfony/Component/Yaml/.gitattributes b/core/vendor/symfony/yaml/Symfony/Component/Yaml/.gitattributes deleted file mode 100644 index 80481513cff2..000000000000 --- a/core/vendor/symfony/yaml/Symfony/Component/Yaml/.gitattributes +++ /dev/null @@ -1,2 +0,0 @@ -/Tests export-ignore -phpunit.xml.dist export-ignore diff --git a/core/vendor/symfony/yaml/Symfony/Component/Yaml/Dumper.php b/core/vendor/symfony/yaml/Symfony/Component/Yaml/Dumper.php index 7193127411df..8709f8b7e462 100644 --- a/core/vendor/symfony/yaml/Symfony/Component/Yaml/Dumper.php +++ b/core/vendor/symfony/yaml/Symfony/Component/Yaml/Dumper.php @@ -38,19 +38,21 @@ public function setIndentation($num) /** * Dumps a PHP value to YAML. * - * @param mixed $input The PHP value - * @param integer $inline The level where you switch to inline YAML - * @param integer $indent The level of indentation (used internally) + * @param mixed $input The PHP value + * @param integer $inline The level where you switch to inline YAML + * @param integer $indent The level of indentation (used internally) + * @param Boolean $exceptionOnInvalidType true if an exception must be thrown on invalid types (a PHP resource or object), false otherwise + * @param Boolean $objectSupport true if object support is enabled, false otherwise * * @return string The YAML representation of the PHP value */ - public function dump($input, $inline = 0, $indent = 0) + public function dump($input, $inline = 0, $indent = 0, $exceptionOnInvalidType = false, $objectSupport = false) { $output = ''; $prefix = $indent ? str_repeat(' ', $indent) : ''; if ($inline <= 0 || !is_array($input) || empty($input)) { - $output .= $prefix.Inline::dump($input); + $output .= $prefix.Inline::dump($input, $exceptionOnInvalidType, $objectSupport); } else { $isAHash = array_keys($input) !== range(0, count($input) - 1); @@ -59,9 +61,9 @@ public function dump($input, $inline = 0, $indent = 0) $output .= sprintf('%s%s%s%s', $prefix, - $isAHash ? Inline::dump($key).':' : '-', + $isAHash ? Inline::dump($key, $exceptionOnInvalidType, $objectSupport).':' : '-', $willBeInlined ? ' ' : "\n", - $this->dump($value, $inline - 1, $willBeInlined ? 0 : $indent + $this->indentation) + $this->dump($value, $inline - 1, $willBeInlined ? 0 : $indent + $this->indentation, $exceptionOnInvalidType, $objectSupport) ).($willBeInlined ? "\n" : ''); } } diff --git a/core/vendor/symfony/yaml/Symfony/Component/Yaml/Inline.php b/core/vendor/symfony/yaml/Symfony/Component/Yaml/Inline.php index 4ece8472b571..21a121a060db 100644 --- a/core/vendor/symfony/yaml/Symfony/Component/Yaml/Inline.php +++ b/core/vendor/symfony/yaml/Symfony/Component/Yaml/Inline.php @@ -22,17 +22,25 @@ class Inline { const REGEX_QUOTED_STRING = '(?:"([^"\\\\]*(?:\\\\.[^"\\\\]*)*)"|\'([^\']*(?:\'\'[^\']*)*)\')'; + private static $exceptionOnInvalidType = false; + private static $objectSupport = false; + /** * Converts a YAML string to a PHP array. * - * @param string $value A YAML string + * @param string $value A YAML string + * @param Boolean $exceptionOnInvalidType true if an exception must be thrown on invalid types (a PHP resource or object), false otherwise + * @param Boolean $objectSupport true if object support is enabled, false otherwise * * @return array A PHP array representing the YAML string * * @throws ParseException */ - public static function parse($value) + public static function parse($value, $exceptionOnInvalidType = false, $objectSupport = false) { + self::$exceptionOnInvalidType = $exceptionOnInvalidType; + self::$objectSupport = $objectSupport; + $value = trim($value); if (0 == strlen($value)) { @@ -44,21 +52,23 @@ public static function parse($value) mb_internal_encoding('ASCII'); } + $i = 0; switch ($value[0]) { case '[': - $result = self::parseSequence($value); + $result = self::parseSequence($value, $i); + ++$i; break; case '{': - $result = self::parseMapping($value); + $result = self::parseMapping($value, $i); + ++$i; break; default: - $i = 0; $result = self::parseScalar($value, null, array('"', "'"), $i); + } - // some comment can end the scalar - if (preg_replace('/\s+#.*$/A', '', substr($value, $i))) { - throw new ParseException(sprintf('Unexpected characters near "%s".', substr($value, $i))); - } + // some comments are allowed at the end + if (preg_replace('/\s+#.*$/A', '', substr($value, $i))) { + throw new ParseException(sprintf('Unexpected characters near "%s".', substr($value, $i))); } if (isset($mbEncoding)) { @@ -71,21 +81,35 @@ public static function parse($value) /** * Dumps a given PHP variable to a YAML string. * - * @param mixed $value The PHP variable to convert + * @param mixed $value The PHP variable to convert + * @param Boolean $exceptionOnInvalidType true if an exception must be thrown on invalid types (a PHP resource or object), false otherwise + * @param Boolean $objectSupport true if object support is enabled, false otherwise * * @return string The YAML string representing the PHP array * * @throws DumpException When trying to dump PHP resource */ - public static function dump($value) + public static function dump($value, $exceptionOnInvalidType = false, $objectSupport = false) { switch (true) { case is_resource($value): - throw new DumpException(sprintf('Unable to dump PHP resources in a YAML file ("%s").', get_resource_type($value))); + if ($exceptionOnInvalidType) { + throw new DumpException(sprintf('Unable to dump PHP resources in a YAML file ("%s").', get_resource_type($value))); + } + + return 'null'; case is_object($value): - return '!!php/object:'.serialize($value); + if ($objectSupport) { + return '!!php/object:'.serialize($value); + } + + if ($exceptionOnInvalidType) { + throw new DumpException('Object support when dumping a YAML file has been disabled.'); + } + + return 'null'; case is_array($value): - return self::dumpArray($value); + return self::dumpArray($value, $exceptionOnInvalidType, $objectSupport); case null === $value: return 'null'; case true === $value: @@ -123,11 +147,13 @@ public static function dump($value) /** * Dumps a PHP array to a YAML string. * - * @param array $value The PHP array to dump + * @param array $value The PHP array to dump + * @param Boolean $exceptionOnInvalidType true if an exception must be thrown on invalid types (a PHP resource or object), false otherwise + * @param Boolean $objectSupport true if object support is enabled, false otherwise * * @return string The YAML string representing the PHP array */ - private static function dumpArray($value) + private static function dumpArray($value, $exceptionOnInvalidType, $objectSupport) { // array $keys = array_keys($value); @@ -136,7 +162,7 @@ private static function dumpArray($value) ) { $output = array(); foreach ($value as $val) { - $output[] = self::dump($val); + $output[] = self::dump($val, $exceptionOnInvalidType, $objectSupport); } return sprintf('[%s]', implode(', ', $output)); @@ -145,7 +171,7 @@ private static function dumpArray($value) // mapping $output = array(); foreach ($value as $key => $val) { - $output[] = sprintf('%s: %s', self::dump($key), self::dump($val)); + $output[] = sprintf('%s: %s', self::dump($key, $exceptionOnInvalidType, $objectSupport), self::dump($val, $exceptionOnInvalidType, $objectSupport)); } return sprintf('{ %s }', implode(', ', $output)); @@ -375,12 +401,25 @@ private static function evaluateScalar($scalar) case 0 === strpos($scalar, '! '): return intval(self::parseScalar(substr($scalar, 2))); case 0 === strpos($scalar, '!!php/object:'): - return unserialize(substr($scalar, 13)); + if (self::$objectSupport) { + return unserialize(substr($scalar, 13)); + } + + if (self::$exceptionOnInvalidType) { + throw new ParseException('Object support when parsing a YAML file has been disabled.'); + } + + return null; case ctype_digit($scalar): $raw = $scalar; $cast = intval($scalar); return '0' == $scalar[0] ? octdec($scalar) : (((string) $raw == (string) $cast) ? $cast : $raw); + case '-' === $scalar[0] && ctype_digit(substr($scalar, 1)): + $raw = $scalar; + $cast = intval($scalar); + + return '0' == $scalar[1] ? octdec($scalar) : (((string) $raw == (string) $cast) ? $cast : $raw); case 'true' === strtolower($scalar): return true; case 'false' === strtolower($scalar): diff --git a/core/vendor/symfony/yaml/Symfony/Component/Yaml/LICENSE b/core/vendor/symfony/yaml/Symfony/Component/Yaml/LICENSE index cdffe7aebc04..88a57f8d8da4 100644 --- a/core/vendor/symfony/yaml/Symfony/Component/Yaml/LICENSE +++ b/core/vendor/symfony/yaml/Symfony/Component/Yaml/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2004-2012 Fabien Potencier +Copyright (c) 2004-2013 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 diff --git a/core/vendor/symfony/yaml/Symfony/Component/Yaml/Parser.php b/core/vendor/symfony/yaml/Symfony/Component/Yaml/Parser.php index d09227b2797e..8129b41e070c 100644 --- a/core/vendor/symfony/yaml/Symfony/Component/Yaml/Parser.php +++ b/core/vendor/symfony/yaml/Symfony/Component/Yaml/Parser.php @@ -38,13 +38,15 @@ public function __construct($offset = 0) /** * Parses a YAML string to a PHP value. * - * @param string $value A YAML string + * @param string $value A YAML string + * @param Boolean $exceptionOnInvalidType true if an exception must be thrown on invalid types (a PHP resource or object), false otherwise + * @param Boolean $objectSupport true if object support is enabled, false otherwise * * @return mixed A PHP value * * @throws ParseException If the YAML is not valid */ - public function parse($value) + public function parse($value, $exceptionOnInvalidType = false, $objectSupport = false) { $this->currentLineNb = -1; $this->currentLine = ''; @@ -88,7 +90,7 @@ public function parse($value) $c = $this->getRealCurrentLineNb() + 1; $parser = new Parser($c); $parser->refs =& $this->refs; - $data[] = $parser->parse($this->getNextEmbedBlock()); + $data[] = $parser->parse($this->getNextEmbedBlock(), $exceptionOnInvalidType, $objectSupport); } else { if (isset($values['leadspaces']) && ' ' == $values['leadspaces'] @@ -104,9 +106,9 @@ public function parse($value) $block .= "\n".$this->getNextEmbedBlock($this->getCurrentLineIndentation() + 2); } - $data[] = $parser->parse($block); + $data[] = $parser->parse($block, $exceptionOnInvalidType, $objectSupport); } else { - $data[] = $this->parseValue($values['value']); + $data[] = $this->parseValue($values['value'], $exceptionOnInvalidType, $objectSupport); } } } elseif (preg_match('#^(?P<key>'.Inline::REGEX_QUOTED_STRING.'|[^ \'"\[\{].*?) *\:(\s+(?P<value>.+?))?\s*$#u', $this->currentLine, $values)) { @@ -115,6 +117,8 @@ public function parse($value) } $context = 'mapping'; + // force correct settings + Inline::parse(null, $exceptionOnInvalidType, $objectSupport); try { $key = Inline::parseScalar($values['key']); } catch (ParseException $e) { @@ -139,7 +143,7 @@ public function parse($value) $c = $this->getRealCurrentLineNb() + 1; $parser = new Parser($c); $parser->refs =& $this->refs; - $parsed = $parser->parse($value); + $parsed = $parser->parse($value, $exceptionOnInvalidType, $objectSupport); $merged = array(); if (!is_array($parsed)) { @@ -176,20 +180,21 @@ public function parse($value) $c = $this->getRealCurrentLineNb() + 1; $parser = new Parser($c); $parser->refs =& $this->refs; - $data[$key] = $parser->parse($this->getNextEmbedBlock()); + $data[$key] = $parser->parse($this->getNextEmbedBlock(), $exceptionOnInvalidType, $objectSupport); } } else { if ($isInPlace) { $data = $this->refs[$isInPlace]; } else { - $data[$key] = $this->parseValue($values['value']); + $data[$key] = $this->parseValue($values['value'], $exceptionOnInvalidType, $objectSupport); } } } else { - // 1-liner followed by newline - if (2 == count($this->lines) && empty($this->lines[1])) { + // 1-liner optionally followed by newline + $lineCount = count($this->lines); + if (1 === $lineCount || (2 === $lineCount && empty($this->lines[1]))) { try { - $value = Inline::parse($this->lines[0]); + $value = Inline::parse($this->lines[0], $exceptionOnInvalidType, $objectSupport); } catch (ParseException $e) { $e->setParsedLine($this->getRealCurrentLineNb() + 1); $e->setSnippet($this->currentLine); @@ -366,7 +371,7 @@ private function moveToPreviousLine() * * @throws ParseException When reference does not exist */ - private function parseValue($value) + private function parseValue($value, $exceptionOnInvalidType, $objectSupport) { if (0 === strpos($value, '*')) { if (false !== $pos = strpos($value, '#')) { @@ -389,7 +394,7 @@ private function parseValue($value) } try { - return Inline::parse($value); + return Inline::parse($value, $exceptionOnInvalidType, $objectSupport); } catch (ParseException $e) { $e->setParsedLine($this->getRealCurrentLineNb() + 1); $e->setSnippet($this->currentLine); @@ -544,10 +549,6 @@ private function cleanup($value) { $value = str_replace(array("\r\n", "\r"), "\n", $value); - if (!preg_match("#\n$#", $value)) { - $value .= "\n"; - } - // strip YAML header $count = 0; $value = preg_replace('#^\%YAML[: ][\d\.]+.*\n#su', '', $value, -1, $count); diff --git a/core/vendor/symfony/yaml/Symfony/Component/Yaml/Tests/DumperTest.php b/core/vendor/symfony/yaml/Symfony/Component/Yaml/Tests/DumperTest.php index c662eadb8d28..1199118d7798 100644 --- a/core/vendor/symfony/yaml/Symfony/Component/Yaml/Tests/DumperTest.php +++ b/core/vendor/symfony/yaml/Symfony/Component/Yaml/Tests/DumperTest.php @@ -152,11 +152,26 @@ public function testInlineLevel() $this->assertEquals($expected, $this->dumper->dump($array, 10), '->dump() takes an inline level argument'); } - public function testObjectsSupport() + public function testObjectSupportEnabled() { - $a = array('foo' => new A(), 'bar' => 1); + $dump = $this->dumper->dump(array('foo' => new A(), 'bar' => 1), 0, 0, false, true); - $this->assertEquals('{ foo: !!php/object:O:30:"Symfony\Component\Yaml\Tests\A":1:{s:1:"a";s:3:"foo";}, bar: 1 }', $this->dumper->dump($a), '->dump() is able to dump objects'); + $this->assertEquals('{ foo: !!php/object:O:30:"Symfony\Component\Yaml\Tests\A":1:{s:1:"a";s:3:"foo";}, bar: 1 }', $dump, '->dump() is able to dump objects'); + } + + public function testObjectSupportDisabledButNoExceptions() + { + $dump = $this->dumper->dump(array('foo' => new A(), 'bar' => 1)); + + $this->assertEquals('{ foo: null, bar: 1 }', $dump, '->dump() does not dump objects when disabled'); + } + + /** + * @expectedException \Symfony\Component\Yaml\Exception\DumpException + */ + public function testObjectSupportDisabledWithExceptions() + { + $this->dumper->dump(array('foo' => new A(), 'bar' => 1), 0, 0, true, false); } } diff --git a/core/vendor/symfony/yaml/Symfony/Component/Yaml/Tests/InlineTest.php b/core/vendor/symfony/yaml/Symfony/Component/Yaml/Tests/InlineTest.php index 9733426a3e4c..04e9d4df8098 100644 --- a/core/vendor/symfony/yaml/Symfony/Component/Yaml/Tests/InlineTest.php +++ b/core/vendor/symfony/yaml/Symfony/Component/Yaml/Tests/InlineTest.php @@ -19,7 +19,7 @@ class InlineTest extends \PHPUnit_Framework_TestCase public function testParse() { foreach ($this->getTestsForParse() as $yaml => $value) { - $this->assertEquals($value, Inline::parse($yaml), sprintf('::parse() converts an inline YAML to a PHP structure (%s)', $yaml)); + $this->assertSame($value, Inline::parse($yaml), sprintf('::parse() converts an inline YAML to a PHP structure (%s)', $yaml)); } } @@ -92,6 +92,22 @@ public function testParseInvalidMappingKeyShouldThrowException() Inline::parse($value); } + /** + * @expectedException \Symfony\Component\Yaml\Exception\ParseException + */ + public function testParseInvalidMappingShouldThrowException() + { + Inline::parse('[foo] bar'); + } + + /** + * @expectedException \Symfony\Component\Yaml\Exception\ParseException + */ + public function testParseInvalidSequenceShouldThrowException() + { + Inline::parse('{ foo: bar } bar'); + } + public function testParseScalarWithCorrectlyQuotedStringShouldReturnString() { $value = "'don''t do somthin'' like that'"; @@ -108,6 +124,7 @@ protected function getTestsForParse() 'false' => false, 'true' => true, '12' => 12, + '-12' => -12, '"quoted string"' => 'quoted string', "'quoted string'" => 'quoted string', '12.30e+02' => 12.30e+02, @@ -117,7 +134,7 @@ protected function getTestsForParse() '-.Inf' => log(0), "'686e444'" => '686e444', '686e444' => 646e444, - '123456789123456789' => '123456789123456789', + '123456789123456789123456789123456789' => '123456789123456789123456789123456789', '"foo\r\nbar"' => "foo\r\nbar", "'foo#bar'" => 'foo#bar', "'foo # bar'" => 'foo # bar', diff --git a/core/vendor/symfony/yaml/Symfony/Component/Yaml/Tests/ParserTest.php b/core/vendor/symfony/yaml/Symfony/Component/Yaml/Tests/ParserTest.php index e27482a69479..231a37b7d158 100644 --- a/core/vendor/symfony/yaml/Symfony/Component/Yaml/Tests/ParserTest.php +++ b/core/vendor/symfony/yaml/Symfony/Component/Yaml/Tests/ParserTest.php @@ -13,7 +13,6 @@ use Symfony\Component\Yaml\Yaml; use Symfony\Component\Yaml\Parser; -use Symfony\Component\Yaml\Exception\ParseException; class ParserTest extends \PHPUnit_Framework_TestCase { @@ -106,14 +105,226 @@ public function testEndOfTheDocumentMarker() $this->assertEquals('foo', $this->parser->parse($yaml)); } - public function testObjectsSupport() + public function getBlockChompingTests() { - $b = array('foo' => new B(), 'bar' => 1); - $this->assertEquals($this->parser->parse(<<<EOF + $tests = array(); + + $yaml = <<<'EOF' +foo: |- + one + two + +bar: |- + one + two + +EOF; + $expected = array( + 'foo' => "one\ntwo", + 'bar' => "one\ntwo", + ); + $tests['Literal block chomping strip with trailing newline'] = array($expected, $yaml); + + $yaml = <<<'EOF' +foo: |- + one + two +bar: |- + one + two +EOF; + $expected = array( + 'foo' => "one\ntwo", + 'bar' => "one\ntwo", + ); + $tests['Literal block chomping strip without trailing newline'] = array($expected, $yaml); + + $yaml = <<<'EOF' +foo: | + one + two + +bar: | + one + two + +EOF; + $expected = array( + 'foo' => "one\ntwo\n", + 'bar' => "one\ntwo\n", + ); + $tests['Literal block chomping clip with trailing newline'] = array($expected, $yaml); + + $yaml = <<<'EOF' +foo: | + one + two +bar: | + one + two +EOF; + $expected = array( + 'foo' => "one\ntwo\n", + 'bar' => "one\ntwo\n", + ); + $tests['Literal block chomping clip without trailing newline'] = array($expected, $yaml); + + $yaml = <<<'EOF' +foo: |+ + one + two + +bar: |+ + one + two + +EOF; + $expected = array( + 'foo' => "one\ntwo\n\n", + 'bar' => "one\ntwo\n\n", + ); + $tests['Literal block chomping keep with trailing newline'] = array($expected, $yaml); + + $yaml = <<<'EOF' +foo: |+ + one + two +bar: |+ + one + two +EOF; + $expected = array( + 'foo' => "one\ntwo\n", + 'bar' => "one\ntwo\n", + ); + $tests['Literal block chomping keep without trailing newline'] = array($expected, $yaml); + + $yaml = <<<'EOF' +foo: >- + one + two + +bar: >- + one + two + +EOF; + $expected = array( + 'foo' => "one two", + 'bar' => "one two", + ); + $tests['Folded block chomping strip with trailing newline'] = array($expected, $yaml); + + $yaml = <<<'EOF' +foo: >- + one + two +bar: >- + one + two +EOF; + $expected = array( + 'foo' => "one two", + 'bar' => "one two", + ); + $tests['Folded block chomping strip without trailing newline'] = array($expected, $yaml); + + $yaml = <<<'EOF' +foo: > + one + two + +bar: > + one + two + +EOF; + $expected = array( + 'foo' => "one two\n", + 'bar' => "one two\n", + ); + $tests['Folded block chomping clip with trailing newline'] = array($expected, $yaml); + + $yaml = <<<'EOF' +foo: > + one + two +bar: > + one + two +EOF; + $expected = array( + 'foo' => "one two\n", + 'bar' => "one two\n", + ); + $tests['Folded block chomping clip without trailing newline'] = array($expected, $yaml); + + $yaml = <<<'EOF' +foo: >+ + one + two + +bar: >+ + one + two + +EOF; + $expected = array( + 'foo' => "one two\n\n", + 'bar' => "one two\n\n", + ); + $tests['Folded block chomping keep with trailing newline'] = array($expected, $yaml); + + $yaml = <<<'EOF' +foo: >+ + one + two +bar: >+ + one + two +EOF; + $expected = array( + 'foo' => "one two\n", + 'bar' => "one two\n", + ); + $tests['Folded block chomping keep without trailing newline'] = array($expected, $yaml); + + return $tests; + } + + /** + * @dataProvider getBlockChompingTests + */ + public function testBlockChomping($expected, $yaml) + { + $this->assertSame($expected, $this->parser->parse($yaml)); + } + + public function testObjectSupportEnabled() + { + $input = <<<EOF foo: !!php/object:O:30:"Symfony\Component\Yaml\Tests\B":1:{s:1:"b";s:3:"foo";} bar: 1 -EOF - ), $b, '->parse() is able to dump objects'); +EOF; + $this->assertEquals(array('foo' => new B(), 'bar' => 1), $this->parser->parse($input, false, true), '->parse() is able to parse objects'); + } + + public function testObjectSupportDisabledButNoExceptions() + { + $input = <<<EOF +foo: !!php/object:O:30:"Symfony\Tests\Component\Yaml\B":1:{s:1:"b";s:3:"foo";} +bar: 1 +EOF; + + $this->assertEquals(array('foo' => null, 'bar' => 1), $this->parser->parse($input), '->parse() does not parse objects'); + } + + /** + * @expectedException \Symfony\Component\Yaml\Exception\ParseException + */ + public function testObjectsSupportDisabledWithExceptions() + { + $this->parser->parse('foo: !!php/object:O:30:"Symfony\Tests\Component\Yaml\B":1:{s:1:"b";s:3:"foo";}', true, false); } public function testNonUtf8Exception() @@ -143,7 +354,7 @@ public function testNonUtf8Exception() /** * - * @expectedException Symfony\Component\Yaml\Exception\ParseException + * @expectedException \Symfony\Component\Yaml\Exception\ParseException * */ public function testUnindentedCollectionException() @@ -161,7 +372,7 @@ public function testUnindentedCollectionException() } /** - * @expectedException Symfony\Component\Yaml\Exception\ParseException + * @expectedException \Symfony\Component\Yaml\Exception\ParseException */ public function testSequenceInAMapping() { @@ -174,7 +385,7 @@ public function testSequenceInAMapping() } /** - * @expectedException Symfony\Component\Yaml\Exception\ParseException + * @expectedException \Symfony\Component\Yaml\Exception\ParseException */ public function testMappingInASequence() { diff --git a/core/vendor/symfony/yaml/Symfony/Component/Yaml/Yaml.php b/core/vendor/symfony/yaml/Symfony/Component/Yaml/Yaml.php index 85cdf3db66ec..25dfb7143ba7 100644 --- a/core/vendor/symfony/yaml/Symfony/Component/Yaml/Yaml.php +++ b/core/vendor/symfony/yaml/Symfony/Component/Yaml/Yaml.php @@ -22,13 +22,53 @@ */ class Yaml { + /** + * Be warned that PHP support will be removed in Symfony 2.3. + * + * @deprecated Deprecated since version 2.0, to be removed in 2.3. + */ public static $enablePhpParsing = false; + /** + * Enables PHP support when parsing YAML files. + * + * Be warned that PHP support will be removed in Symfony 2.3. + * + * @deprecated Deprecated since version 2.0, to be removed in 2.3. + */ public static function enablePhpParsing() { self::$enablePhpParsing = true; } + /** + * Sets the PHP support flag when parsing YAML files. + * + * Be warned that PHP support will be removed in Symfony 2.3. + * + * @param Boolean $boolean true if PHP parsing support is enabled, false otherwise + * + * @deprecated Deprecated since version 2.0, to be removed in 2.3. + */ + public static function setPhpParsing($boolean) + { + self::$enablePhpParsing = (Boolean) $boolean; + } + + /** + * Checks if PHP support is enabled when parsing YAML files. + * + * Be warned that PHP support will be removed in Symfony 2.3. + * + * @return Boolean true if PHP parsing support is enabled, false otherwise + * + * @deprecated Deprecated since version 2.0, to be removed in 2.3. + */ + public static function supportsPhpParsing() + { + return self::$enablePhpParsing; + } + /** * Parses YAML into a PHP array. * @@ -41,6 +81,10 @@ public static function enablePhpParsing() * print_r($array); * </code> * + * As this method accepts both plain strings and file names as an input, + * you must validate the input before calling this method. Passing a file + * as an input is a deprecated feature and will be removed in 3.0. + * * @param string $input Path to a YAML file or a string containing YAML * * @return array The YAML converted to a PHP array @@ -49,7 +93,7 @@ public static function enablePhpParsing() * * @api */ - public static function parse($input) + public static function parse($input, $exceptionOnInvalidType = false, $objectSupport = false) { // if input is a file, process it $file = ''; @@ -79,7 +123,7 @@ public static function parse($input) $yaml = new Parser(); try { - return $yaml->parse($input); + return $yaml->parse($input, $exceptionOnInvalidType, $objectSupport); } catch (ParseException $e) { if ($file) { $e->setParsedFile($file); @@ -95,19 +139,21 @@ public static function parse($input) * The dump method, when supplied with an array, will do its best * to convert the array into friendly YAML. * - * @param array $array PHP array - * @param integer $inline The level where you switch to inline YAML - * @param integer $indent The amount of spaces to use for indentation of nested nodes. + * @param array $array PHP array + * @param integer $inline The level where you switch to inline YAML + * @param integer $indent The amount of spaces to use for indentation of nested nodes. + * @param Boolean $exceptionOnInvalidType true if an exception must be thrown on invalid types (a PHP resource or object), false otherwise + * @param Boolean $objectSupport true if object support is enabled, false otherwise * * @return string A YAML string representing the original PHP array * * @api */ - public static function dump($array, $inline = 2, $indent = 4) + public static function dump($array, $inline = 2, $indent = 2, $exceptionOnInvalidType = false, $objectSupport = false) { $yaml = new Dumper(); $yaml->setIndentation($indent); - return $yaml->dump($array, $inline); + return $yaml->dump($array, $inline, 0, $exceptionOnInvalidType, $objectSupport); } } diff --git a/core/vendor/twig/twig/.editorconfig b/core/vendor/twig/twig/.editorconfig new file mode 100644 index 000000000000..270f1d1b770f --- /dev/null +++ b/core/vendor/twig/twig/.editorconfig @@ -0,0 +1,18 @@ +; top-most EditorConfig file +root = true + +; Unix-style newlines +[*] +end_of_line = LF + +[*.php] +indent_style = space +indent_size = 4 + +[*.test] +indent_style = space +indent_size = 4 + +[*.rst] +indent_style = space +indent_size = 4 diff --git a/core/vendor/twig/twig/CHANGELOG b/core/vendor/twig/twig/CHANGELOG index dcfab94ac61a..25513cff7e9f 100644 --- a/core/vendor/twig/twig/CHANGELOG +++ b/core/vendor/twig/twig/CHANGELOG @@ -1,3 +1,25 @@ +* 1.12.1 (2013-01-15) + + * added support for object instances as the second argument of the constant function + * relaxed globals management to avoid a BC break + * added support for {{ some_string[:2] }} + +* 1.12.0 (2013-01-08) + + * added verbatim as an alias for the raw tag to avoid confusion with the raw filter + * fixed registration of tests and functions as anonymous functions + * fixed globals management + +* 1.12.0-RC1 (2012-12-29) + + * added an include function (does the same as the include tag but in a more flexible way) + * added the ability to use any PHP callable to define filters, functions, and tests + * added a syntax error when using a loop variable that is not defined + * added the ability to set default values for macro arguments + * added support for named arguments for filters, tests, and functions + * moved filters/functions/tests syntax errors to the parser + * added support for extended ternary operator syntaxes + * 1.11.1 (2012-11-11) * fixed debug info line numbering (was off by 2) diff --git a/core/vendor/twig/twig/LICENSE b/core/vendor/twig/twig/LICENSE index 5063d8d058b8..3384cc5589d5 100644 --- a/core/vendor/twig/twig/LICENSE +++ b/core/vendor/twig/twig/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2009 by the Twig Team, see AUTHORS for more details. +Copyright (c) 2009-2013 by the Twig Team, see AUTHORS for more details. Some rights reserved. diff --git a/core/vendor/twig/twig/bin/create_pear_package.php b/core/vendor/twig/twig/bin/create_pear_package.php deleted file mode 100644 index 4899927fb4ac..000000000000 --- a/core/vendor/twig/twig/bin/create_pear_package.php +++ /dev/null @@ -1,42 +0,0 @@ -<?php - -if (!isset($argv[1])) -{ - die('You must provide the version (1.0.0)'); -} - -if (!isset($argv[2])) -{ - die('You must provide the stability (alpha, beta, or stable)'); -} - -$context = array( - 'date' => date('Y-m-d'), - 'time' => date('H:m:00'), - 'version' => $argv[1], - 'api_version' => $argv[1], - 'stability' => $argv[2], - 'api_stability' => $argv[2], -); - -$context['files'] = ''; -$path = realpath(dirname(__FILE__).'/../lib/Twig'); -foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path), RecursiveIteratorIterator::LEAVES_ONLY) as $file) -{ - if (preg_match('/\.php$/', $file)) - { - $name = str_replace($path.'/', '', $file); - $context['files'] .= ' <file install-as="Twig/'.$name.'" name="'.$name.'" role="php" />'."\n"; - } -} - -$template = file_get_contents(dirname(__FILE__).'/../package.xml.tpl'); -$content = preg_replace_callback('/\{\{\s*([a-zA-Z0-9_]+)\s*\}\}/', 'replace_parameters', $template); -file_put_contents(dirname(__FILE__).'/../package.xml', $content); - -function replace_parameters($matches) -{ - global $context; - - return isset($context[$matches[1]]) ? $context[$matches[1]] : null; -} diff --git a/core/vendor/twig/twig/composer.json b/core/vendor/twig/twig/composer.json index 3bbc5cab1be7..5530d282e524 100644 --- a/core/vendor/twig/twig/composer.json +++ b/core/vendor/twig/twig/composer.json @@ -25,7 +25,7 @@ }, "extra": { "branch-alias": { - "dev-master": "1.11-dev" + "dev-master": "1.12-dev" } } } diff --git a/core/vendor/twig/twig/doc/advanced.rst b/core/vendor/twig/twig/doc/advanced.rst index 4be84ed36d6f..06ad7711c098 100644 --- a/core/vendor/twig/twig/doc/advanced.rst +++ b/core/vendor/twig/twig/doc/advanced.rst @@ -1,6 +1,12 @@ Extending Twig ============== +.. caution:: + + This section describes how to extend Twig as of **Twig 1.12**. If you are + using an older version, read the :doc:`legacy<advanced_legacy>` chapter + instead. + Twig can be extended in many ways; you can add extra tags, filters, tests, operators, global variables, and functions. You can even extend the parser itself with node visitors. @@ -14,11 +20,10 @@ itself with node visitors. .. caution:: - When extending Twig by calling methods on the Twig environment instance, - Twig won't be able to recompile your templates when the PHP code is - updated. To see your changes in real-time, either disable template caching - or package your code into an extension (see the next section of this - chapter). + When extending Twig without creating an extension, Twig won't be able to + recompile your templates when the PHP code is updated. To see your changes + in real-time, either disable template caching or package your code into an + extension (see the next section of this chapter). Before extending Twig, you must understand the differences between all the different possible extension points and when to use them. @@ -75,9 +80,9 @@ extension point to use. And you can use it anywhere an expression is accepted: .. code-block:: jinja - {{ 'some text' ~ ipsum(40) ~ 'some more text' }} + {{ 'some text' ~ lipsum(40) ~ 'some more text' }} - {% set ipsum = ipsum(40) %} + {% set lipsum = lipsum(40) %} Last but not the least, you can also use a *global* object with a method able to generate lorem ipsum text: @@ -121,151 +126,113 @@ You can then use the ``text`` variable anywhere in a template: Filters ------- -A filter is a regular PHP function or an object method that takes the left -side of the filter (before the pipe ``|``) as first argument and the extra -arguments passed to the filter (within parentheses ``()``) as extra arguments. - -Defining a filter is as easy as associating the filter name with a PHP -callable. For instance, let's say you have the following code in a template: - -.. code-block:: jinja - - {{ 'TWIG'|lower }} - -When compiling this template to PHP, Twig looks for the PHP callable -associated with the ``lower`` filter. The ``lower`` filter is a built-in Twig -filter, and it is simply mapped to the PHP ``strtolower()`` function. After -compilation, the generated PHP code is roughly equivalent to: - -.. code-block:: html+php - - <?php echo strtolower('TWIG') ?> - -As you can see, the ``'TWIG'`` string is passed as a first argument to the PHP -function. - -A filter can also take extra arguments like in the following example: - -.. code-block:: jinja - - {{ now|date('d/m/Y') }} - -In this case, the extra arguments are passed to the function after the main -argument, and the compiled code is equivalent to: +Creating a filter is as simple as associating a name with a PHP callable:: -.. code-block:: html+php - - <?php echo twig_date_format_filter($now, 'd/m/Y') ?> - -Let's see how to create a new filter. - -In this section, we will create a ``rot13`` filter, which should return the -`rot13`_ transformation of a string. Here is an example of its usage and the -expected output: + // an anonymous function + $filter = new Twig_SimpleFilter('rot13', function ($string) { + return str_rot13($string); + }); -.. code-block:: jinja + // or a simple PHP function + $filter = new Twig_SimpleFilter('rot13', 'str_rot13'); - {{ "Twig"|rot13 }} + // or a class method + $filter = new Twig_SimpleFilter('rot13', array('SomeClass', 'rot13Filter')); - {# should displays Gjvt #} +The first argument passed to the ``Twig_SimpleFilter`` constructor is the name +of the filter you will use in templates and the second one is the PHP callable +to associate with it. -Adding a filter is as simple as calling the ``addFilter()`` method on the -``Twig_Environment`` instance:: +Then, add the filter to your Twig environment:: $twig = new Twig_Environment($loader); - $twig->addFilter('rot13', new Twig_Filter_Function('str_rot13')); - -The second argument of ``addFilter()`` is an instance of ``Twig_Filter``. -Here, we use ``Twig_Filter_Function`` as the filter is a PHP function. The -first argument passed to the ``Twig_Filter_Function`` constructor is the name -of the PHP function to call, here ``str_rot13``, a native PHP function. + $twig->addFilter($filter); -Let's say I now want to be able to add a prefix before the converted string: +And here is how to use it in a template: .. code-block:: jinja - {{ "Twig"|rot13('prefix_') }} + {{ 'Twig'|rot13 }} - {# should displays prefix_Gjvt #} + {# will output Gjvt #} -As the PHP ``str_rot13()`` function does not support this requirement, let's -create a new PHP function:: +When called by Twig, the PHP callable receives the left side of the filter +(before the pipe ``|``) as the first argument and the extra arguments passed +to the filter (within parentheses ``()``) as extra arguments. - function project_compute_rot13($string, $prefix = '') - { - return $prefix.str_rot13($string); - } +For instance, the following code: -As you can see, the ``prefix`` argument of the filter is passed as an extra -argument to the ``project_compute_rot13()`` function. - -Adding this filter is as easy as before:: +.. code-block:: jinja - $twig->addFilter('rot13', new Twig_Filter_Function('project_compute_rot13')); + {{ 'TWIG'|lower }} + {{ now|date('d/m/Y') }} -For better encapsulation, a filter can also be defined as a static method of a -class. The ``Twig_Filter_Function`` class can also be used to register such -static methods as filters:: +is compiled to something like the following:: - $twig->addFilter('rot13', new Twig_Filter_Function('SomeClass::rot13Filter')); + <?php echo strtolower('TWIG') ?> + <?php echo twig_date_format_filter($now, 'd/m/Y') ?> -.. tip:: +The ``Twig_SimpleFilter`` class takes an array of options as its last +argument:: - In an extension, you can also define a filter as a static method of the - extension class. + $filter = new Twig_SimpleFilter('rot13', 'str_rot13', $options); Environment aware Filters ~~~~~~~~~~~~~~~~~~~~~~~~~ -The ``Twig_Filter`` classes take options as their last argument. For instance, -if you want access to the current environment instance in your filter, set the -``needs_environment`` option to ``true``:: - - $filter = new Twig_Filter_Function('str_rot13', array('needs_environment' => true)); - -Twig will then pass the current environment as the first argument to the -filter call:: +If you want to access the current environment instance in your filter, set the +``needs_environment`` option to ``true``; Twig will pass the current +environment as the first argument to the filter call:: - function twig_compute_rot13(Twig_Environment $env, $string) - { + $filter = new Twig_SimpleFilter('rot13', function (Twig_Environment $env, $string) { // get the current charset for instance $charset = $env->getCharset(); return str_rot13($string); - } + }, array('needs_environment' => true)); + +Context aware Filters +~~~~~~~~~~~~~~~~~~~~~ + +If you want to access the current context in your filter, set the +``needs_context`` option to ``true``; Twig will pass the current context as +the first argument to the filter call (or the second one if +``needs_environment`` is also set to ``true``):: + + $filter = new Twig_SimpleFilter('rot13', function ($context, $string) { + // ... + }, array('needs_context' => true)); + + $filter = new Twig_SimpleFilter('rot13', function (Twig_Environment $env, $context, $string) { + // ... + }, array('needs_context' => true, 'needs_environment' => true)); Automatic Escaping ~~~~~~~~~~~~~~~~~~ If automatic escaping is enabled, the output of the filter may be escaped before printing. If your filter acts as an escaper (or explicitly outputs html -or javascript code), you will want the raw output to be printed. In such a +or JavaScript code), you will want the raw output to be printed. In such a case, set the ``is_safe`` option:: - $filter = new Twig_Filter_Function('nl2br', array('is_safe' => array('html'))); + $filter = new Twig_SimpleFilter('nl2br', 'nl2br', array('is_safe' => array('html'))); Some filters may need to work on input that is already escaped or safe, for example when adding (safe) html tags to originally unsafe output. In such a case, set the ``pre_escape`` option to escape the input data before it is run through your filter:: - $filter = new Twig_Filter_Function('somefilter', array('pre_escape' => 'html', 'is_safe' => array('html'))); + $filter = new Twig_SimpleFilter('somefilter', 'somefilter', array('pre_escape' => 'html', 'is_safe' => array('html'))); Dynamic Filters ~~~~~~~~~~~~~~~ -.. versionadded:: 1.5 - Dynamic filters support was added in Twig 1.5. - A filter name containing the special ``*`` character is a dynamic filter as the ``*`` can be any string:: - $twig->addFilter('*_path', new Twig_Filter_Function('twig_path')); - - function twig_path($name, $arguments) - { + $filter = new Twig_SimpleFilter('*_path', function ($name, $arguments) { // ... - } + }); The following filters will be matched by the above defined dynamic filter: @@ -274,83 +241,43 @@ The following filters will be matched by the above defined dynamic filter: A dynamic filter can define more than one dynamic parts:: - $twig->addFilter('*_path_*', new Twig_Filter_Function('twig_path')); - - function twig_path($name, $suffix, $arguments) - { + $filter = new Twig_SimpleFilter('*_path', function ($name, $suffix, $arguments) { // ... - } + }); The filter will receive all dynamic part values before the normal filters -arguments. For instance, a call to ``'foo'|a_path_b()`` will result in the -following PHP call: ``twig_path('a', 'b', 'foo')``. +arguments, but after the environment and the context. For instance, a call to +``'foo'|a_path_b()`` will result in the following arguments to be passed to +the filter: ``('a', 'b', 'foo')``. Functions --------- -A function is a regular PHP function or an object method that can be called from -templates. - -.. code-block:: jinja - - {{ constant("DATE_W3C") }} +Functions are defined in the exact same way as filters, but you need to create +an instance of ``Twig_SimpleFunction``:: -When compiling this template to PHP, Twig looks for the PHP callable -associated with the ``constant`` function. The ``constant`` function is a built-in Twig -function, and it is simply mapped to the PHP ``constant()`` function. After -compilation, the generated PHP code is roughly equivalent to: - -.. code-block:: html+php - - <?php echo constant('DATE_W3C') ?> - -Adding a function is similar to adding a filter. This can be done by calling the -``addFunction()`` method on the ``Twig_Environment`` instance:: - - $twig = new Twig_Environment($loader); - $twig->addFunction('functionName', new Twig_Function_Function('someFunction')); - -You can also expose extension methods as functions in your templates:: - - // $this is an object that implements Twig_ExtensionInterface. $twig = new Twig_Environment($loader); - $twig->addFunction('otherFunction', new Twig_Function_Method($this, 'someMethod')); - -Functions also support ``needs_environment`` and ``is_safe`` parameters. - -Dynamic Functions -~~~~~~~~~~~~~~~~~ - -.. versionadded:: 1.5 - Dynamic functions support was added in Twig 1.5. - -A function name containing the special ``*`` character is a dynamic function -as the ``*`` can be any string:: - - $twig->addFunction('*_path', new Twig_Function_Function('twig_path')); - - function twig_path($name, $arguments) - { + $function = new Twig_SimpleFunction('function_name', function () { // ... - } + }); + $twig->addFunction($function); -The following functions will be matched by the above defined dynamic function: +Functions support the same features as filters, except for the ``pre_escape`` +and ``preserves_safety`` options. -* ``product_path`` -* ``category_path`` - -A dynamic function can define more than one dynamic parts:: +Tests +----- - $twig->addFilter('*_path_*', new Twig_Filter_Function('twig_path')); +Tests are defined in the exact same way as filters and functions, but you need +to create an instance of ``Twig_SimpleTest``:: - function twig_path($name, $suffix, $arguments) - { + $twig = new Twig_Environment($loader); + $test = new Twig_SimpleTest('test_name', function () { // ... - } + }); + $twig->addTest($test); -The function will receive all dynamic part values before the normal functions -arguments. For instance, a call to ``a_path_b('foo')`` will result in the -following PHP call: ``twig_path('a', 'b', 'foo')``. +Tests do not support any options. Tags ---- @@ -517,7 +444,7 @@ to host all the specific tags and filters you want to add to Twig. .. tip:: When packaging your code into an extension, Twig is smart enough to - recompile your templates whenever you make a change to it (when the + recompile your templates whenever you make a change to it (when ``auto_reload`` is enabled). .. note:: @@ -663,7 +590,7 @@ method:: public function getFunctions() { return array( - 'lipsum' => new Twig_Function_Function('generate_lipsum'), + new Twig_SimpleFunction('lipsum', 'generate_lipsum'), ); } @@ -682,94 +609,13 @@ environment:: public function getFilters() { return array( - 'rot13' => new Twig_Filter_Function('str_rot13'), + new Twig_SimpleFilter('rot13', 'str_rot13'), ); } // ... } -As you can see in the above code, the ``getFilters()`` method returns an array -where keys are the name of the filters (``rot13``) and the values the -definition of the filter (``new Twig_Filter_Function('str_rot13')``). - -As seen in the previous chapter, you can also define filters as static methods -on the extension class:: - -$twig->addFilter('rot13', new Twig_Filter_Function('Project_Twig_Extension::rot13Filter')); - -You can also use ``Twig_Filter_Method`` instead of ``Twig_Filter_Function`` -when defining a filter to use a method:: - - class Project_Twig_Extension extends Twig_Extension - { - public function getFilters() - { - return array( - 'rot13' => new Twig_Filter_Method($this, 'rot13Filter'), - ); - } - - public function rot13Filter($string) - { - return str_rot13($string); - } - - // ... - } - -The first argument of the ``Twig_Filter_Method`` constructor is always -``$this``, the current extension object. The second one is the name of the -method to call. - -Using methods for filters is a great way to package your filter without -polluting the global namespace. This also gives the developer more flexibility -at the cost of a small overhead. - -Overriding default Filters -.......................... - -If some default core filters do not suit your needs, you can easily override -them by creating your own core extension. Of course, you don't need to copy -and paste the whole core extension code of Twig. Instead, you can just extends -it and override the filter(s) you want by overriding the ``getFilters()`` -method:: - - class MyCoreExtension extends Twig_Extension_Core - { - public function getFilters() - { - return array_merge(parent::getFilters(), array( - 'date' => new Twig_Filter_Method($this, 'dateFilter'), - // ... - )); - } - - public function dateFilter($timestamp, $format = 'F j, Y H:i') - { - return '...'.twig_date_format_filter($timestamp, $format); - } - - // ... - } - -Here, we override the ``date`` filter with a custom one. Using this new core -extension is as simple as registering the ``MyCoreExtension`` extension by -calling the ``addExtension()`` method on the environment instance:: - - $twig = new Twig_Environment($loader); - $twig->addExtension(new MyCoreExtension()); - -But I can already hear some people wondering how it can work as the Core -extension is loaded by default. That's true, but the trick is that both -extensions share the same unique identifier (``core`` - defined in the -``getName()`` method). By registering an extension with the same name as an -existing one, you have actually overridden the default one, even if it is -already registered:: - - $twig->addExtension(new Twig_Extension_Core()); - $twig->addExtension(new MyCoreExtension()); - Tags ~~~~ @@ -825,19 +671,59 @@ The ``getTests()`` methods allows to add new test functions:: public function getTests() { return array( - 'even' => new Twig_Test_Function('twig_test_even'), + new Twig_SimpleTest('even', 'twig_test_even'), ); } // ... } +Overloading +----------- + +To overload an already defined filter, test, operator, global variable, or +function, define it again **as late as possible**:: + + $twig = new Twig_Environment($loader); + $twig->addFilter(new Twig_SimpleFilter('date', function ($timestamp, $format = 'F j, Y H:i') { + // do something different from the built-in date filter + })); + +Here, we have overloaded the built-in ``date`` filter with a custom one. + +That also works with an extension:: + + class MyCoreExtension extends Twig_Extension + { + public function getFilters() + { + return array( + new Twig_SimpleFilter('date', array($this, 'dateFilter')), + ); + } + + public function dateFilter($timestamp, $format = 'F j, Y H:i') + { + // do something different from the built-in date filter + } + + public function getName() + { + return 'project'; + } + } + + $twig = new Twig_Environment($loader); + $twig->addExtension(new MyCoreExtension()); + +.. caution:: + + Note that overloading the built-in Twig elements is not recommended as it + might be confusing. + Testing an Extension -------------------- -.. versionadded:: 1.10 - Support for functional tests was added in Twig 1.10. - Functional Tests ~~~~~~~~~~~~~~~~ diff --git a/core/vendor/twig/twig/doc/advanced_legacy.rst b/core/vendor/twig/twig/doc/advanced_legacy.rst new file mode 100644 index 000000000000..8dbc52519b60 --- /dev/null +++ b/core/vendor/twig/twig/doc/advanced_legacy.rst @@ -0,0 +1,887 @@ +Extending Twig +============== + +.. caution:: + + This section describes how to extends Twig for versions **older than + 1.12**. If you are using a newer version, read the :doc:`newer<advanced>` + chapter instead. + +Twig can be extended in many ways; you can add extra tags, filters, tests, +operators, global variables, and functions. You can even extend the parser +itself with node visitors. + +.. note:: + + The first section of this chapter describes how to extend Twig easily. If + you want to reuse your changes in different projects or if you want to + share them with others, you should then create an extension as described + in the following section. + +.. caution:: + + When extending Twig by calling methods on the Twig environment instance, + Twig won't be able to recompile your templates when the PHP code is + updated. To see your changes in real-time, either disable template caching + or package your code into an extension (see the next section of this + chapter). + +Before extending Twig, you must understand the differences between all the +different possible extension points and when to use them. + +First, remember that Twig has two main language constructs: + +* ``{{ }}``: used to print the result of an expression evaluation; + +* ``{% %}``: used to execute statements. + +To understand why Twig exposes so many extension points, let's see how to +implement a *Lorem ipsum* generator (it needs to know the number of words to +generate). + +You can use a ``lipsum`` *tag*: + +.. code-block:: jinja + + {% lipsum 40 %} + +That works, but using a tag for ``lipsum`` is not a good idea for at least +three main reasons: + +* ``lipsum`` is not a language construct; +* The tag outputs something; +* The tag is not flexible as you cannot use it in an expression: + + .. code-block:: jinja + + {{ 'some text' ~ {% lipsum 40 %} ~ 'some more text' }} + +In fact, you rarely need to create tags; and that's good news because tags are +the most complex extension point of Twig. + +Now, let's use a ``lipsum`` *filter*: + +.. code-block:: jinja + + {{ 40|lipsum }} + +Again, it works, but it looks weird. A filter transforms the passed value to +something else but here we use the value to indicate the number of words to +generate (so, ``40`` is an argument of the filter, not the value we want to +transform). + +Next, let's use a ``lipsum`` *function*: + +.. code-block:: jinja + + {{ lipsum(40) }} + +Here we go. For this specific example, the creation of a function is the +extension point to use. And you can use it anywhere an expression is accepted: + +.. code-block:: jinja + + {{ 'some text' ~ ipsum(40) ~ 'some more text' }} + + {% set ipsum = ipsum(40) %} + +Last but not the least, you can also use a *global* object with a method able +to generate lorem ipsum text: + +.. code-block:: jinja + + {{ text.lipsum(40) }} + +As a rule of thumb, use functions for frequently used features and global +objects for everything else. + +Keep in mind the following when you want to extend Twig: + +========== ========================== ========== ========================= +What? Implementation difficulty? How often? When? +========== ========================== ========== ========================= +*macro* trivial frequent Content generation +*global* trivial frequent Helper object +*function* trivial frequent Content generation +*filter* trivial frequent Value transformation +*tag* complex rare DSL language construct +*test* trivial rare Boolean decision +*operator* trivial rare Values transformation +========== ========================== ========== ========================= + +Globals +------- + +A global variable is like any other template variable, except that it's +available in all templates and macros:: + + $twig = new Twig_Environment($loader); + $twig->addGlobal('text', new Text()); + +You can then use the ``text`` variable anywhere in a template: + +.. code-block:: jinja + + {{ text.lipsum(40) }} + +Filters +------- + +A filter is a regular PHP function or an object method that takes the left +side of the filter (before the pipe ``|``) as first argument and the extra +arguments passed to the filter (within parentheses ``()``) as extra arguments. + +Defining a filter is as easy as associating the filter name with a PHP +callable. For instance, let's say you have the following code in a template: + +.. code-block:: jinja + + {{ 'TWIG'|lower }} + +When compiling this template to PHP, Twig looks for the PHP callable +associated with the ``lower`` filter. The ``lower`` filter is a built-in Twig +filter, and it is simply mapped to the PHP ``strtolower()`` function. After +compilation, the generated PHP code is roughly equivalent to: + +.. code-block:: html+php + + <?php echo strtolower('TWIG') ?> + +As you can see, the ``'TWIG'`` string is passed as a first argument to the PHP +function. + +A filter can also take extra arguments like in the following example: + +.. code-block:: jinja + + {{ now|date('d/m/Y') }} + +In this case, the extra arguments are passed to the function after the main +argument, and the compiled code is equivalent to: + +.. code-block:: html+php + + <?php echo twig_date_format_filter($now, 'd/m/Y') ?> + +Let's see how to create a new filter. + +In this section, we will create a ``rot13`` filter, which should return the +`rot13`_ transformation of a string. Here is an example of its usage and the +expected output: + +.. code-block:: jinja + + {{ "Twig"|rot13 }} + + {# should displays Gjvt #} + +Adding a filter is as simple as calling the ``addFilter()`` method on the +``Twig_Environment`` instance:: + + $twig = new Twig_Environment($loader); + $twig->addFilter('rot13', new Twig_Filter_Function('str_rot13')); + +The second argument of ``addFilter()`` is an instance of ``Twig_Filter``. +Here, we use ``Twig_Filter_Function`` as the filter is a PHP function. The +first argument passed to the ``Twig_Filter_Function`` constructor is the name +of the PHP function to call, here ``str_rot13``, a native PHP function. + +Let's say I now want to be able to add a prefix before the converted string: + +.. code-block:: jinja + + {{ "Twig"|rot13('prefix_') }} + + {# should displays prefix_Gjvt #} + +As the PHP ``str_rot13()`` function does not support this requirement, let's +create a new PHP function:: + + function project_compute_rot13($string, $prefix = '') + { + return $prefix.str_rot13($string); + } + +As you can see, the ``prefix`` argument of the filter is passed as an extra +argument to the ``project_compute_rot13()`` function. + +Adding this filter is as easy as before:: + + $twig->addFilter('rot13', new Twig_Filter_Function('project_compute_rot13')); + +For better encapsulation, a filter can also be defined as a static method of a +class. The ``Twig_Filter_Function`` class can also be used to register such +static methods as filters:: + + $twig->addFilter('rot13', new Twig_Filter_Function('SomeClass::rot13Filter')); + +.. tip:: + + In an extension, you can also define a filter as a static method of the + extension class. + +Environment aware Filters +~~~~~~~~~~~~~~~~~~~~~~~~~ + +The ``Twig_Filter`` classes take options as their last argument. For instance, +if you want access to the current environment instance in your filter, set the +``needs_environment`` option to ``true``:: + + $filter = new Twig_Filter_Function('str_rot13', array('needs_environment' => true)); + +Twig will then pass the current environment as the first argument to the +filter call:: + + function twig_compute_rot13(Twig_Environment $env, $string) + { + // get the current charset for instance + $charset = $env->getCharset(); + + return str_rot13($string); + } + +Automatic Escaping +~~~~~~~~~~~~~~~~~~ + +If automatic escaping is enabled, the output of the filter may be escaped +before printing. If your filter acts as an escaper (or explicitly outputs html +or javascript code), you will want the raw output to be printed. In such a +case, set the ``is_safe`` option:: + + $filter = new Twig_Filter_Function('nl2br', array('is_safe' => array('html'))); + +Some filters may need to work on input that is already escaped or safe, for +example when adding (safe) html tags to originally unsafe output. In such a +case, set the ``pre_escape`` option to escape the input data before it is run +through your filter:: + + $filter = new Twig_Filter_Function('somefilter', array('pre_escape' => 'html', 'is_safe' => array('html'))); + +Dynamic Filters +~~~~~~~~~~~~~~~ + +.. versionadded:: 1.5 + Dynamic filters support was added in Twig 1.5. + +A filter name containing the special ``*`` character is a dynamic filter as +the ``*`` can be any string:: + + $twig->addFilter('*_path', new Twig_Filter_Function('twig_path')); + + function twig_path($name, $arguments) + { + // ... + } + +The following filters will be matched by the above defined dynamic filter: + +* ``product_path`` +* ``category_path`` + +A dynamic filter can define more than one dynamic parts:: + + $twig->addFilter('*_path_*', new Twig_Filter_Function('twig_path')); + + function twig_path($name, $suffix, $arguments) + { + // ... + } + +The filter will receive all dynamic part values before the normal filters +arguments. For instance, a call to ``'foo'|a_path_b()`` will result in the +following PHP call: ``twig_path('a', 'b', 'foo')``. + +Functions +--------- + +A function is a regular PHP function or an object method that can be called from +templates. + +.. code-block:: jinja + + {{ constant("DATE_W3C") }} + +When compiling this template to PHP, Twig looks for the PHP callable +associated with the ``constant`` function. The ``constant`` function is a built-in Twig +function, and it is simply mapped to the PHP ``constant()`` function. After +compilation, the generated PHP code is roughly equivalent to: + +.. code-block:: html+php + + <?php echo constant('DATE_W3C') ?> + +Adding a function is similar to adding a filter. This can be done by calling the +``addFunction()`` method on the ``Twig_Environment`` instance:: + + $twig = new Twig_Environment($loader); + $twig->addFunction('functionName', new Twig_Function_Function('someFunction')); + +You can also expose extension methods as functions in your templates:: + + // $this is an object that implements Twig_ExtensionInterface. + $twig = new Twig_Environment($loader); + $twig->addFunction('otherFunction', new Twig_Function_Method($this, 'someMethod')); + +Functions also support ``needs_environment`` and ``is_safe`` parameters. + +Dynamic Functions +~~~~~~~~~~~~~~~~~ + +.. versionadded:: 1.5 + Dynamic functions support was added in Twig 1.5. + +A function name containing the special ``*`` character is a dynamic function +as the ``*`` can be any string:: + + $twig->addFunction('*_path', new Twig_Function_Function('twig_path')); + + function twig_path($name, $arguments) + { + // ... + } + +The following functions will be matched by the above defined dynamic function: + +* ``product_path`` +* ``category_path`` + +A dynamic function can define more than one dynamic parts:: + + $twig->addFilter('*_path_*', new Twig_Filter_Function('twig_path')); + + function twig_path($name, $suffix, $arguments) + { + // ... + } + +The function will receive all dynamic part values before the normal functions +arguments. For instance, a call to ``a_path_b('foo')`` will result in the +following PHP call: ``twig_path('a', 'b', 'foo')``. + +Tags +---- + +One of the most exciting feature of a template engine like Twig is the +possibility to define new language constructs. This is also the most complex +feature as you need to understand how Twig's internals work. + +Let's create a simple ``set`` tag that allows the definition of simple +variables from within a template. The tag can be used like follows: + +.. code-block:: jinja + + {% set name = "value" %} + + {{ name }} + + {# should output value #} + +.. note:: + + The ``set`` tag is part of the Core extension and as such is always + available. The built-in version is slightly more powerful and supports + multiple assignments by default (cf. the template designers chapter for + more information). + +Three steps are needed to define a new tag: + +* Defining a Token Parser class (responsible for parsing the template code); + +* Defining a Node class (responsible for converting the parsed code to PHP); + +* Registering the tag. + +Registering a new tag +~~~~~~~~~~~~~~~~~~~~~ + +Adding a tag is as simple as calling the ``addTokenParser`` method on the +``Twig_Environment`` instance:: + + $twig = new Twig_Environment($loader); + $twig->addTokenParser(new Project_Set_TokenParser()); + +Defining a Token Parser +~~~~~~~~~~~~~~~~~~~~~~~ + +Now, let's see the actual code of this class:: + + class Project_Set_TokenParser extends Twig_TokenParser + { + public function parse(Twig_Token $token) + { + $lineno = $token->getLine(); + $name = $this->parser->getStream()->expect(Twig_Token::NAME_TYPE)->getValue(); + $this->parser->getStream()->expect(Twig_Token::OPERATOR_TYPE, '='); + $value = $this->parser->getExpressionParser()->parseExpression(); + + $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE); + + return new Project_Set_Node($name, $value, $lineno, $this->getTag()); + } + + public function getTag() + { + return 'set'; + } + } + +The ``getTag()`` method must return the tag we want to parse, here ``set``. + +The ``parse()`` method is invoked whenever the parser encounters a ``set`` +tag. It should return a ``Twig_Node`` instance that represents the node (the +``Project_Set_Node`` calls creating is explained in the next section). + +The parsing process is simplified thanks to a bunch of methods you can call +from the token stream (``$this->parser->getStream()``): + +* ``getCurrent()``: Gets the current token in the stream. + +* ``next()``: Moves to the next token in the stream, *but returns the old one*. + +* ``test($type)``, ``test($value)`` or ``test($type, $value)``: Determines whether + the current token is of a particular type or value (or both). The value may be an + array of several possible values. + +* ``expect($type[, $value[, $message]])``: If the current token isn't of the given + type/value a syntax error is thrown. Otherwise, if the type and value are correct, + the token is returned and the stream moves to the next token. + +* ``look()``: Looks a the next token without consuming it. + +Parsing expressions is done by calling the ``parseExpression()`` like we did for +the ``set`` tag. + +.. tip:: + + Reading the existing ``TokenParser`` classes is the best way to learn all + the nitty-gritty details of the parsing process. + +Defining a Node +~~~~~~~~~~~~~~~ + +The ``Project_Set_Node`` class itself is rather simple:: + + class Project_Set_Node extends Twig_Node + { + public function __construct($name, Twig_Node_Expression $value, $lineno, $tag = null) + { + parent::__construct(array('value' => $value), array('name' => $name), $lineno, $tag); + } + + public function compile(Twig_Compiler $compiler) + { + $compiler + ->addDebugInfo($this) + ->write('$context[\''.$this->getAttribute('name').'\'] = ') + ->subcompile($this->getNode('value')) + ->raw(";\n") + ; + } + } + +The compiler implements a fluid interface and provides methods that helps the +developer generate beautiful and readable PHP code: + +* ``subcompile()``: Compiles a node. + +* ``raw()``: Writes the given string as is. + +* ``write()``: Writes the given string by adding indentation at the beginning + of each line. + +* ``string()``: Writes a quoted string. + +* ``repr()``: Writes a PHP representation of a given value (see + ``Twig_Node_For`` for a usage example). + +* ``addDebugInfo()``: Adds the line of the original template file related to + the current node as a comment. + +* ``indent()``: Indents the generated code (see ``Twig_Node_Block`` for a + usage example). + +* ``outdent()``: Outdents the generated code (see ``Twig_Node_Block`` for a + usage example). + +.. _creating_extensions: + +Creating an Extension +--------------------- + +The main motivation for writing an extension is to move often used code into a +reusable class like adding support for internationalization. An extension can +define tags, filters, tests, operators, global variables, functions, and node +visitors. + +Creating an extension also makes for a better separation of code that is +executed at compilation time and code needed at runtime. As such, it makes +your code faster. + +Most of the time, it is useful to create a single extension for your project, +to host all the specific tags and filters you want to add to Twig. + +.. tip:: + + When packaging your code into an extension, Twig is smart enough to + recompile your templates whenever you make a change to it (when the + ``auto_reload`` is enabled). + +.. note:: + + Before writing your own extensions, have a look at the Twig official + extension repository: http://github.com/fabpot/Twig-extensions. + +An extension is a class that implements the following interface:: + + interface Twig_ExtensionInterface + { + /** + * Initializes the runtime environment. + * + * This is where you can load some file that contains filter functions for instance. + * + * @param Twig_Environment $environment The current Twig_Environment instance + */ + function initRuntime(Twig_Environment $environment); + + /** + * Returns the token parser instances to add to the existing list. + * + * @return array An array of Twig_TokenParserInterface or Twig_TokenParserBrokerInterface instances + */ + function getTokenParsers(); + + /** + * Returns the node visitor instances to add to the existing list. + * + * @return array An array of Twig_NodeVisitorInterface instances + */ + function getNodeVisitors(); + + /** + * Returns a list of filters to add to the existing list. + * + * @return array An array of filters + */ + function getFilters(); + + /** + * Returns a list of tests to add to the existing list. + * + * @return array An array of tests + */ + function getTests(); + + /** + * Returns a list of functions to add to the existing list. + * + * @return array An array of functions + */ + function getFunctions(); + + /** + * Returns a list of operators to add to the existing list. + * + * @return array An array of operators + */ + function getOperators(); + + /** + * Returns a list of global variables to add to the existing list. + * + * @return array An array of global variables + */ + function getGlobals(); + + /** + * Returns the name of the extension. + * + * @return string The extension name + */ + function getName(); + } + +To keep your extension class clean and lean, it can inherit from the built-in +``Twig_Extension`` class instead of implementing the whole interface. That +way, you just need to implement the ``getName()`` method as the +``Twig_Extension`` provides empty implementations for all other methods. + +The ``getName()`` method must return a unique identifier for your extension. + +Now, with this information in mind, let's create the most basic extension +possible:: + + class Project_Twig_Extension extends Twig_Extension + { + public function getName() + { + return 'project'; + } + } + +.. note:: + + Of course, this extension does nothing for now. We will customize it in + the next sections. + +Twig does not care where you save your extension on the filesystem, as all +extensions must be registered explicitly to be available in your templates. + +You can register an extension by using the ``addExtension()`` method on your +main ``Environment`` object:: + + $twig = new Twig_Environment($loader); + $twig->addExtension(new Project_Twig_Extension()); + +Of course, you need to first load the extension file by either using +``require_once()`` or by using an autoloader (see `spl_autoload_register()`_). + +.. tip:: + + The bundled extensions are great examples of how extensions work. + +Globals +~~~~~~~ + +Global variables can be registered in an extension via the ``getGlobals()`` +method:: + + class Project_Twig_Extension extends Twig_Extension + { + public function getGlobals() + { + return array( + 'text' => new Text(), + ); + } + + // ... + } + +Functions +~~~~~~~~~ + +Functions can be registered in an extension via the ``getFunctions()`` +method:: + + class Project_Twig_Extension extends Twig_Extension + { + public function getFunctions() + { + return array( + 'lipsum' => new Twig_Function_Function('generate_lipsum'), + ); + } + + // ... + } + +Filters +~~~~~~~ + +To add a filter to an extension, you need to override the ``getFilters()`` +method. This method must return an array of filters to add to the Twig +environment:: + + class Project_Twig_Extension extends Twig_Extension + { + public function getFilters() + { + return array( + 'rot13' => new Twig_Filter_Function('str_rot13'), + ); + } + + // ... + } + +As you can see in the above code, the ``getFilters()`` method returns an array +where keys are the name of the filters (``rot13``) and the values the +definition of the filter (``new Twig_Filter_Function('str_rot13')``). + +As seen in the previous chapter, you can also define filters as static methods +on the extension class:: + +$twig->addFilter('rot13', new Twig_Filter_Function('Project_Twig_Extension::rot13Filter')); + +You can also use ``Twig_Filter_Method`` instead of ``Twig_Filter_Function`` +when defining a filter to use a method:: + + class Project_Twig_Extension extends Twig_Extension + { + public function getFilters() + { + return array( + 'rot13' => new Twig_Filter_Method($this, 'rot13Filter'), + ); + } + + public function rot13Filter($string) + { + return str_rot13($string); + } + + // ... + } + +The first argument of the ``Twig_Filter_Method`` constructor is always +``$this``, the current extension object. The second one is the name of the +method to call. + +Using methods for filters is a great way to package your filter without +polluting the global namespace. This also gives the developer more flexibility +at the cost of a small overhead. + +Overriding default Filters +.......................... + +If some default core filters do not suit your needs, you can easily override +them by creating your own extension. Just use the same names as the one you +want to override:: + + class MyCoreExtension extends Twig_Extension + { + public function getFilters() + { + return array( + 'date' => new Twig_Filter_Method($this, 'dateFilter'), + // ... + ); + } + + public function dateFilter($timestamp, $format = 'F j, Y H:i') + { + return '...'.twig_date_format_filter($timestamp, $format); + } + + public function getName() + { + return 'project'; + } + } + +Here, we override the ``date`` filter with a custom one. Using this extension +is as simple as registering the ``MyCoreExtension`` extension by calling the +``addExtension()`` method on the environment instance:: + + $twig = new Twig_Environment($loader); + $twig->addExtension(new MyCoreExtension()); + +Tags +~~~~ + +Adding a tag in an extension can be done by overriding the +``getTokenParsers()`` method. This method must return an array of tags to add +to the Twig environment:: + + class Project_Twig_Extension extends Twig_Extension + { + public function getTokenParsers() + { + return array(new Project_Set_TokenParser()); + } + + // ... + } + +In the above code, we have added a single new tag, defined by the +``Project_Set_TokenParser`` class. The ``Project_Set_TokenParser`` class is +responsible for parsing the tag and compiling it to PHP. + +Operators +~~~~~~~~~ + +The ``getOperators()`` methods allows to add new operators. Here is how to add +``!``, ``||``, and ``&&`` operators:: + + class Project_Twig_Extension extends Twig_Extension + { + public function getOperators() + { + return array( + array( + '!' => array('precedence' => 50, 'class' => 'Twig_Node_Expression_Unary_Not'), + ), + array( + '||' => array('precedence' => 10, 'class' => 'Twig_Node_Expression_Binary_Or', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), + '&&' => array('precedence' => 15, 'class' => 'Twig_Node_Expression_Binary_And', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), + ), + ); + } + + // ... + } + +Tests +~~~~~ + +The ``getTests()`` methods allows to add new test functions:: + + class Project_Twig_Extension extends Twig_Extension + { + public function getTests() + { + return array( + 'even' => new Twig_Test_Function('twig_test_even'), + ); + } + + // ... + } + +Testing an Extension +-------------------- + +.. versionadded:: 1.10 + Support for functional tests was added in Twig 1.10. + +Functional Tests +~~~~~~~~~~~~~~~~ + +You can create functional tests for extensions simply by creating the +following file structure in your test directory:: + + Fixtures/ + filters/ + foo.test + bar.test + functions/ + foo.test + bar.test + tags/ + foo.test + bar.test + IntegrationTest.php + +The ``IntegrationTest.php`` file should look like this:: + + class Project_Tests_IntegrationTest extends Twig_Test_IntegrationTestCase + { + public function getExtensions() + { + return array( + new Project_Twig_Extension1(), + new Project_Twig_Extension2(), + ); + } + + public function getFixturesDir() + { + return dirname(__FILE__).'/Fixtures/'; + } + } + +Fixtures examples can be found within the Twig repository +`tests/Twig/Fixtures`_ directory. + +Node Tests +~~~~~~~~~~ + +Testing the node visitors can be complex, so extend your test cases from +``Twig_Test_NodeTestCase``. Examples can be found in the Twig repository +`tests/Twig/Node`_ directory. + +.. _`spl_autoload_register()`: http://www.php.net/spl_autoload_register +.. _`rot13`: http://www.php.net/manual/en/function.str-rot13.php +.. _`tests/Twig/Fixtures`: https://github.com/fabpot/Twig/tree/master/test/Twig/Tests/Fixtures +.. _`tests/Twig/Node`: https://github.com/fabpot/Twig/tree/master/test/Twig/Tests/Node diff --git a/core/vendor/twig/twig/doc/api.rst b/core/vendor/twig/twig/doc/api.rst index fbcc8bc74e19..9160c3f32a3f 100644 --- a/core/vendor/twig/twig/doc/api.rst +++ b/core/vendor/twig/twig/doc/api.rst @@ -317,10 +317,7 @@ Twig comes bundled with the following extensions: * *Twig_Extension_Optimizer*: Optimizers the node tree before compilation. The core, escaper, and optimizer extensions do not need to be added to the -Twig environment, as they are registered by default. You can disable an -already registered extension:: - - $twig->removeExtension('escaper'); +Twig environment, as they are registered by default. Built-in Extensions ------------------- @@ -354,7 +351,7 @@ The ``core`` extension defines all the core features of Twig: * ``do`` * ``embed`` * ``flush`` - * ``raw`` + * ``verbatim`` * ``sandbox`` * ``use`` diff --git a/core/vendor/twig/twig/doc/deprecated.rst b/core/vendor/twig/twig/doc/deprecated.rst new file mode 100644 index 000000000000..f0a3a0f0ef4c --- /dev/null +++ b/core/vendor/twig/twig/doc/deprecated.rst @@ -0,0 +1,98 @@ +Deprecated Features +=================== + +This document lists all deprecated features in Twig. Deprecated features are +kept for backward compatibility and removed in the next major release (a +feature that was deprecated in Twig 1.x is removed in Twig 2.0). + +Token Parsers +------------- + +* As of Twig 1.x, the token parser broker sub-system is deprecated. The + following class and interface will be removed in 2.0: + + * ``Twig_TokenParserBrokerInterface`` + * ``Twig_TokenParserBroker`` + +Extensions +---------- + +* As of Twig 1.x, the ability to remove an extension is deprecated and the + ``Twig_Environment::removeExtension()`` method will be removed in 2.0. + +PEAR +---- + +PEAR support will be discontinued in Twig 2.0, and no PEAR packages will be +provided. Use Composer instead. + +Filters +------- + +* As of Twig 1.x, use ``Twig_SimpleFilter`` to add a filter. The following + classes and interfaces will be removed in 2.0: + + * ``Twig_FilterInterface`` + * ``Twig_FilterCallableInterface`` + * ``Twig_Filter`` + * ``Twig_Filter_Function`` + * ``Twig_Filter_Method`` + * ``Twig_Filter_Node`` + +* As of Twig 2.x, the ``Twig_SimpleFilter`` class is deprecated and will be + removed in Twig 3.x (use ``Twig_Filter`` instead). In Twig 2.x, + ``Twig_SimpleFilter`` is just an alias for ``Twig_Filter``. + +Functions +--------- + +* As of Twig 1.x, use ``Twig_SimpleFunction`` to add a function. The following + classes and interfaces will be removed in 2.0: + + * ``Twig_FunctionInterface`` + * ``Twig_FunctionCallableInterface`` + * ``Twig_Function`` + * ``Twig_Function_Function`` + * ``Twig_Function_Method`` + * ``Twig_Function_Node`` + +* As of Twig 2.x, the ``Twig_SimpleFunction`` class is deprecated and will be + removed in Twig 3.x (use ``Twig_Function`` instead). In Twig 2.x, + ``Twig_SimpleFunction`` is just an alias for ``Twig_Function``. + +Tests +----- + +* As of Twig 1.x, use ``Twig_SimpleTest`` to add a test. The following classes + and interfaces will be removed in 2.0: + + * ``Twig_TestInterface`` + * ``Twig_TestCallableInterface`` + * ``Twig_Test`` + * ``Twig_Test_Function`` + * ``Twig_Test_Method`` + * ``Twig_Test_Node`` + +* As of Twig 2.x, the ``Twig_SimpleTest`` class is deprecated and will be + removed in Twig 3.x (use ``Twig_Test`` instead). In Twig 2.x, + ``Twig_SimpleTest`` is just an alias for ``Twig_Test``. + +Interfaces +---------- + +* As of Twig 2.x, the following interfaces are deprecated and empty (they will + be removed in Twig 3.0): + +* ``Twig_CompilerInterface`` (use ``Twig_Compiler`` instead) +* ``Twig_LexerInterface`` (use ``Twig_Lexer`` instead) +* ``Twig_NodeInterface`` (use ``Twig_Node`` instead) +* ``Twig_ParserInterface`` (use ``Twig_Parser`` instead) +* ``Twig_ExistsLoaderInterface`` (merged with ``Twig_LoaderInterface``) +* ``Twig_TemplateInterface`` (use ``Twig_Template`` instead) + +Globals +------- + +* As of Twig 2.x, the ability to register a global variable after the runtime + or the extensions have been initialized is not possible anymore (but + changing the value of an already registered global is possible). diff --git a/core/vendor/twig/twig/doc/filters/convert_encoding.rst b/core/vendor/twig/twig/doc/filters/convert_encoding.rst index 2febab2ff7e9..1b0eb60c3ab4 100644 --- a/core/vendor/twig/twig/doc/filters/convert_encoding.rst +++ b/core/vendor/twig/twig/doc/filters/convert_encoding.rst @@ -18,5 +18,11 @@ is the input charset: them must be installed. In case both are installed, `mbstring`_ is used by default (Twig before 1.8.1 uses `iconv`_ by default). +Arguments +--------- + + * ``from``: The input charset + * ``to``: The output charset + .. _`iconv`: http://php.net/iconv .. _`mbstring`: http://php.net/mbstring diff --git a/core/vendor/twig/twig/doc/filters/date.rst b/core/vendor/twig/twig/doc/filters/date.rst index 39ad732c181e..8e2f31faab91 100644 --- a/core/vendor/twig/twig/doc/filters/date.rst +++ b/core/vendor/twig/twig/doc/filters/date.rst @@ -77,6 +77,12 @@ The default timezone can also be set globally by calling ``setTimezone()``: $twig = new Twig_Environment($loader); $twig->getExtension('core')->setTimezone('Europe/Paris'); +Arguments +--------- + + * ``format``: The date format + * ``timezone``: The date timezone + .. _`strtotime`: http://www.php.net/strtotime .. _`DateTime`: http://www.php.net/DateTime .. _`DateInterval`: http://www.php.net/DateInterval diff --git a/core/vendor/twig/twig/doc/filters/date_modify.rst b/core/vendor/twig/twig/doc/filters/date_modify.rst index ae12c52975e0..6a5c73d6bb20 100644 --- a/core/vendor/twig/twig/doc/filters/date_modify.rst +++ b/core/vendor/twig/twig/doc/filters/date_modify.rst @@ -14,5 +14,10 @@ The ``date_modify`` filter accepts strings (it must be in a format supported by the `strtotime`_ function) or `DateTime`_ instances. You can easily combine it with the :doc:`date<date>` filter for formatting. +Arguments +--------- + + * ``modifier``: The modifier + .. _`strtotime`: http://www.php.net/strtotime .. _`DateTime`: http://www.php.net/DateTime diff --git a/core/vendor/twig/twig/doc/filters/default.rst b/core/vendor/twig/twig/doc/filters/default.rst index 4055ead81f71..46ed9636750d 100644 --- a/core/vendor/twig/twig/doc/filters/default.rst +++ b/core/vendor/twig/twig/doc/filters/default.rst @@ -26,3 +26,8 @@ undefined: Read the documentation for the :doc:`defined<../tests/defined>` and :doc:`empty<../tests/empty>` tests to learn more about their semantics. + +Arguments +--------- + + * ``default``: The default value diff --git a/core/vendor/twig/twig/doc/filters/escape.rst b/core/vendor/twig/twig/doc/filters/escape.rst index ddb2bbba0186..5ade7d7484a7 100644 --- a/core/vendor/twig/twig/doc/filters/escape.rst +++ b/core/vendor/twig/twig/doc/filters/escape.rst @@ -74,7 +74,7 @@ The ``escape`` filter supports the following escaping strategies: {% endautoescape %} When using a variable as the escaping strategy, you should disable - automatic escaping:: + automatic escaping: .. code-block:: jinja @@ -84,4 +84,10 @@ The ``escape`` filter supports the following escaping strategies: {{ var|escape(strategy)|raw }} {# won't be double-escaped #} {% endautoescape %} +Arguments +--------- + + * ``strategy``: The escaping strategy + * ``charset``: The string charset + .. _`htmlspecialchars`: http://php.net/htmlspecialchars diff --git a/core/vendor/twig/twig/doc/filters/join.rst b/core/vendor/twig/twig/doc/filters/join.rst index eec20454b024..f49524217698 100644 --- a/core/vendor/twig/twig/doc/filters/join.rst +++ b/core/vendor/twig/twig/doc/filters/join.rst @@ -16,3 +16,8 @@ define it with the optional first parameter: {{ [1, 2, 3]|join('|') }} {# returns 1|2|3 #} + +Arguments +--------- + + * ``glue``: The separator diff --git a/core/vendor/twig/twig/doc/filters/json_encode.rst b/core/vendor/twig/twig/doc/filters/json_encode.rst index c7d19b39f11a..374f51980d38 100644 --- a/core/vendor/twig/twig/doc/filters/json_encode.rst +++ b/core/vendor/twig/twig/doc/filters/json_encode.rst @@ -11,4 +11,9 @@ The ``json_encode`` filter returns the JSON representation of a string: Internally, Twig uses the PHP `json_encode`_ function. +Arguments +--------- + + * ``options``: The options + .. _`json_encode`: http://php.net/json_encode diff --git a/core/vendor/twig/twig/doc/filters/number_format.rst b/core/vendor/twig/twig/doc/filters/number_format.rst index b591b1e56bad..fedacd9d7d89 100644 --- a/core/vendor/twig/twig/doc/filters/number_format.rst +++ b/core/vendor/twig/twig/doc/filters/number_format.rst @@ -35,4 +35,11 @@ These defaults can be easily changed through the core extension: The defaults set for ``number_format`` can be over-ridden upon each call using the additional parameters. +Arguments +--------- + + * ``decimal``: The number of decimal points to display + * ``decimal_point``: The character(s) to use for the decimal point + * ``decimal_sep``: The character(s) to use for the thousands separator + .. _`number_format`: http://php.net/number_format diff --git a/core/vendor/twig/twig/doc/filters/replace.rst b/core/vendor/twig/twig/doc/filters/replace.rst index cc603fa37351..e961f23d49b6 100644 --- a/core/vendor/twig/twig/doc/filters/replace.rst +++ b/core/vendor/twig/twig/doc/filters/replace.rst @@ -11,4 +11,9 @@ The ``replace`` filter formats a given string by replacing the placeholders {# returns I like foo and bar if the foo parameter equals to the foo string. #} +Arguments +--------- + + * ``replace_pairs``: The placeholder values + .. seealso:: :doc:`format<format>` diff --git a/core/vendor/twig/twig/doc/filters/slice.rst b/core/vendor/twig/twig/doc/filters/slice.rst index 80a4293d8418..7a9ada0256df 100644 --- a/core/vendor/twig/twig/doc/filters/slice.rst +++ b/core/vendor/twig/twig/doc/filters/slice.rst @@ -34,6 +34,12 @@ As syntactic sugar, you can also use the ``[]`` notation: {{ '1234'[1:2] }} + {# you can omit the first argument -- which is the same as 0 #} + {{ '1234'[:2] }} {# will display "12" #} + + {# you can omit the last argument -- which will select everything till the end #} + {{ '1234'[2:] }} {# will display "34 #} + The ``slice`` filter works as the `array_slice`_ PHP function for arrays and `substr`_ for strings. @@ -52,6 +58,13 @@ up until the end of the variable. It also works with objects implementing the `Traversable`_ interface. +Arguments +--------- + + * ``start``: The start of the slice + * ``length``: The size of the slice + * ``preserve_keys``: Whether to preserve key or not (when the input is an array) + .. _`Traversable`: http://php.net/manual/en/class.traversable.php .. _`array_slice`: http://php.net/array_slice .. _`substr`: http://php.net/substr diff --git a/core/vendor/twig/twig/doc/filters/split.rst b/core/vendor/twig/twig/doc/filters/split.rst index 9b9e4e65bdf0..7cd2ca5b8047 100644 --- a/core/vendor/twig/twig/doc/filters/split.rst +++ b/core/vendor/twig/twig/doc/filters/split.rst @@ -25,7 +25,7 @@ You can also pass a ``limit`` argument: .. code-block:: jinja {{ "one,two,three,four,five"|split(',', 3) }} - {# returns [one, two, "three,four,five"] #} + {# returns ['one', 'two', 'three,four,five'] #} If the ``delimiter`` is an empty string, then value will be split by equal chunks. Length is set by the ``limit`` argument (one character by default). @@ -33,15 +33,21 @@ chunks. Length is set by the ``limit`` argument (one character by default). .. code-block:: jinja {{ "123"|split('') }} - {# returns [1, 2, 3] #} + {# returns ['1', '2', '3'] #} {{ "aabbcc"|split('', 2) }} - {# returns [aa, bb, cc] #} + {# returns ['aa', 'bb', 'cc'] #} .. note:: Internally, Twig uses the PHP `explode`_ or `str_split`_ (if delimiter is empty) functions for string splitting. +Arguments +--------- + + * ``delimiter``: The delimiter + * ``limit``: The limit argument + .. _`explode`: http://php.net/explode .. _`str_split`: http://php.net/str_split diff --git a/core/vendor/twig/twig/doc/filters/trim.rst b/core/vendor/twig/twig/doc/filters/trim.rst index f1215f6ecdc9..f38afd55ad60 100644 --- a/core/vendor/twig/twig/doc/filters/trim.rst +++ b/core/vendor/twig/twig/doc/filters/trim.rst @@ -21,4 +21,9 @@ and end of a string: Internally, Twig uses the PHP `trim`_ function. +Arguments +--------- + + * ``character_mask``: The characters to strip + .. _`trim`: http://php.net/trim diff --git a/core/vendor/twig/twig/doc/functions/constant.rst b/core/vendor/twig/twig/doc/functions/constant.rst index 5b247b382b08..bea0e9fc0b3b 100644 --- a/core/vendor/twig/twig/doc/functions/constant.rst +++ b/core/vendor/twig/twig/doc/functions/constant.rst @@ -1,9 +1,18 @@ ``constant`` ============ +.. versionadded: 1.12.1 + constant now accepts object instances as the second argument. + ``constant`` returns the constant value for a given string: .. code-block:: jinja {{ some_date|date(constant('DATE_W3C')) }} {{ constant('Namespace\\Classname::CONSTANT_NAME') }} + +As of 1.12.1 you can read constants from object instances as well: + +.. code-block:: jinja + + {{ constant('RSS', date) }} diff --git a/core/vendor/twig/twig/doc/functions/cycle.rst b/core/vendor/twig/twig/doc/functions/cycle.rst index fe11d68e4969..0015cae1f9ad 100644 --- a/core/vendor/twig/twig/doc/functions/cycle.rst +++ b/core/vendor/twig/twig/doc/functions/cycle.rst @@ -18,3 +18,8 @@ The array can contain any number of values: {% for i in 0..10 %} {{ cycle(fruits, i) }} {% endfor %} + +Arguments +--------- + + * ``position``: The cycle position diff --git a/core/vendor/twig/twig/doc/functions/date.rst b/core/vendor/twig/twig/doc/functions/date.rst index c1a011c3f46c..fd67fc56c9d0 100644 --- a/core/vendor/twig/twig/doc/functions/date.rst +++ b/core/vendor/twig/twig/doc/functions/date.rst @@ -43,4 +43,10 @@ If no argument is passed, the function returns the current date: $twig = new Twig_Environment($loader); $twig->getExtension('core')->setTimezone('Europe/Paris'); +Arguments +--------- + + * ``date``: The date + * ``timezone``: The timezone + .. _`date`: http://www.php.net/date diff --git a/core/vendor/twig/twig/doc/functions/dump.rst b/core/vendor/twig/twig/doc/functions/dump.rst index 8ff0c052d3c6..1500b0f4aa1d 100644 --- a/core/vendor/twig/twig/doc/functions/dump.rst +++ b/core/vendor/twig/twig/doc/functions/dump.rst @@ -60,5 +60,10 @@ dumped: Internally, Twig uses the PHP `var_dump`_ function. +Arguments +--------- + + * ``context``: The context to dump + .. _`XDebug`: http://xdebug.org/docs/display .. _`var_dump`: http://php.net/var_dump diff --git a/core/vendor/twig/twig/doc/functions/include.rst b/core/vendor/twig/twig/doc/functions/include.rst new file mode 100644 index 000000000000..eaddfe61b101 --- /dev/null +++ b/core/vendor/twig/twig/doc/functions/include.rst @@ -0,0 +1,80 @@ +``include`` +=========== + +.. versionadded:: 1.12 + The include function was added in Twig 1.12. + +The ``include`` function returns the rendered content of a template: + +.. code-block:: jinja + + {{ include('template.html') }} + {{ include(some_var) }} + +Included templates have access to the variables of the active context. + +If you are using the filesystem loader, the templates are looked for in the +paths defined by it. + +The context is passed by default to the template but you can also pass +additional variables: + +.. code-block:: jinja + + {# template.html will have access to the variables from the current context and the additional ones provided #} + {{ include('template.html', {foo: 'bar'}) }} + +You can disable access to the context by setting ``with_context`` to +``false``: + +.. code-block:: jinja + + {# only the foo variable will be accessible #} + {{ include('template.html', {foo: 'bar'}, with_context = false) }} + +.. code-block:: jinja + + {# no variables will be accessible #} + {{ include('template.html', with_context = false) }} + +And if the expression evaluates to a ``Twig_Template`` object, Twig will use it +directly:: + + // {{ include(template) }} + + $template = $twig->loadTemplate('some_template.twig'); + + $twig->loadTemplate('template.twig')->display(array('template' => $template)); + +When you set the ``ignore_missing`` flag, Twig will return an empty string if +the template does not exist: + +.. code-block:: jinja + + {{ include('sidebar.html', ignore_missing = true) }} + +You can also provide a list of templates that are checked for existence before +inclusion. The first template that exists will be rendered: + +.. code-block:: jinja + + {{ include(['page_detailed.html', 'page.html']) }} + +If ``ignore_missing`` is set, it will fall back to rendering nothing if none +of the templates exist, otherwise it will throw an exception. + +When including a template created by an end user, you should consider +sandboxing it: + +.. code-block:: jinja + + {{ include('page.html', sandboxed = true) }} + +Arguments +--------- + + * ``template``: The template to render + * ``variables``: The variables to pass to the template + * ``with_context``: Whether to pass the current context variables or not + * ``ignore_missing``: Whether to ignore missing templates or not + * ``sandboxed``: Whether to sandbox the template or not diff --git a/core/vendor/twig/twig/doc/functions/index.rst b/core/vendor/twig/twig/doc/functions/index.rst index 4d9a003787a2..c5ac896391c5 100644 --- a/core/vendor/twig/twig/doc/functions/index.rst +++ b/core/vendor/twig/twig/doc/functions/index.rst @@ -14,3 +14,4 @@ Functions dump date template_from_string + include diff --git a/core/vendor/twig/twig/doc/functions/random.rst b/core/vendor/twig/twig/doc/functions/random.rst index 104493d93e97..a5a916bbcd33 100644 --- a/core/vendor/twig/twig/doc/functions/random.rst +++ b/core/vendor/twig/twig/doc/functions/random.rst @@ -21,4 +21,9 @@ parameter type: {{ random() }} {# example output: 15386094 (works as native PHP `mt_rand`_ function) #} {{ random(5) }} {# example output: 3 #} +Arguments +--------- + + * ``values``: The values + .. _`mt_rand`: http://php.net/mt_rand diff --git a/core/vendor/twig/twig/doc/functions/range.rst b/core/vendor/twig/twig/doc/functions/range.rst index c9bdd960229b..b1fa54710c9a 100644 --- a/core/vendor/twig/twig/doc/functions/range.rst +++ b/core/vendor/twig/twig/doc/functions/range.rst @@ -35,4 +35,11 @@ function (with a step of 1): The ``range`` function works as the native PHP `range`_ function. +Arguments +--------- + + * ``low``: The first value of the sequence. + * ``high``: The highest possible value of the sequence. + * ``step``: The increment between elements of the sequence. + .. _`range`: http://php.net/range diff --git a/core/vendor/twig/twig/doc/functions/template_from_string.rst b/core/vendor/twig/twig/doc/functions/template_from_string.rst index 0b3b0b4bb709..6df650e3f51d 100644 --- a/core/vendor/twig/twig/doc/functions/template_from_string.rst +++ b/core/vendor/twig/twig/doc/functions/template_from_string.rst @@ -25,3 +25,8 @@ The ``template_from_string`` function loads a template from a string: Even if you will probably always use the ``template_from_string`` function with the ``include`` tag, you can use it with any tag or function that takes a template as an argument (like the ``embed`` or ``extends`` tags). + +Arguments +--------- + + * ``template``: The template diff --git a/core/vendor/twig/twig/doc/index.rst b/core/vendor/twig/twig/doc/index.rst index 56012f7bf692..3e5166c6e543 100644 --- a/core/vendor/twig/twig/doc/index.rst +++ b/core/vendor/twig/twig/doc/index.rst @@ -15,3 +15,4 @@ Twig filters/index functions/index tests/index + deprecated diff --git a/core/vendor/twig/twig/doc/tags/include.rst b/core/vendor/twig/twig/doc/tags/include.rst index 1440c50a7e41..d83996869218 100644 --- a/core/vendor/twig/twig/doc/tags/include.rst +++ b/core/vendor/twig/twig/doc/tags/include.rst @@ -19,23 +19,23 @@ You can add additional variables by passing them after the ``with`` keyword: .. code-block:: jinja - {# the foo template will have access to the variables from the current context and the foo one #} - {% include 'foo' with {'foo': 'bar'} %} + {# template.html will have access to the variables from the current context and the additional ones provided #} + {% include 'template.html' with {'foo': 'bar'} %} {% set vars = {'foo': 'bar'} %} - {% include 'foo' with vars %} + {% include 'template.html' with vars %} You can disable access to the context by appending the ``only`` keyword: .. code-block:: jinja {# only the foo variable will be accessible #} - {% include 'foo' with {'foo': 'bar'} only %} + {% include 'template.html' with {'foo': 'bar'} only %} .. code-block:: jinja - {# no variable will be accessible #} - {% include 'foo' only %} + {# no variables will be accessible #} + {% include 'template.html' only %} .. tip:: @@ -68,9 +68,9 @@ placed just after the template name. Here some valid examples: .. code-block:: jinja - {% include "sidebar.html" ignore missing %} - {% include "sidebar.html" ignore missing with {'foo': 'bar} %} - {% include "sidebar.html" ignore missing only %} + {% include 'sidebar.html' ignore missing %} + {% include 'sidebar.html' ignore missing with {'foo': 'bar'} %} + {% include 'sidebar.html' ignore missing only %} .. versionadded:: 1.2 The possibility to pass an array of templates has been added in Twig 1.2. diff --git a/core/vendor/twig/twig/doc/tags/index.rst b/core/vendor/twig/twig/doc/tags/index.rst index fe0a00f2f6f3..6dbc55038ab1 100644 --- a/core/vendor/twig/twig/doc/tags/index.rst +++ b/core/vendor/twig/twig/doc/tags/index.rst @@ -17,7 +17,7 @@ Tags use spaceless autoescape - raw + verbatim flush do sandbox diff --git a/core/vendor/twig/twig/doc/tags/raw.rst b/core/vendor/twig/twig/doc/tags/raw.rst deleted file mode 100644 index 4136c702e3b0..000000000000 --- a/core/vendor/twig/twig/doc/tags/raw.rst +++ /dev/null @@ -1,16 +0,0 @@ -``raw`` -======= - -The ``raw`` tag marks sections as being raw text that should not be parsed. -For example to put Twig syntax as example into a template you can use this -snippet: - -.. code-block:: jinja - - {% raw %} - <ul> - {% for item in seq %} - <li>{{ item }}</li> - {% endfor %} - </ul> - {% endraw %} diff --git a/core/vendor/twig/twig/doc/tags/verbatim.rst b/core/vendor/twig/twig/doc/tags/verbatim.rst new file mode 100644 index 000000000000..fe61ca1b0ae7 --- /dev/null +++ b/core/vendor/twig/twig/doc/tags/verbatim.rst @@ -0,0 +1,24 @@ +``verbatim`` +============ + +.. versionadded:: 1.12 + The ``verbatim`` tag was added in Twig 1.12 (it was named ``raw`` before). + +The ``verbatim`` tag marks sections as being raw text that should not be +parsed. For example to put Twig syntax as example into a template you can use +this snippet: + +.. code-block:: jinja + + {% verbatim %} + <ul> + {% for item in seq %} + <li>{{ item }}</li> + {% endfor %} + </ul> + {% endverbatim %} + +.. note:: + + The ``verbatim`` tag works in the exact same way as the old ``raw`` tag, + but was renamed to avoid confusion with the ``raw`` filter. \ No newline at end of file diff --git a/core/vendor/twig/twig/doc/templates.rst b/core/vendor/twig/twig/doc/templates.rst index 104dcad63c25..a23fcb60864f 100644 --- a/core/vendor/twig/twig/doc/templates.rst +++ b/core/vendor/twig/twig/doc/templates.rst @@ -57,6 +57,7 @@ Many IDEs support syntax highlighting and auto-completion for Twig: * *Coda 2* via the `other Twig syntax mode`_ * *Komodo* and *Komodo Edit* via the Twig highlight/syntax check mode * *Notepad++* via the `Notepad++ Twig Highlighter`_ +* *Emacs* via `web-mode.el`_ Variables --------- @@ -190,6 +191,56 @@ progression of integers: Go to the :doc:`functions<functions/index>` page to learn more about the built-in functions. +Named Arguments +--------------- + +.. versionadded:: 1.12 + Support for named arguments was added in Twig 1.12. + +Arguments for filters and functions can also be passed as *named arguments*: + +.. code-block:: jinja + + {% for i in range(low=1, high=10, step=2) %} + {{ i }}, + {% endfor %} + +Using named arguments makes your templates more explicit about the meaning of +the values you pass as arguments: + +.. code-block:: jinja + + {{ data|convert_encoding('UTF-8', 'iso-2022-jp') }} + + {# versus #} + + {{ data|convert_encoding(from='iso-2022-jp', to='UTF-8') }} + +Named arguments also allow you to skip some arguments for which you don't want +to change the default value:: + +.. code-block:: jinja + + {# the first argument is the date format, which defaults to the global date format if null is passed #} + {{ "now"|date(null, "Europe/Paris") }} + + {# or skip the format value by using a named argument for the timezone #} + {{ "now"|date(timezone="Europe/Paris") }} + +You can also use both positional and named arguments in one call, which is not +recommended as it can be confusing: + +.. code-block:: jinja + + {# both work #} + {{ "now"|date('d/m/Y H:i', timezone="Europe/Paris") }} + {{ "now"|date(timezone="Europe/Paris", 'd/m/Y H:i') }} + +.. tip:: + + Each function and filter documentation page has a section where the names + of all arguments are listed when supported. + Control Structure ----------------- @@ -438,11 +489,15 @@ expression: {{ '{{' }} -For bigger sections it makes sense to mark a block :doc:`raw<tags/raw>`. +For bigger sections it makes sense to mark a block +:doc:`verbatim<tags/verbatim>`. Macros ------ +.. versionadded:: 1.12 + Support for default argument values was added in Twig 1.12. + Macros are comparable with functions in regular programming languages. They are useful to reuse often used HTML fragments to not repeat yourself. @@ -478,6 +533,15 @@ current namespace via the :doc:`from<tags/from>` tag and optionally alias them: <dd>{{ input_field('password', '', 'password') }}</dd> </dl> +A default value can also be defined for macro arguments when not provided in a +macro call: + +.. code-block:: jinja + + {% macro input(name, value = "", type = "text", size = 20) %} + <input type="{{ type }}" name="{{ name }}" value="{{ value|e }}" size="{{ size }}" /> + {% endmacro %} + Expressions ----------- @@ -659,6 +723,9 @@ tests. Other Operators ~~~~~~~~~~~~~~~ +.. versionadded:: 1.12.0 + Support for the extended ternary operator was added in Twig 1.12.0. + The following operators are very useful but don't fit into any of the other categories: @@ -674,7 +741,15 @@ categories: * ``.``, ``[]``: Gets an attribute of an object. -* ``?:``: The PHP ternary operator: ``{{ foo ? 'yes' : 'no' }}`` +* ``?:``: The ternary operator: + + .. code-block:: jinja + + {{ foo ? 'yes' : 'no' }} + + {# as of Twig 1.12.0 #} + {{ foo ?: 'no' }} == {{ foo ? foo : 'no' }} + {{ foo ? 'yes' }} == {{ foo ? 'yes' : '' }} String Interpolation ~~~~~~~~~~~~~~~~~~~~ @@ -759,3 +834,4 @@ Extension<creating_extensions>` chapter. .. _`Twig syntax mode`: https://github.com/bobthecow/Twig-HTML.mode .. _`other Twig syntax mode`: https://github.com/muxx/Twig-HTML.mode .. _`Notepad++ Twig Highlighter`: https://github.com/Banane9/notepadplusplus-twig +.. _`web-mode.el`: http://web-mode.org/ diff --git a/core/vendor/twig/twig/ext/twig/php_twig.h b/core/vendor/twig/twig/ext/twig/php_twig.h index 0cba85879ebf..1508b0eff916 100644 --- a/core/vendor/twig/twig/ext/twig/php_twig.h +++ b/core/vendor/twig/twig/ext/twig/php_twig.h @@ -15,7 +15,7 @@ #ifndef PHP_TWIG_H #define PHP_TWIG_H -#define PHP_TWIG_VERSION "1.11.1" +#define PHP_TWIG_VERSION "1.12.1" #include "php.h" diff --git a/core/vendor/twig/twig/ext/twig/twig.c b/core/vendor/twig/twig/ext/twig/twig.c index 1fea683a4f6a..f871d1ebad8c 100644 --- a/core/vendor/twig/twig/ext/twig/twig.c +++ b/core/vendor/twig/twig/ext/twig/twig.c @@ -1030,7 +1030,7 @@ PHP_FUNCTION(twig_template_get_attributes) // ret can be null, if e.g. the called method throws an exception if (ret) { if (TWIG_INSTANCE_OF_USERLAND(object, "Twig_TemplateInterface" TSRMLS_CC)) { - if (Z_STRVAL_P(ret) == "") { + if (Z_STRLEN_P(ret) == 0) { free_ret = 1; } else { zval *charset = TWIG_CALL_USER_FUNC_ARRAY(TWIG_PROPERTY_CHAR(template, "env" TSRMLS_CC), "getCharset", NULL TSRMLS_CC); diff --git a/core/vendor/twig/twig/lib/Twig/Compiler.php b/core/vendor/twig/twig/lib/Twig/Compiler.php index c1ab250bc6a6..95b18699c6a0 100644 --- a/core/vendor/twig/twig/lib/Twig/Compiler.php +++ b/core/vendor/twig/twig/lib/Twig/Compiler.php @@ -256,7 +256,7 @@ public function indent($step = 1) */ public function outdent($step = 1) { - // can't outdent by more steps that the current indentation level + // can't outdent by more steps than the current indentation level if ($this->indentation < $step) { throw new LogicException('Unable to call outdent() as the indentation would become negative'); } diff --git a/core/vendor/twig/twig/lib/Twig/CompilerInterface.php b/core/vendor/twig/twig/lib/Twig/CompilerInterface.php index 89d87e6b970b..db848a0385d7 100644 --- a/core/vendor/twig/twig/lib/Twig/CompilerInterface.php +++ b/core/vendor/twig/twig/lib/Twig/CompilerInterface.php @@ -14,6 +14,7 @@ * * @package twig * @author Fabien Potencier <fabien@symfony.com> + * @deprecated since 1.12 (to be removed in 2.0) */ interface Twig_CompilerInterface { diff --git a/core/vendor/twig/twig/lib/Twig/Environment.php b/core/vendor/twig/twig/lib/Twig/Environment.php index 39e2c76ea927..eabbf0ada08c 100644 --- a/core/vendor/twig/twig/lib/Twig/Environment.php +++ b/core/vendor/twig/twig/lib/Twig/Environment.php @@ -17,7 +17,7 @@ */ class Twig_Environment { - const VERSION = '1.11.1'; + const VERSION = '1.12.1'; protected $charset; protected $loader; @@ -36,6 +36,7 @@ class Twig_Environment protected $functions; protected $globals; protected $runtimeInitialized; + protected $extensionInitialized; protected $loadedTemplates; protected $strictVariables; protected $unaryOperators; @@ -102,24 +103,17 @@ public function __construct(Twig_LoaderInterface $loader = null, $options = arra $this->charset = $options['charset']; $this->baseTemplateClass = $options['base_template_class']; $this->autoReload = null === $options['auto_reload'] ? $this->debug : (bool) $options['auto_reload']; - $this->extensions = array( - 'core' => new Twig_Extension_Core(), - 'escaper' => new Twig_Extension_Escaper($options['autoescape']), - 'optimizer' => new Twig_Extension_Optimizer($options['optimizations']), - ); $this->strictVariables = (bool) $options['strict_variables']; $this->runtimeInitialized = false; $this->setCache($options['cache']); $this->functionCallbacks = array(); $this->filterCallbacks = array(); - $this->staging = array( - 'functions' => array(), - 'filters' => array(), - 'tests' => array(), - 'token_parsers' => array(), - 'visitors' => array(), - 'globals' => array(), - ); + + $this->addExtension(new Twig_Extension_Core()); + $this->addExtension(new Twig_Extension_Escaper($options['autoescape'])); + $this->addExtension(new Twig_Extension_Optimizer($options['optimizations'])); + $this->extensionInitialized = false; + $this->staging = new Twig_Extension_Staging(); } /** @@ -629,29 +623,29 @@ public function getExtension($name) */ public function addExtension(Twig_ExtensionInterface $extension) { + if ($this->extensionInitialized) { + throw new LogicException(sprintf('Unable to register extension "%s" as extensions have already been initialized.', $extension->getName())); + } + $this->extensions[$extension->getName()] = $extension; - $this->parsers = null; - $this->visitors = null; - $this->filters = null; - $this->tests = null; - $this->functions = null; - $this->globals = null; } /** * Removes an extension by name. * + * This method is deprecated and you should not use it. + * * @param string $name The extension name + * + * @deprecated since 1.12 (to be removed in 2.0) */ public function removeExtension($name) { + if ($this->extensionInitialized) { + throw new LogicException(sprintf('Unable to remove extension "%s" as extensions have already been initialized.', $name)); + } + unset($this->extensions[$name]); - $this->parsers = null; - $this->visitors = null; - $this->filters = null; - $this->tests = null; - $this->functions = null; - $this->globals = null; } /** @@ -683,8 +677,11 @@ public function getExtensions() */ public function addTokenParser(Twig_TokenParserInterface $parser) { - $this->staging['token_parsers'][] = $parser; - $this->parsers = null; + if ($this->extensionInitialized) { + throw new LogicException('Unable to add a token parser as extensions have already been initialized.'); + } + + $this->staging->addTokenParser($parser); } /** @@ -694,27 +691,8 @@ public function addTokenParser(Twig_TokenParserInterface $parser) */ public function getTokenParsers() { - if (null === $this->parsers) { - $this->parsers = new Twig_TokenParserBroker(); - - if (isset($this->staging['token_parsers'])) { - foreach ($this->staging['token_parsers'] as $parser) { - $this->parsers->addTokenParser($parser); - } - } - - foreach ($this->getExtensions() as $extension) { - $parsers = $extension->getTokenParsers(); - foreach ($parsers as $parser) { - if ($parser instanceof Twig_TokenParserInterface) { - $this->parsers->addTokenParser($parser); - } elseif ($parser instanceof Twig_TokenParserBrokerInterface) { - $this->parsers->addTokenParserBroker($parser); - } else { - throw new LogicException('getTokenParsers() must return an array of Twig_TokenParserInterface or Twig_TokenParserBrokerInterface instances'); - } - } - } + if (!$this->extensionInitialized) { + $this->initExtensions(); } return $this->parsers; @@ -746,8 +724,11 @@ public function getTags() */ public function addNodeVisitor(Twig_NodeVisitorInterface $visitor) { - $this->staging['visitors'][] = $visitor; - $this->visitors = null; + if ($this->extensionInitialized) { + throw new LogicException('Unable to add a node visitor as extensions have already been initialized.', $extension->getName()); + } + + $this->staging->addNodeVisitor($visitor); } /** @@ -757,14 +738,8 @@ public function addNodeVisitor(Twig_NodeVisitorInterface $visitor) */ public function getNodeVisitors() { - if (null === $this->visitors) { - foreach ($this->getExtensions() as $extension) { - foreach ($extension->getNodeVisitors() as $visitor) { - $this->addNodeVisitor($visitor); - } - } - - $this->visitors = $this->staging['visitors']; + if (!$this->extensionInitialized) { + $this->initExtensions(); } return $this->visitors; @@ -773,13 +748,25 @@ public function getNodeVisitors() /** * Registers a Filter. * - * @param string $name The filter name - * @param Twig_FilterInterface $filter A Twig_FilterInterface instance + * @param string|Twig_SimpleFilter $name The filter name or a Twig_SimpleFilter instance + * @param Twig_FilterInterface|Twig_SimpleFilter $filter A Twig_FilterInterface instance or a Twig_SimpleFilter instance */ - public function addFilter($name, Twig_FilterInterface $filter) + public function addFilter($name, $filter = null) { - $this->staging['filters'][$name] = $filter; - $this->filters = null; + if ($this->extensionInitialized) { + throw new LogicException(sprintf('Unable to add filter "%s" as extensions have already been initialized.', $name)); + } + + if (!$name instanceof Twig_SimpleFilter && !($filter instanceof Twig_SimpleFilter || $filter instanceof Twig_FilterInterface)) { + throw new LogicException('A filter must be an instance of Twig_FilterInterface or Twig_SimpleFilter'); + } + + if ($name instanceof Twig_SimpleFilter) { + $filter = $name; + $name = $filter->getName(); + } + + $this->staging->addFilter($name, $filter); } /** @@ -790,12 +777,12 @@ public function addFilter($name, Twig_FilterInterface $filter) * * @param string $name The filter name * - * @return Twig_Filter|false A Twig_Filter instance or false if the filter does not exists + * @return Twig_Filter|false A Twig_Filter instance or false if the filter does not exist */ public function getFilter($name) { - if (null === $this->filters) { - $this->getFilters(); + if (!$this->extensionInitialized) { + $this->initExtensions(); } if (isset($this->filters[$name])) { @@ -840,14 +827,8 @@ public function registerUndefinedFilterCallback($callable) */ public function getFilters() { - if (null === $this->filters) { - foreach ($this->getExtensions() as $extension) { - foreach ($extension->getFilters() as $name => $filter) { - $this->addFilter($name, $filter); - } - } - - $this->filters = $this->staging['filters']; + if (!$this->extensionInitialized) { + $this->initExtensions(); } return $this->filters; @@ -856,13 +837,25 @@ public function getFilters() /** * Registers a Test. * - * @param string $name The test name - * @param Twig_TestInterface $test A Twig_TestInterface instance + * @param string|Twig_SimpleTest $name The test name or a Twig_SimpleTest instance + * @param Twig_TestInterface|Twig_SimpleTest $test A Twig_TestInterface instance or a Twig_SimpleTest instance */ - public function addTest($name, Twig_TestInterface $test) + public function addTest($name, $test = null) { - $this->staging['tests'][$name] = $test; - $this->tests = null; + if ($this->extensionInitialized) { + throw new LogicException(sprintf('Unable to add test "%s" as extensions have already been initialized.', $name)); + } + + if (!$name instanceof Twig_SimpleTest && !($test instanceof Twig_SimpleTest || $test instanceof Twig_TestInterface)) { + throw new LogicException('A test must be an instance of Twig_TestInterface or Twig_SimpleTest'); + } + + if ($name instanceof Twig_SimpleTest) { + $test = $name; + $name = $test->getName(); + } + + $this->staging->addTest($name, $test); } /** @@ -872,29 +865,55 @@ public function addTest($name, Twig_TestInterface $test) */ public function getTests() { - if (null === $this->tests) { - foreach ($this->getExtensions() as $extension) { - foreach ($extension->getTests() as $name => $test) { - $this->addTest($name, $test); - } - } - - $this->tests = $this->staging['tests']; + if (!$this->extensionInitialized) { + $this->initExtensions(); } return $this->tests; } + /** + * Gets a test by name. + * + * @param string $name The test name + * + * @return Twig_Test|false A Twig_Test instance or false if the test does not exist + */ + public function getTest($name) + { + if (!$this->extensionInitialized) { + $this->initExtensions(); + } + + if (isset($this->tests[$name])) { + return $this->tests[$name]; + } + + return false; + } + /** * Registers a Function. * - * @param string $name The function name - * @param Twig_FunctionInterface $function A Twig_FunctionInterface instance + * @param string|Twig_SimpleFunction $name The function name or a Twig_SimpleFunction instance + * @param Twig_FunctionInterface|Twig_SimpleFunction $function A Twig_FunctionInterface instance or a Twig_SimpleFunction instance */ - public function addFunction($name, Twig_FunctionInterface $function) + public function addFunction($name, $function = null) { - $this->staging['functions'][$name] = $function; - $this->functions = null; + if ($this->extensionInitialized) { + throw new LogicException(sprintf('Unable to add function "%s" as extensions have already been initialized.', $name)); + } + + if (!$name instanceof Twig_SimpleFunction && !($function instanceof Twig_SimpleFunction || $function instanceof Twig_FunctionInterface)) { + throw new LogicException('A function must be an instance of Twig_FunctionInterface or Twig_SimpleFunction'); + } + + if ($name instanceof Twig_SimpleFunction) { + $function = $name; + $name = $function->getName(); + } + + $this->staging->addFunction($name, $function); } /** @@ -905,12 +924,12 @@ public function addFunction($name, Twig_FunctionInterface $function) * * @param string $name function name * - * @return Twig_Function|false A Twig_Function instance or false if the function does not exists + * @return Twig_Function|false A Twig_Function instance or false if the function does not exist */ public function getFunction($name) { - if (null === $this->functions) { - $this->getFunctions(); + if (!$this->extensionInitialized) { + $this->initExtensions(); } if (isset($this->functions[$name])) { @@ -955,14 +974,8 @@ public function registerUndefinedFunctionCallback($callable) */ public function getFunctions() { - if (null === $this->functions) { - foreach ($this->getExtensions() as $extension) { - foreach ($extension->getFunctions() as $name => $function) { - $this->addFunction($name, $function); - } - } - - $this->functions = $this->staging['functions']; + if (!$this->extensionInitialized) { + $this->initExtensions(); } return $this->functions; @@ -971,13 +984,32 @@ public function getFunctions() /** * Registers a Global. * + * New globals can be added before compiling or rendering a template; + * but after, you can only update existing globals. + * * @param string $name The global name * @param mixed $value The global value */ public function addGlobal($name, $value) { - $this->staging['globals'][$name] = $value; - $this->globals = null; + if ($this->extensionInitialized || $this->runtimeInitialized) { + if (null === $this->globals) { + $this->initGlobals(); + } + + /* This condition must be uncommented in Twig 2.0 + if (!array_key_exists($name, $this->globals)) { + throw new LogicException(sprintf('Unable to add global "%s" as the runtime or the extensions have already been initialized.', $name)); + } + */ + } + + if ($this->extensionInitialized || $this->runtimeInitialized) { + // update the value + $this->globals[$name] = $value; + } else { + $this->staging->addGlobal($name, $value); + } } /** @@ -987,11 +1019,8 @@ public function addGlobal($name, $value) */ public function getGlobals() { - if (null === $this->globals) { - $this->globals = isset($this->staging['globals']) ? $this->staging['globals'] : array(); - foreach ($this->getExtensions() as $extension) { - $this->globals = array_merge($this->globals, $extension->getGlobals()); - } + if (null === $this->globals || !($this->runtimeInitialized || $this->extensionInitialized)) { + $this->initGlobals(); } return $this->globals; @@ -1024,8 +1053,8 @@ public function mergeGlobals(array $context) */ public function getUnaryOperators() { - if (null === $this->unaryOperators) { - $this->initOperators(); + if (!$this->extensionInitialized) { + $this->initExtensions(); } return $this->unaryOperators; @@ -1038,8 +1067,8 @@ public function getUnaryOperators() */ public function getBinaryOperators() { - if (null === $this->binaryOperators) { - $this->initOperators(); + if (!$this->extensionInitialized) { + $this->initExtensions(); } return $this->binaryOperators; @@ -1059,17 +1088,92 @@ public function computeAlternatives($name, $items) return array_keys($alternatives); } - protected function initOperators() + protected function initGlobals() + { + $this->globals = array(); + foreach ($this->extensions as $extension) { + $this->globals = array_merge($this->globals, $extension->getGlobals()); + } + $this->globals = array_merge($this->globals, $this->staging->getGlobals()); + } + + protected function initExtensions() { + if ($this->extensionInitialized) { + return; + } + + $this->extensionInitialized = true; + $this->parsers = new Twig_TokenParserBroker(); + $this->filters = array(); + $this->functions = array(); + $this->tests = array(); + $this->visitors = array(); $this->unaryOperators = array(); $this->binaryOperators = array(); - foreach ($this->getExtensions() as $extension) { - $operators = $extension->getOperators(); - if (!$operators) { - continue; + foreach ($this->extensions as $extension) { + $this->initExtension($extension); + } + $this->initExtension($this->staging); + } + + protected function initExtension(Twig_ExtensionInterface $extension) + { + // filters + foreach ($extension->getFilters() as $name => $filter) { + if ($name instanceof Twig_SimpleFilter) { + $filter = $name; + $name = $filter->getName(); + } elseif ($filter instanceof Twig_SimpleFilter) { + $name = $filter->getName(); + } + + $this->filters[$name] = $filter; + } + + // functions + foreach ($extension->getFunctions() as $name => $function) { + if ($name instanceof Twig_SimpleFunction) { + $function = $name; + $name = $function->getName(); + } elseif ($function instanceof Twig_SimpleFunction) { + $name = $function->getName(); + } + + $this->functions[$name] = $function; + } + + // tests + foreach ($extension->getTests() as $name => $test) { + if ($name instanceof Twig_SimpleTest) { + $test = $name; + $name = $test->getName(); + } elseif ($test instanceof Twig_SimpleTest) { + $name = $test->getName(); + } + + $this->tests[$name] = $test; + } + + // token parsers + foreach ($extension->getTokenParsers() as $parser) { + if ($parser instanceof Twig_TokenParserInterface) { + $this->parsers->addTokenParser($parser); + } elseif ($parser instanceof Twig_TokenParserBrokerInterface) { + $this->parsers->addTokenParserBroker($parser); + } else { + throw new LogicException('getTokenParsers() must return an array of Twig_TokenParserInterface or Twig_TokenParserBrokerInterface instances'); } + } + + // node visitors + foreach ($extension->getNodeVisitors() as $visitor) { + $this->visitors[] = $visitor; + } + // operators + if ($operators = $extension->getOperators()) { if (2 !== count($operators)) { throw new InvalidArgumentException(sprintf('"%s::getOperators()" does not return a valid operators array.', get_class($extension))); } diff --git a/core/vendor/twig/twig/lib/Twig/ExistsLoaderInterface.php b/core/vendor/twig/twig/lib/Twig/ExistsLoaderInterface.php index 0e08a1dfcd18..95fbeb0cb8c8 100644 --- a/core/vendor/twig/twig/lib/Twig/ExistsLoaderInterface.php +++ b/core/vendor/twig/twig/lib/Twig/ExistsLoaderInterface.php @@ -14,6 +14,7 @@ * * @package twig * @author Florin Patan <florinpatan@gmail.com> + * @deprecated since 1.12 (to be removed in 2.0) */ interface Twig_ExistsLoaderInterface { diff --git a/core/vendor/twig/twig/lib/Twig/ExpressionParser.php b/core/vendor/twig/twig/lib/Twig/ExpressionParser.php index 3309bb52db75..7b9114afa193 100644 --- a/core/vendor/twig/twig/lib/Twig/ExpressionParser.php +++ b/core/vendor/twig/twig/lib/Twig/ExpressionParser.php @@ -89,9 +89,19 @@ protected function parseConditionalExpression($expr) { while ($this->parser->getStream()->test(Twig_Token::PUNCTUATION_TYPE, '?')) { $this->parser->getStream()->next(); - $expr2 = $this->parseExpression(); - $this->parser->getStream()->expect(Twig_Token::PUNCTUATION_TYPE, ':', 'The ternary operator must have a default value'); - $expr3 = $this->parseExpression(); + if (!$this->parser->getStream()->test(Twig_Token::PUNCTUATION_TYPE, ':')) { + $expr2 = $this->parseExpression(); + if ($this->parser->getStream()->test(Twig_Token::PUNCTUATION_TYPE, ':')) { + $this->parser->getStream()->next(); + $expr3 = $this->parseExpression(); + } else { + $expr3 = new Twig_Node_Expression_Constant('', $this->parser->getCurrentToken()->getLine()); + } + } else { + $this->parser->getStream()->next(); + $expr2 = $expr; + $expr3 = $this->parseExpression(); + } $expr = new Twig_Node_Expression_Conditional($expr, $expr2, $expr3, $this->parser->getCurrentToken()->getLine()); } @@ -287,9 +297,9 @@ public function parsePostfixExpression($node) public function getFunctionNode($name, $line) { - $args = $this->parseArguments(); switch ($name) { case 'parent': + $args = $this->parseArguments(); if (!count($this->parser->getBlockStack())) { throw new Twig_Error_Syntax('Calling "parent" outside a block is forbidden', $line, $this->parser->getFilename()); } @@ -300,8 +310,9 @@ public function getFunctionNode($name, $line) return new Twig_Node_Expression_Parent($this->parser->peekBlockStack(), $line); case 'block': - return new Twig_Node_Expression_BlockReference($args->getNode(0), false, $line); + return new Twig_Node_Expression_BlockReference($this->parseArguments()->getNode(0), false, $line); case 'attribute': + $args = $this->parseArguments(); if (count($args) < 2) { throw new Twig_Error_Syntax('The "attribute" function takes at least two arguments (the variable and the attributes)', $line, $this->parser->getFilename()); } @@ -310,7 +321,7 @@ public function getFunctionNode($name, $line) default: if (null !== $alias = $this->parser->getImportedSymbol('function', $name)) { $arguments = new Twig_Node_Expression_Array(array(), $line); - foreach ($args as $n) { + foreach ($this->parseArguments() as $n) { $arguments->addElement($n); } @@ -320,7 +331,8 @@ public function getFunctionNode($name, $line) return $node; } - $class = $this->getFunctionNodeClass($name); + $args = $this->parseArguments(true); + $class = $this->getFunctionNodeClass($name, $line); return new $class($name, $args, $line); } @@ -353,22 +365,42 @@ public function parseSubscriptExpression($node) } else { throw new Twig_Error_Syntax('Expected name or number', $lineno, $this->parser->getFilename()); } + + if ($node instanceof Twig_Node_Expression_Name && null !== $alias = $this->parser->getImportedSymbol('template', $node->getAttribute('name'))) { + if (!$arg instanceof Twig_Node_Expression_Constant) { + throw new Twig_Error_Syntax(sprintf('Dynamic macro names are not supported (called on "%s")', $node->getAttribute('name')), $token->getLine(), $this->parser->getFilename()); + } + + $node = new Twig_Node_Expression_MethodCall($node, 'get'.$arg->getAttribute('value'), $arguments, $lineno); + $node->setAttribute('safe', true); + + return $node; + } } else { $type = Twig_TemplateInterface::ARRAY_CALL; - $arg = $this->parseExpression(); - // slice? + $slice = false; + if ($stream->test(Twig_Token::PUNCTUATION_TYPE, ':')) { + $slice = true; + $arg = new Twig_Node_Expression_Constant(0, $token->getLine()); + } else { + $arg = $this->parseExpression(); + } + if ($stream->test(Twig_Token::PUNCTUATION_TYPE, ':')) { + $slice = true; $stream->next(); + } + if ($slice) { if ($stream->test(Twig_Token::PUNCTUATION_TYPE, ']')) { $length = new Twig_Node_Expression_Constant(null, $token->getLine()); } else { $length = $this->parseExpression(); } - $class = $this->getFilterNodeClass('slice'); + $class = $this->getFilterNodeClass('slice', $token->getLine()); $arguments = new Twig_Node(array($arg, $length)); $filter = new $class($node, new Twig_Node_Expression_Constant('slice', $token->getLine()), $arguments, $token->getLine()); @@ -380,13 +412,6 @@ public function parseSubscriptExpression($node) $stream->expect(Twig_Token::PUNCTUATION_TYPE, ']'); } - if ($node instanceof Twig_Node_Expression_Name && null !== $alias = $this->parser->getImportedSymbol('template', $node->getAttribute('name'))) { - $node = new Twig_Node_Expression_MethodCall($node, 'get'.$arg->getAttribute('value'), $arguments, $lineno); - $node->setAttribute('safe', true); - - return $node; - } - return new Twig_Node_Expression_GetAttr($node, $arg, $arguments, $type, $lineno); } @@ -406,10 +431,10 @@ public function parseFilterExpressionRaw($node, $tag = null) if (!$this->parser->getStream()->test(Twig_Token::PUNCTUATION_TYPE, '(')) { $arguments = new Twig_Node(); } else { - $arguments = $this->parseArguments(); + $arguments = $this->parseArguments(true); } - $class = $this->getFilterNodeClass($name->getAttribute('value')); + $class = $this->getFilterNodeClass($name->getAttribute('value'), $token->getLine()); $node = new $class($node, $name, $arguments, $token->getLine(), $tag); @@ -423,17 +448,62 @@ public function parseFilterExpressionRaw($node, $tag = null) return $node; } - public function parseArguments() + /** + * Parses arguments. + * + * @param Boolean $namedArguments Whether to allow named arguments or not + * @param Boolean $definition Whether we are parsing arguments for a function definition + */ + public function parseArguments($namedArguments = false, $definition = false) { $args = array(); $stream = $this->parser->getStream(); - $stream->expect(Twig_Token::PUNCTUATION_TYPE, '(', 'A list of arguments must be opened by a parenthesis'); + $stream->expect(Twig_Token::PUNCTUATION_TYPE, '(', 'A list of arguments must begin with an opening parenthesis'); while (!$stream->test(Twig_Token::PUNCTUATION_TYPE, ')')) { if (!empty($args)) { $stream->expect(Twig_Token::PUNCTUATION_TYPE, ',', 'Arguments must be separated by a comma'); } - $args[] = $this->parseExpression(); + + if ($definition) { + $token = $stream->expect(Twig_Token::NAME_TYPE, null, 'An argument must be a name'); + $value = new Twig_Node_Expression_Name($token->getValue(), $this->parser->getCurrentToken()->getLine()); + } else { + $value = $this->parseExpression(); + } + + $name = null; + if ($namedArguments && $stream->test(Twig_Token::OPERATOR_TYPE, '=')) { + $token = $stream->next(); + if (!$value instanceof Twig_Node_Expression_Name) { + throw new Twig_Error_Syntax(sprintf('A parameter name must be a string, "%s" given', get_class($value)), $token->getLine(), $this->parser->getFilename()); + } + $name = $value->getAttribute('name'); + + if ($definition) { + $value = $this->parsePrimaryExpression(); + + if (!$this->checkConstantExpression($value)) { + throw new Twig_Error_Syntax(sprintf('A default value for an argument must be a constant (a boolean, a string, a number, or an array).'), $token->getLine(), $this->parser->getFilename()); + } + } else { + $value = $this->parseExpression(); + } + } + + if ($definition) { + if (null === $name) { + $name = $value->getAttribute('name'); + $value = new Twig_Node_Expression_Constant(null, $this->parser->getCurrentToken()->getLine()); + } + $args[$name] = $value; + } else { + if (null === $name) { + $args[] = $value; + } else { + $args[$name] = $value; + } + } } $stream->expect(Twig_Token::PUNCTUATION_TYPE, ')', 'A list of arguments must be closed by a parenthesis'); @@ -473,23 +543,59 @@ public function parseMultitargetExpression() return new Twig_Node($targets); } - protected function getFunctionNodeClass($name) + protected function getFunctionNodeClass($name, $line) + { + $env = $this->parser->getEnvironment(); + + if (false === $function = $env->getFunction($name)) { + $message = sprintf('The function "%s" does not exist', $name); + if ($alternatives = $env->computeAlternatives($name, array_keys($env->getFunctions()))) { + $message = sprintf('%s. Did you mean "%s"', $message, implode('", "', $alternatives)); + } + + throw new Twig_Error_Syntax($message, $line, $this->parser->getFilename()); + } + + if ($function instanceof Twig_SimpleFunction) { + return $function->getNodeClass(); + } + + return $function instanceof Twig_Function_Node ? $function->getClass() : 'Twig_Node_Expression_Function'; + } + + protected function getFilterNodeClass($name, $line) { - $functionMap = $this->parser->getEnvironment()->getFunctions(); - if (isset($functionMap[$name]) && $functionMap[$name] instanceof Twig_Function_Node) { - return $functionMap[$name]->getClass(); + $env = $this->parser->getEnvironment(); + + if (false === $filter = $env->getFilter($name)) { + $message = sprintf('The filter "%s" does not exist', $name); + if ($alternatives = $env->computeAlternatives($name, array_keys($env->getFilters()))) { + $message = sprintf('%s. Did you mean "%s"', $message, implode('", "', $alternatives)); + } + + throw new Twig_Error_Syntax($message, $line, $this->parser->getFilename()); + } + + if ($filter instanceof Twig_SimpleFilter) { + return $filter->getNodeClass(); } - return 'Twig_Node_Expression_Function'; + return $filter instanceof Twig_Filter_Node ? $filter->getClass() : 'Twig_Node_Expression_Filter'; } - protected function getFilterNodeClass($name) + // checks that the node only contains "constant" elements + protected function checkConstantExpression(Twig_NodeInterface $node) { - $filterMap = $this->parser->getEnvironment()->getFilters(); - if (isset($filterMap[$name]) && $filterMap[$name] instanceof Twig_Filter_Node) { - return $filterMap[$name]->getClass(); + if (!($node instanceof Twig_Node_Expression_Constant || $node instanceof Twig_Node_Expression_Array)) { + return false; + } + + foreach ($node as $n) { + if (!$this->checkConstantExpression($n)) { + return false; + } } - return 'Twig_Node_Expression_Filter'; + return true; } } diff --git a/core/vendor/twig/twig/lib/Twig/Extension/Core.php b/core/vendor/twig/twig/lib/Twig/Extension/Core.php index 3db899f75017..2110120ff8c5 100644 --- a/core/vendor/twig/twig/lib/Twig/Extension/Core.php +++ b/core/vendor/twig/twig/lib/Twig/Extension/Core.php @@ -126,47 +126,45 @@ public function getFilters() { $filters = array( // formatting filters - 'date' => new Twig_Filter_Function('twig_date_format_filter', array('needs_environment' => true)), - 'date_modify' => new Twig_Filter_Function('twig_date_modify_filter', array('needs_environment' => true)), - 'format' => new Twig_Filter_Function('sprintf'), - 'replace' => new Twig_Filter_Function('strtr'), - 'number_format' => new Twig_Filter_Function('twig_number_format_filter', array('needs_environment' => true)), - 'abs' => new Twig_Filter_Function('abs'), + new Twig_SimpleFilter('date', 'twig_date_format_filter', array('needs_environment' => true)), + new Twig_SimpleFilter('date_modify', 'twig_date_modify_filter', array('needs_environment' => true)), + new Twig_SimpleFilter('format', 'sprintf'), + new Twig_SimpleFilter('replace', 'strtr'), + new Twig_SimpleFilter('number_format', 'twig_number_format_filter', array('needs_environment' => true)), + new Twig_SimpleFilter('abs', 'abs'), // encoding - 'url_encode' => new Twig_Filter_Function('twig_urlencode_filter'), - 'json_encode' => new Twig_Filter_Function('twig_jsonencode_filter'), - 'convert_encoding' => new Twig_Filter_Function('twig_convert_encoding'), + new Twig_SimpleFilter('url_encode', 'twig_urlencode_filter'), + new Twig_SimpleFilter('json_encode', 'twig_jsonencode_filter'), + new Twig_SimpleFilter('convert_encoding', 'twig_convert_encoding'), // string filters - 'title' => new Twig_Filter_Function('twig_title_string_filter', array('needs_environment' => true)), - 'capitalize' => new Twig_Filter_Function('twig_capitalize_string_filter', array('needs_environment' => true)), - 'upper' => new Twig_Filter_Function('strtoupper'), - 'lower' => new Twig_Filter_Function('strtolower'), - 'striptags' => new Twig_Filter_Function('strip_tags'), - 'trim' => new Twig_Filter_Function('trim'), - 'nl2br' => new Twig_Filter_Function('nl2br', array('pre_escape' => 'html', 'is_safe' => array('html'))), + new Twig_SimpleFilter('title', 'twig_title_string_filter', array('needs_environment' => true)), + new Twig_SimpleFilter('capitalize', 'twig_capitalize_string_filter', array('needs_environment' => true)), + new Twig_SimpleFilter('upper', 'strtoupper'), + new Twig_SimpleFilter('lower', 'strtolower'), + new Twig_SimpleFilter('striptags', 'strip_tags'), + new Twig_SimpleFilter('trim', 'trim'), + new Twig_SimpleFilter('nl2br', 'nl2br', array('pre_escape' => 'html', 'is_safe' => array('html'))), // array helpers - 'join' => new Twig_Filter_Function('twig_join_filter'), - 'split' => new Twig_Filter_Function('twig_split_filter'), - 'sort' => new Twig_Filter_Function('twig_sort_filter'), - 'merge' => new Twig_Filter_Function('twig_array_merge'), + new Twig_SimpleFilter('join', 'twig_join_filter'), + new Twig_SimpleFilter('split', 'twig_split_filter'), + new Twig_SimpleFilter('sort', 'twig_sort_filter'), + new Twig_SimpleFilter('merge', 'twig_array_merge'), // string/array filters - 'reverse' => new Twig_Filter_Function('twig_reverse_filter', array('needs_environment' => true)), - 'length' => new Twig_Filter_Function('twig_length_filter', array('needs_environment' => true)), - 'slice' => new Twig_Filter_Function('twig_slice', array('needs_environment' => true)), + new Twig_SimpleFilter('reverse', 'twig_reverse_filter', array('needs_environment' => true)), + new Twig_SimpleFilter('length', 'twig_length_filter', array('needs_environment' => true)), + new Twig_SimpleFilter('slice', 'twig_slice', array('needs_environment' => true)), // iteration and runtime - 'default' => new Twig_Filter_Node('Twig_Node_Expression_Filter_Default'), - '_default' => new Twig_Filter_Function('_twig_default_filter'), - - 'keys' => new Twig_Filter_Function('twig_get_array_keys_filter'), + new Twig_SimpleFilter('default', '_twig_default_filter', array('node_class' => 'Twig_Node_Expression_Filter_Default')), + new Twig_SimpleFilter('keys', 'twig_get_array_keys_filter'), // escaping - 'escape' => new Twig_Filter_Function('twig_escape_filter', array('needs_environment' => true, 'is_safe_callback' => 'twig_escape_filter_is_safe')), - 'e' => new Twig_Filter_Function('twig_escape_filter', array('needs_environment' => true, 'is_safe_callback' => 'twig_escape_filter_is_safe')), + new Twig_SimpleFilter('escape', 'twig_escape_filter', array('needs_environment' => true, 'is_safe_callback' => 'twig_escape_filter_is_safe')), + new Twig_SimpleFilter('e', 'twig_escape_filter', array('needs_environment' => true, 'is_safe_callback' => 'twig_escape_filter_is_safe')), ); if (function_exists('mb_get_info')) { @@ -185,11 +183,12 @@ public function getFilters() public function getFunctions() { return array( - 'range' => new Twig_Function_Function('range'), - 'constant' => new Twig_Function_Function('constant'), - 'cycle' => new Twig_Function_Function('twig_cycle'), - 'random' => new Twig_Function_Function('twig_random', array('needs_environment' => true)), - 'date' => new Twig_Function_Function('twig_date_converter', array('needs_environment' => true)), + new Twig_SimpleFunction('range', 'range'), + new Twig_SimpleFunction('constant', 'twig_constant'), + new Twig_SimpleFunction('cycle', 'twig_cycle'), + new Twig_SimpleFunction('random', 'twig_random', array('needs_environment' => true)), + new Twig_SimpleFunction('date', 'twig_date_converter', array('needs_environment' => true)), + new Twig_SimpleFunction('include', 'twig_include', array('needs_environment' => true, 'needs_context' => true)), ); } @@ -201,16 +200,16 @@ public function getFunctions() public function getTests() { return array( - 'even' => new Twig_Test_Node('Twig_Node_Expression_Test_Even'), - 'odd' => new Twig_Test_Node('Twig_Node_Expression_Test_Odd'), - 'defined' => new Twig_Test_Node('Twig_Node_Expression_Test_Defined'), - 'sameas' => new Twig_Test_Node('Twig_Node_Expression_Test_Sameas'), - 'none' => new Twig_Test_Node('Twig_Node_Expression_Test_Null'), - 'null' => new Twig_Test_Node('Twig_Node_Expression_Test_Null'), - 'divisibleby' => new Twig_Test_Node('Twig_Node_Expression_Test_Divisibleby'), - 'constant' => new Twig_Test_Node('Twig_Node_Expression_Test_Constant'), - 'empty' => new Twig_Test_Function('twig_test_empty'), - 'iterable' => new Twig_Test_Function('twig_test_iterable'), + new Twig_SimpleTest('even', null, array('node_class' => 'Twig_Node_Expression_Test_Even')), + new Twig_SimpleTest('odd', null, array('node_class' => 'Twig_Node_Expression_Test_Odd')), + new Twig_SimpleTest('defined', null, array('node_class' => 'Twig_Node_Expression_Test_Defined')), + new Twig_SimpleTest('sameas', null, array('node_class' => 'Twig_Node_Expression_Test_Sameas')), + new Twig_SimpleTest('none', null, array('node_class' => 'Twig_Node_Expression_Test_Null')), + new Twig_SimpleTest('null', null, array('node_class' => 'Twig_Node_Expression_Test_Null')), + new Twig_SimpleTest('divisibleby', null, array('node_class' => 'Twig_Node_Expression_Test_Divisibleby')), + new Twig_SimpleTest('constant', null, array('node_class' => 'Twig_Node_Expression_Test_Constant')), + new Twig_SimpleTest('empty', 'twig_test_empty'), + new Twig_SimpleTest('iterable', 'twig_test_iterable'), ); } @@ -267,22 +266,32 @@ public function parseTestExpression(Twig_Parser $parser, $node) $name = $stream->expect(Twig_Token::NAME_TYPE)->getValue(); $arguments = null; if ($stream->test(Twig_Token::PUNCTUATION_TYPE, '(')) { - $arguments = $parser->getExpressionParser()->parseArguments(); + $arguments = $parser->getExpressionParser()->parseArguments(true); } - $class = $this->getTestNodeClass($parser->getEnvironment(), $name); + $class = $this->getTestNodeClass($parser, $name, $node->getLine()); return new $class($node, $name, $arguments, $parser->getCurrentToken()->getLine()); } - protected function getTestNodeClass(Twig_Environment $env, $name) + protected function getTestNodeClass(Twig_Parser $parser, $name, $line) { + $env = $parser->getEnvironment(); $testMap = $env->getTests(); - if (isset($testMap[$name]) && $testMap[$name] instanceof Twig_Test_Node) { - return $testMap[$name]->getClass(); + if (!isset($testMap[$name])) { + $message = sprintf('The test "%s" does not exist', $name); + if ($alternatives = $env->computeAlternatives($name, array_keys($env->getTests()))) { + $message = sprintf('%s. Did you mean "%s"', $message, implode('", "', $alternatives)); + } + + throw new Twig_Error_Syntax($message, $line, $parser->getFilename()); + } + + if ($testMap[$name] instanceof Twig_SimpleTest) { + return $testMap[$name]->getNodeClass(); } - return 'Twig_Node_Expression_Test'; + return $testMap[$name] instanceof Twig_Test_Node ? $testMap[$name]->getClass() : 'Twig_Node_Expression_Test'; } /** @@ -299,18 +308,18 @@ public function getName() /** * Cycles over a value. * - * @param ArrayAccess|array $values An array or an ArrayAccess instance - * @param integer $i The cycle value + * @param ArrayAccess|array $values An array or an ArrayAccess instance + * @param integer $position The cycle position * * @return string The next value in the cycle */ -function twig_cycle($values, $i) +function twig_cycle($values, $position) { if (!is_array($values) && !$values instanceof ArrayAccess) { return $values; } - return $values[$i % count($values)]; + return $values[$position % count($values)]; } /** @@ -404,7 +413,7 @@ function twig_date_format_filter(Twig_Environment $env, $date, $format = null, $ * Returns a new date object modified * * <pre> - * {{ post.published_at|modify("-1day")|date("m/d/Y") }} + * {{ post.published_at|date_modify("-1day")|date("m/d/Y") }} * </pre> * * @param Twig_Environment $env A Twig_Environment instance @@ -773,18 +782,16 @@ function twig_sort_filter($array) /* used internally */ function twig_in_filter($value, $compare) { - $strict = is_object($value); - if (is_array($compare)) { - return in_array($value, $compare, $strict); + return in_array($value, $compare, is_object($value)); } elseif (is_string($compare)) { - if (!strlen((string) $value)) { + if (!strlen($value)) { return empty($compare); } return false !== strpos($compare, (string) $value); - } elseif (is_object($compare) && $compare instanceof Traversable) { - return in_array($value, iterator_to_array($compare, false), $strict); + } elseif ($compare instanceof Traversable) { + return in_array($value, iterator_to_array($compare, false), is_object($value)); } return false; @@ -1191,7 +1198,7 @@ function twig_test_empty($value) return 0 == count($value); } - return false === $value || (empty($value) && '0' != $value); + return '' === $value || false === $value || null === $value || array() === $value; } /** @@ -1212,3 +1219,58 @@ function twig_test_iterable($value) { return $value instanceof Traversable || is_array($value); } + +/** + * Renders a template. + * + * @param string template The template to render + * @param array variables The variables to pass to the template + * @param Boolean with_context Whether to pass the current context variables or not + * @param Boolean ignore_missing Whether to ignore missing templates or not + * @param Boolean sandboxed Whether to sandbox the template or not + * + * @return string The rendered template + */ +function twig_include(Twig_Environment $env, $context, $template, $variables = array(), $withContext = true, $ignoreMissing = false, $sandboxed = false) +{ + if ($withContext) { + $variables = array_merge($context, $variables); + } + + if ($isSandboxed = $sandboxed && $env->hasExtension('sandbox')) { + $sandbox = $env->getExtension('sandbox'); + if (!$alreadySandboxed = $sandbox->isSandboxed()) { + $sandbox->enableSandbox(); + } + } + + try { + return $env->resolveTemplate($template)->display($variables); + } catch (Twig_Error_Loader $e) { + if (!$ignoreMissing) { + throw $e; + } + } + + if ($isSandboxed && !$alreadySandboxed) { + $sandbox->disableSandbox(); + } +} + +/** + * Provides the ability to get constants from instances as well as class/global constants. + * + * @param string $constant The name of the constant + * @param null|object $object The object to get the constant from + * + * @return string + */ +function twig_constant($constant, $object = null) +{ + if (!$object) { + return constant($constant); + } + $class = get_class($object); + + return constant($class.'::'.$constant); +} diff --git a/core/vendor/twig/twig/lib/Twig/Extension/Debug.php b/core/vendor/twig/twig/lib/Twig/Extension/Debug.php index 3dc4d2d20ed6..97007fb1dbef 100644 --- a/core/vendor/twig/twig/lib/Twig/Extension/Debug.php +++ b/core/vendor/twig/twig/lib/Twig/Extension/Debug.php @@ -27,7 +27,7 @@ public function getFunctions() ; return array( - 'dump' => new Twig_Function_Function('twig_var_dump', array('is_safe' => $isDumpOutputHtmlSafe ? array('html') : array(), 'needs_context' => true, 'needs_environment' => true)), + new Twig_SimpleFunction('dump', 'twig_var_dump', array('is_safe' => $isDumpOutputHtmlSafe ? array('html') : array(), 'needs_context' => true, 'needs_environment' => true)), ); } diff --git a/core/vendor/twig/twig/lib/Twig/Extension/Escaper.php b/core/vendor/twig/twig/lib/Twig/Extension/Escaper.php index db1a50ef085c..c9a7f68e783e 100644 --- a/core/vendor/twig/twig/lib/Twig/Extension/Escaper.php +++ b/core/vendor/twig/twig/lib/Twig/Extension/Escaper.php @@ -45,7 +45,7 @@ public function getNodeVisitors() public function getFilters() { return array( - 'raw' => new Twig_Filter_Function('twig_raw_filter', array('is_safe' => array('all'))), + new Twig_SimpleFilter('raw', 'twig_raw_filter', array('is_safe' => array('all'))), ); } diff --git a/core/vendor/twig/twig/lib/Twig/Extension/Staging.php b/core/vendor/twig/twig/lib/Twig/Extension/Staging.php new file mode 100644 index 000000000000..f67fc6576455 --- /dev/null +++ b/core/vendor/twig/twig/lib/Twig/Extension/Staging.php @@ -0,0 +1,114 @@ +<?php + +/* + * This file is part of Twig. + * + * (c) 2012 Fabien Potencier + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * Internal class. + * + * This class is used by Twig_Environment as a staging area and must not be used directly. + * + * @package twig + * @author Fabien Potencier <fabien@symfony.com> + */ +class Twig_Extension_Staging extends Twig_Extension +{ + protected $functions = array(); + protected $filters = array(); + protected $visitors = array(); + protected $tokenParsers = array(); + protected $globals = array(); + protected $tests = array(); + + public function addFunction($name, $function) + { + $this->functions[$name] = $function; + } + + /** + * {@inheritdoc} + */ + public function getFunctions() + { + return $this->functions; + } + + public function addFilter($name, $filter) + { + $this->filters[$name] = $filter; + } + + /** + * {@inheritdoc} + */ + public function getFilters() + { + return $this->filters; + } + + public function addNodeVisitor(Twig_NodeVisitorInterface $visitor) + { + $this->visitors[] = $visitor; + } + + /** + * {@inheritdoc} + */ + public function getNodeVisitors() + { + return $this->visitors; + } + + public function addTokenParser(Twig_TokenParserInterface $parser) + { + $this->tokenParsers[] = $parser; + } + + /** + * {@inheritdoc} + */ + public function getTokenParsers() + { + return $this->tokenParsers; + } + + public function addGlobal($name, $value) + { + $this->globals[$name] = $value; + } + + /** + * {@inheritdoc} + */ + public function getGlobals() + { + return $this->globals; + } + + public function addTest($name, $test) + { + $this->tests[$name] = $test; + } + + /** + * {@inheritdoc} + */ + public function getTests() + { + return $this->tests; + } + + /** + * {@inheritdoc} + */ + public function getName() + { + return 'staging'; + } +} diff --git a/core/vendor/twig/twig/lib/Twig/Extension/StringLoader.php b/core/vendor/twig/twig/lib/Twig/Extension/StringLoader.php index 90caf28a8c5f..d5b881bf2bd7 100644 --- a/core/vendor/twig/twig/lib/Twig/Extension/StringLoader.php +++ b/core/vendor/twig/twig/lib/Twig/Extension/StringLoader.php @@ -16,7 +16,7 @@ class Twig_Extension_StringLoader extends Twig_Extension public function getFunctions() { return array( - 'template_from_string' => new Twig_Function_Function('twig_template_from_string', array('needs_environment' => true)), + new Twig_SimpleFunction('template_from_string', 'twig_template_from_string', array('needs_environment' => true)), ); } diff --git a/core/vendor/twig/twig/lib/Twig/Filter.php b/core/vendor/twig/twig/lib/Twig/Filter.php index 1a4806cba3bc..879ef672335c 100644 --- a/core/vendor/twig/twig/lib/Twig/Filter.php +++ b/core/vendor/twig/twig/lib/Twig/Filter.php @@ -12,10 +12,13 @@ /** * Represents a template filter. * + * Use Twig_SimpleFilter instead. + * * @package twig * @author Fabien Potencier <fabien@symfony.com> + * @deprecated since 1.12 (to be removed in 2.0) */ -abstract class Twig_Filter implements Twig_FilterInterface +abstract class Twig_Filter implements Twig_FilterInterface, Twig_FilterCallableInterface { protected $options; protected $arguments = array(); @@ -27,6 +30,7 @@ public function __construct(array $options = array()) 'needs_context' => false, 'pre_escape' => null, 'preserves_safety' => null, + 'callable' => null, ), $options); } @@ -72,4 +76,9 @@ public function getPreEscape() { return $this->options['pre_escape']; } + + public function getCallable() + { + return $this->options['callable']; + } } diff --git a/core/vendor/twig/twig/lib/Twig/Filter/Function.php b/core/vendor/twig/twig/lib/Twig/Filter/Function.php index 1de078b2720d..ae1f9613f3c2 100644 --- a/core/vendor/twig/twig/lib/Twig/Filter/Function.php +++ b/core/vendor/twig/twig/lib/Twig/Filter/Function.php @@ -12,8 +12,11 @@ /** * Represents a function template filter. * + * Use Twig_SimpleFilter instead. + * * @package twig * @author Fabien Potencier <fabien@symfony.com> + * @deprecated since 1.12 (to be removed in 2.0) */ class Twig_Filter_Function extends Twig_Filter { @@ -21,6 +24,8 @@ class Twig_Filter_Function extends Twig_Filter public function __construct($function, array $options = array()) { + $options['callable'] = $function; + parent::__construct($options); $this->function = $function; diff --git a/core/vendor/twig/twig/lib/Twig/Filter/Method.php b/core/vendor/twig/twig/lib/Twig/Filter/Method.php index a680f61d81b4..074371abeeeb 100644 --- a/core/vendor/twig/twig/lib/Twig/Filter/Method.php +++ b/core/vendor/twig/twig/lib/Twig/Filter/Method.php @@ -12,8 +12,11 @@ /** * Represents a method template filter. * + * Use Twig_SimpleFilter instead. + * * @package twig * @author Fabien Potencier <fabien@symfony.com> + * @deprecated since 1.12 (to be removed in 2.0) */ class Twig_Filter_Method extends Twig_Filter { @@ -22,6 +25,8 @@ class Twig_Filter_Method extends Twig_Filter public function __construct(Twig_ExtensionInterface $extension, $method, array $options = array()) { + $options['callable'] = array($extension, $method); + parent::__construct($options); $this->extension = $extension; diff --git a/core/vendor/twig/twig/lib/Twig/Filter/Node.php b/core/vendor/twig/twig/lib/Twig/Filter/Node.php index 7481c05caa6f..4d27c939902d 100644 --- a/core/vendor/twig/twig/lib/Twig/Filter/Node.php +++ b/core/vendor/twig/twig/lib/Twig/Filter/Node.php @@ -12,8 +12,11 @@ /** * Represents a template filter as a node. * + * Use Twig_SimpleFilter instead. + * * @package twig * @author Fabien Potencier <fabien@symfony.com> + * @deprecated since 1.12 (to be removed in 2.0) */ class Twig_Filter_Node extends Twig_Filter { diff --git a/core/vendor/twig/twig/lib/Twig/FilterCallableInterface.php b/core/vendor/twig/twig/lib/Twig/FilterCallableInterface.php new file mode 100644 index 000000000000..97c7610ef526 --- /dev/null +++ b/core/vendor/twig/twig/lib/Twig/FilterCallableInterface.php @@ -0,0 +1,24 @@ +<?php + +/* + * This file is part of Twig. + * + * (c) 2012 Fabien Potencier + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * Represents a callable template filter. + * + * Use Twig_SimpleFilter instead. + * + * @package twig + * @author Fabien Potencier <fabien@symfony.com> + * @deprecated since 1.12 (to be removed in 2.0) + */ +interface Twig_FilterCallableInterface +{ + public function getCallable(); +} diff --git a/core/vendor/twig/twig/lib/Twig/FilterInterface.php b/core/vendor/twig/twig/lib/Twig/FilterInterface.php index 0a07c7c39e80..0c7f0a48e8a8 100644 --- a/core/vendor/twig/twig/lib/Twig/FilterInterface.php +++ b/core/vendor/twig/twig/lib/Twig/FilterInterface.php @@ -12,8 +12,11 @@ /** * Represents a template filter. * + * Use Twig_SimpleFilter instead. + * * @package twig * @author Fabien Potencier <fabien@symfony.com> + * @deprecated since 1.12 (to be removed in 2.0) */ interface Twig_FilterInterface { diff --git a/core/vendor/twig/twig/lib/Twig/Function.php b/core/vendor/twig/twig/lib/Twig/Function.php index cd7643f021ed..b30c30ee9514 100644 --- a/core/vendor/twig/twig/lib/Twig/Function.php +++ b/core/vendor/twig/twig/lib/Twig/Function.php @@ -12,10 +12,13 @@ /** * Represents a template function. * + * Use Twig_SimpleFunction instead. + * * @package twig * @author Fabien Potencier <fabien@symfony.com> + * @deprecated since 1.12 (to be removed in 2.0) */ -abstract class Twig_Function implements Twig_FunctionInterface +abstract class Twig_Function implements Twig_FunctionInterface, Twig_FunctionCallableInterface { protected $options; protected $arguments = array(); @@ -25,6 +28,7 @@ public function __construct(array $options = array()) $this->options = array_merge(array( 'needs_environment' => false, 'needs_context' => false, + 'callable' => null, ), $options); } @@ -60,4 +64,9 @@ public function getSafe(Twig_Node $functionArgs) return array(); } + + public function getCallable() + { + return $this->options['callable']; + } } diff --git a/core/vendor/twig/twig/lib/Twig/Function/Function.php b/core/vendor/twig/twig/lib/Twig/Function/Function.php index 3237d8c5dab9..7e5c9c236c2e 100644 --- a/core/vendor/twig/twig/lib/Twig/Function/Function.php +++ b/core/vendor/twig/twig/lib/Twig/Function/Function.php @@ -13,8 +13,11 @@ /** * Represents a function template function. * + * Use Twig_SimpleFunction instead. + * * @package twig * @author Arnaud Le Blanc <arnaud.lb@gmail.com> + * @deprecated since 1.12 (to be removed in 2.0) */ class Twig_Function_Function extends Twig_Function { @@ -22,6 +25,8 @@ class Twig_Function_Function extends Twig_Function public function __construct($function, array $options = array()) { + $options['callable'] = $function; + parent::__construct($options); $this->function = $function; diff --git a/core/vendor/twig/twig/lib/Twig/Function/Method.php b/core/vendor/twig/twig/lib/Twig/Function/Method.php index 88386188bc24..a13741eae1c2 100644 --- a/core/vendor/twig/twig/lib/Twig/Function/Method.php +++ b/core/vendor/twig/twig/lib/Twig/Function/Method.php @@ -13,8 +13,11 @@ /** * Represents a method template function. * + * Use Twig_SimpleFunction instead. + * * @package twig * @author Arnaud Le Blanc <arnaud.lb@gmail.com> + * @deprecated since 1.12 (to be removed in 2.0) */ class Twig_Function_Method extends Twig_Function { @@ -23,6 +26,8 @@ class Twig_Function_Method extends Twig_Function public function __construct(Twig_ExtensionInterface $extension, $method, array $options = array()) { + $options['callable'] = array($extension, $method); + parent::__construct($options); $this->extension = $extension; diff --git a/core/vendor/twig/twig/lib/Twig/Function/Node.php b/core/vendor/twig/twig/lib/Twig/Function/Node.php index df937e500972..068c5fd31ccb 100644 --- a/core/vendor/twig/twig/lib/Twig/Function/Node.php +++ b/core/vendor/twig/twig/lib/Twig/Function/Node.php @@ -12,8 +12,11 @@ /** * Represents a template function as a node. * + * Use Twig_SimpleFunction instead. + * * @package twig * @author Fabien Potencier <fabien@symfony.com> + * @deprecated since 1.12 (to be removed in 2.0) */ class Twig_Function_Node extends Twig_Function { diff --git a/core/vendor/twig/twig/lib/Twig/FunctionCallableInterface.php b/core/vendor/twig/twig/lib/Twig/FunctionCallableInterface.php new file mode 100644 index 000000000000..dfd6f7503171 --- /dev/null +++ b/core/vendor/twig/twig/lib/Twig/FunctionCallableInterface.php @@ -0,0 +1,24 @@ +<?php + +/* + * This file is part of Twig. + * + * (c) 2012 Fabien Potencier + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * Represents a callable template function. + * + * Use Twig_SimpleFunction instead. + * + * @package twig + * @author Fabien Potencier <fabien@symfony.com> + * @deprecated since 1.12 (to be removed in 2.0) + */ +interface Twig_FunctionCallableInterface +{ + public function getCallable(); +} diff --git a/core/vendor/twig/twig/lib/Twig/FunctionInterface.php b/core/vendor/twig/twig/lib/Twig/FunctionInterface.php index d652ac3c02c1..1c03cbd2e09a 100644 --- a/core/vendor/twig/twig/lib/Twig/FunctionInterface.php +++ b/core/vendor/twig/twig/lib/Twig/FunctionInterface.php @@ -13,8 +13,11 @@ /** * Represents a template function. * + * Use Twig_SimpleFunction instead. + * * @package twig * @author Arnaud Le Blanc <arnaud.lb@gmail.com> + * @deprecated since 1.12 (to be removed in 2.0) */ interface Twig_FunctionInterface { diff --git a/core/vendor/twig/twig/lib/Twig/Lexer.php b/core/vendor/twig/twig/lib/Twig/Lexer.php index d77071d34475..3be72159dafe 100644 --- a/core/vendor/twig/twig/lib/Twig/Lexer.php +++ b/core/vendor/twig/twig/lib/Twig/Lexer.php @@ -61,10 +61,10 @@ public function __construct(Twig_Environment $env, array $options = array()) $this->regexes = array( 'lex_var' => '/\s*'.preg_quote($this->options['whitespace_trim'].$this->options['tag_variable'][1], '/').'\s*|\s*'.preg_quote($this->options['tag_variable'][1], '/').'/A', 'lex_block' => '/\s*(?:'.preg_quote($this->options['whitespace_trim'].$this->options['tag_block'][1], '/').'\s*|\s*'.preg_quote($this->options['tag_block'][1], '/').')\n?/A', - 'lex_raw_data' => '/('.preg_quote($this->options['tag_block'][0].$this->options['whitespace_trim'], '/').'|'.preg_quote($this->options['tag_block'][0], '/').')\s*endraw\s*(?:'.preg_quote($this->options['whitespace_trim'].$this->options['tag_block'][1], '/').'\s*|\s*'.preg_quote($this->options['tag_block'][1], '/').')/s', + 'lex_raw_data' => '/('.preg_quote($this->options['tag_block'][0].$this->options['whitespace_trim'], '/').'|'.preg_quote($this->options['tag_block'][0], '/').')\s*(?:end%s)\s*(?:'.preg_quote($this->options['whitespace_trim'].$this->options['tag_block'][1], '/').'\s*|\s*'.preg_quote($this->options['tag_block'][1], '/').')/s', 'operator' => $this->getOperatorRegex(), 'lex_comment' => '/(?:'.preg_quote($this->options['whitespace_trim'], '/').preg_quote($this->options['tag_comment'][1], '/').'\s*|'.preg_quote($this->options['tag_comment'][1], '/').')\n?/s', - 'lex_block_raw' => '/\s*raw\s*(?:'.preg_quote($this->options['whitespace_trim'].$this->options['tag_block'][1], '/').'\s*|\s*'.preg_quote($this->options['tag_block'][1], '/').')/As', + 'lex_block_raw' => '/\s*(raw|verbatim)\s*(?:'.preg_quote($this->options['whitespace_trim'].$this->options['tag_block'][1], '/').'\s*|\s*'.preg_quote($this->options['tag_block'][1], '/').')/As', 'lex_block_line' => '/\s*line\s+(\d+)\s*'.preg_quote($this->options['tag_block'][1], '/').'/As', 'lex_tokens_start' => '/('.preg_quote($this->options['tag_variable'][0], '/').'|'.preg_quote($this->options['tag_block'][0], '/').'|'.preg_quote($this->options['tag_comment'][0], '/').')('.preg_quote($this->options['whitespace_trim'], '/').')?/s', 'interpolation_start' => '/'.preg_quote($this->options['interpolation'][0], '/').'\s*/A', @@ -178,7 +178,7 @@ protected function lexData() // raw data? if (preg_match($this->regexes['lex_block_raw'], $this->code, $match, null, $this->cursor)) { $this->moveCursor($match[0]); - $this->lexRawData(); + $this->lexRawData($match[1]); // {% line \d+ %} } elseif (preg_match($this->regexes['lex_block_line'], $this->code, $match, null, $this->cursor)) { $this->moveCursor($match[0]); @@ -286,10 +286,10 @@ protected function lexExpression() } } - protected function lexRawData() + protected function lexRawData($tag) { - if (!preg_match($this->regexes['lex_raw_data'], $this->code, $match, PREG_OFFSET_CAPTURE, $this->cursor)) { - throw new Twig_Error_Syntax(sprintf('Unexpected end of file: Unclosed "block"'), $this->lineno, $this->filename); + if (!preg_match(str_replace('%s', $tag, $this->regexes['lex_raw_data']), $this->code, $match, PREG_OFFSET_CAPTURE, $this->cursor)) { + throw new Twig_Error_Syntax(sprintf('Unexpected end of file: Unclosed "%s" block', $tag), $this->lineno, $this->filename); } $text = substr($this->code, $this->cursor, $match[0][1] - $this->cursor); diff --git a/core/vendor/twig/twig/lib/Twig/LexerInterface.php b/core/vendor/twig/twig/lib/Twig/LexerInterface.php index 9c3d3d2ac23f..6fd4db521af2 100644 --- a/core/vendor/twig/twig/lib/Twig/LexerInterface.php +++ b/core/vendor/twig/twig/lib/Twig/LexerInterface.php @@ -14,6 +14,7 @@ * * @package twig * @author Fabien Potencier <fabien@symfony.com> + * @deprecated since 1.12 (to be removed in 2.0) */ interface Twig_LexerInterface { diff --git a/core/vendor/twig/twig/lib/Twig/Node/Expression/Call.php b/core/vendor/twig/twig/lib/Twig/Node/Expression/Call.php new file mode 100644 index 000000000000..a97b3b572c59 --- /dev/null +++ b/core/vendor/twig/twig/lib/Twig/Node/Expression/Call.php @@ -0,0 +1,171 @@ +<?php + +/* + * This file is part of Twig. + * + * (c) 2012 Fabien Potencier + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +abstract class Twig_Node_Expression_Call extends Twig_Node_Expression +{ + protected function compileCallable(Twig_Compiler $compiler) + { + $callable = $this->getAttribute('callable'); + + $closingParenthesis = false; + if ($callable) { + if (is_string($callable)) { + $compiler->raw($callable); + } elseif (is_array($callable) && $callable[0] instanceof Twig_ExtensionInterface) { + $compiler->raw(sprintf('$this->env->getExtension(\'%s\')->%s', $callable[0]->getName(), $callable[1])); + } else { + $type = ucfirst($this->getAttribute('type')); + $compiler->raw(sprintf('call_user_func_array($this->env->get%s(\'%s\')->getCallable(), array', $type, $this->getAttribute('name'))); + $closingParenthesis = true; + } + } else { + $compiler->raw($this->getAttribute('thing')->compile()); + } + + $this->compileArguments($compiler); + + if ($closingParenthesis) { + $compiler->raw(')'); + } + } + + protected function compileArguments(Twig_Compiler $compiler) + { + $compiler->raw('('); + + $first = true; + + if ($this->hasAttribute('needs_environment') && $this->getAttribute('needs_environment')) { + $compiler->raw('$this->env'); + $first = false; + } + + if ($this->hasAttribute('needs_context') && $this->getAttribute('needs_context')) { + if (!$first) { + $compiler->raw(', '); + } + $compiler->raw('$context'); + $first = false; + } + + if ($this->hasAttribute('arguments')) { + foreach ($this->getAttribute('arguments') as $argument) { + if (!$first) { + $compiler->raw(', '); + } + $compiler->string($argument); + $first = false; + } + } + + if ($this->hasNode('node')) { + if (!$first) { + $compiler->raw(', '); + } + $compiler->subcompile($this->getNode('node')); + $first = false; + } + + if ($this->hasNode('arguments') && null !== $this->getNode('arguments')) { + $callable = $this->hasAttribute('callable') ? $this->getAttribute('callable') : null; + + $arguments = $this->getArguments($callable, $this->getNode('arguments')); + + foreach ($arguments as $node) { + if (!$first) { + $compiler->raw(', '); + } + $compiler->subcompile($node); + $first = false; + } + } + + $compiler->raw(')'); + } + + protected function getArguments($callable, $arguments) + { + $parameters = array(); + $named = false; + foreach ($arguments as $name => $node) { + if (!is_int($name)) { + $named = true; + $name = $this->normalizeName($name); + } + $parameters[$name] = $node; + } + + if (!$named) { + return $parameters; + } + + if (!$callable) { + throw new LogicException(sprintf('Named arguments are not supported for %s "%s".', $this->getAttribute('type'), $this->getAttribute('name'))); + } + + // manage named arguments + if (is_array($callable)) { + $r = new ReflectionMethod($callable[0], $callable[1]); + } elseif (is_object($callable) && !$callable instanceof Closure) { + $r = new ReflectionObject($callable); + $r = $r->getMethod('__invoke'); + } else { + $r = new ReflectionFunction($callable); + } + + $definition = $r->getParameters(); + if ($this->hasNode('node')) { + array_shift($definition); + } + if ($this->hasAttribute('needs_environment') && $this->getAttribute('needs_environment')) { + array_shift($definition); + } + if ($this->hasAttribute('needs_context') && $this->getAttribute('needs_context')) { + array_shift($definition); + } + if ($this->hasAttribute('arguments') && null !== $this->getAttribute('arguments')) { + foreach ($this->getAttribute('arguments') as $argument) { + array_shift($definition); + } + } + + $arguments = array(); + $pos = 0; + foreach ($definition as $param) { + $name = $this->normalizeName($param->name); + + if (array_key_exists($name, $parameters)) { + $arguments[] = $parameters[$name]; + unset($parameters[$name]); + } elseif (array_key_exists($pos, $parameters)) { + $arguments[] = $parameters[$pos]; + unset($parameters[$pos]); + ++$pos; + } elseif ($param->isDefaultValueAvailable()) { + $arguments[] = new Twig_Node_Expression_Constant($param->getDefaultValue(), -1); + } elseif ($param->isOptional()) { + break; + } else { + throw new Twig_Error_Syntax(sprintf('Value for argument "%s" is required for %s "%s".', $name, $this->getAttribute('type'), $this->getAttribute('name'))); + } + } + + foreach (array_keys($parameters) as $name) { + throw new Twig_Error_Syntax(sprintf('Unknown argument "%s" for %s "%s".', $name, $this->getAttribute('type'), $this->getAttribute('name'))); + } + + return $arguments; + } + + protected function normalizeName($name) + { + return strtolower(preg_replace(array('/([A-Z]+)([A-Z][a-z])/', '/([a-z\d])([A-Z])/'), array('\\1_\\2', '\\1_\\2'), $name)); + } +} diff --git a/core/vendor/twig/twig/lib/Twig/Node/Expression/Filter.php b/core/vendor/twig/twig/lib/Twig/Node/Expression/Filter.php index eb9cd310f8c0..207b062a3aff 100644 --- a/core/vendor/twig/twig/lib/Twig/Node/Expression/Filter.php +++ b/core/vendor/twig/twig/lib/Twig/Node/Expression/Filter.php @@ -9,7 +9,7 @@ * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ -class Twig_Node_Expression_Filter extends Twig_Node_Expression +class Twig_Node_Expression_Filter extends Twig_Node_Expression_Call { public function __construct(Twig_NodeInterface $node, Twig_Node_Expression_Constant $filterName, Twig_NodeInterface $arguments, $lineno, $tag = null) { @@ -19,43 +19,18 @@ public function __construct(Twig_NodeInterface $node, Twig_Node_Expression_Const public function compile(Twig_Compiler $compiler) { $name = $this->getNode('filter')->getAttribute('value'); - - if (false === $filter = $compiler->getEnvironment()->getFilter($name)) { - $message = sprintf('The filter "%s" does not exist', $name); - if ($alternatives = $compiler->getEnvironment()->computeAlternatives($name, array_keys($compiler->getEnvironment()->getFilters()))) { - $message = sprintf('%s. Did you mean "%s"', $message, implode('", "', $alternatives)); - } - - throw new Twig_Error_Syntax($message, $this->getLine(), $compiler->getFilename()); - } - - $this->compileFilter($compiler, $filter); - } - - protected function compileFilter(Twig_Compiler $compiler, Twig_FilterInterface $filter) - { - $compiler - ->raw($filter->compile().'(') - ->raw($filter->needsEnvironment() ? '$this->env, ' : '') - ->raw($filter->needsContext() ? '$context, ' : '') - ; - - foreach ($filter->getArguments() as $argument) { - $compiler - ->string($argument) - ->raw(', ') - ; - } - - $compiler->subcompile($this->getNode('node')); - - foreach ($this->getNode('arguments') as $node) { - $compiler - ->raw(', ') - ->subcompile($node) - ; + $filter = $compiler->getEnvironment()->getFilter($name); + + $this->setAttribute('name', $name); + $this->setAttribute('type', 'filter'); + $this->setAttribute('thing', $filter); + $this->setAttribute('needs_environment', $filter->needsEnvironment()); + $this->setAttribute('needs_context', $filter->needsContext()); + $this->setAttribute('arguments', $filter->getArguments()); + if ($filter instanceof Twig_FilterCallableInterface || $filter instanceof Twig_SimpleFilter) { + $this->setAttribute('callable', $filter->getCallable()); } - $compiler->raw(')'); + $this->compileCallable($compiler); } } diff --git a/core/vendor/twig/twig/lib/Twig/Node/Expression/Filter/Default.php b/core/vendor/twig/twig/lib/Twig/Node/Expression/Filter/Default.php index 1cb334281267..fccd39aefac8 100644 --- a/core/vendor/twig/twig/lib/Twig/Node/Expression/Filter/Default.php +++ b/core/vendor/twig/twig/lib/Twig/Node/Expression/Filter/Default.php @@ -23,7 +23,7 @@ class Twig_Node_Expression_Filter_Default extends Twig_Node_Expression_Filter { public function __construct(Twig_NodeInterface $node, Twig_Node_Expression_Constant $filterName, Twig_NodeInterface $arguments, $lineno, $tag = null) { - $default = new Twig_Node_Expression_Filter($node, new Twig_Node_Expression_Constant('_default', $node->getLine()), $arguments, $node->getLine()); + $default = new Twig_Node_Expression_Filter($node, new Twig_Node_Expression_Constant('default', $node->getLine()), $arguments, $node->getLine()); if ('default' === $filterName->getAttribute('value') && ($node instanceof Twig_Node_Expression_Name || $node instanceof Twig_Node_Expression_GetAttr)) { $test = new Twig_Node_Expression_Test_Defined(clone $node, 'defined', new Twig_Node(), $node->getLine()); diff --git a/core/vendor/twig/twig/lib/Twig/Node/Expression/Function.php b/core/vendor/twig/twig/lib/Twig/Node/Expression/Function.php index 56403775a6fd..3e1f6b559099 100644 --- a/core/vendor/twig/twig/lib/Twig/Node/Expression/Function.php +++ b/core/vendor/twig/twig/lib/Twig/Node/Expression/Function.php @@ -8,7 +8,7 @@ * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ -class Twig_Node_Expression_Function extends Twig_Node_Expression +class Twig_Node_Expression_Function extends Twig_Node_Expression_Call { public function __construct($name, Twig_NodeInterface $arguments, $lineno) { @@ -18,49 +18,18 @@ public function __construct($name, Twig_NodeInterface $arguments, $lineno) public function compile(Twig_Compiler $compiler) { $name = $this->getAttribute('name'); - - if (false === $function = $compiler->getEnvironment()->getFunction($name)) { - $message = sprintf('The function "%s" does not exist', $name); - if ($alternatives = $compiler->getEnvironment()->computeAlternatives($name, array_keys($compiler->getEnvironment()->getFunctions()))) { - $message = sprintf('%s. Did you mean "%s"', $message, implode('", "', $alternatives)); - } - - throw new Twig_Error_Syntax($message, $this->getLine(), $compiler->getFilename()); - } - - $compiler->raw($function->compile().'('); - - $first = true; - - if ($function->needsEnvironment()) { - $compiler->raw('$this->env'); - $first = false; - } - - if ($function->needsContext()) { - if (!$first) { - $compiler->raw(', '); - } - $compiler->raw('$context'); - $first = false; - } - - foreach ($function->getArguments() as $argument) { - if (!$first) { - $compiler->raw(', '); - } - $compiler->string($argument); - $first = false; - } - - foreach ($this->getNode('arguments') as $node) { - if (!$first) { - $compiler->raw(', '); - } - $compiler->subcompile($node); - $first = false; + $function = $compiler->getEnvironment()->getFunction($name); + + $this->setAttribute('name', $name); + $this->setAttribute('type', 'function'); + $this->setAttribute('thing', $function); + $this->setAttribute('needs_environment', $function->needsEnvironment()); + $this->setAttribute('needs_context', $function->needsContext()); + $this->setAttribute('arguments', $function->getArguments()); + if ($function instanceof Twig_FunctionCallableInterface || $function instanceof Twig_SimpleFunction) { + $this->setAttribute('callable', $function->getCallable()); } - $compiler->raw(')'); + $this->compileCallable($compiler); } } diff --git a/core/vendor/twig/twig/lib/Twig/Node/Expression/Test.php b/core/vendor/twig/twig/lib/Twig/Node/Expression/Test.php index 076e39dae2b6..639f501a1869 100644 --- a/core/vendor/twig/twig/lib/Twig/Node/Expression/Test.php +++ b/core/vendor/twig/twig/lib/Twig/Node/Expression/Test.php @@ -8,7 +8,7 @@ * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ -class Twig_Node_Expression_Test extends Twig_Node_Expression +class Twig_Node_Expression_Test extends Twig_Node_Expression_Call { public function __construct(Twig_NodeInterface $node, $name, Twig_NodeInterface $arguments = null, $lineno) { @@ -18,37 +18,15 @@ public function __construct(Twig_NodeInterface $node, $name, Twig_NodeInterface public function compile(Twig_Compiler $compiler) { $name = $this->getAttribute('name'); - $testMap = $compiler->getEnvironment()->getTests(); - if (!isset($testMap[$name])) { - $message = sprintf('The test "%s" does not exist', $name); - if ($alternatives = $compiler->getEnvironment()->computeAlternatives($name, array_keys($compiler->getEnvironment()->getTests()))) { - $message = sprintf('%s. Did you mean "%s"', $message, implode('", "', $alternatives)); - } + $test = $compiler->getEnvironment()->getTest($name); - throw new Twig_Error_Syntax($message, $this->getLine(), $compiler->getFilename()); + $this->setAttribute('name', $name); + $this->setAttribute('type', 'test'); + $this->setAttribute('thing', $test); + if ($test instanceof Twig_TestCallableInterface || $test instanceof Twig_SimpleTest) { + $this->setAttribute('callable', $test->getCallable()); } - $name = $this->getAttribute('name'); - $node = $this->getNode('node'); - - $compiler - ->raw($testMap[$name]->compile().'(') - ->subcompile($node) - ; - - if (null !== $this->getNode('arguments')) { - $compiler->raw(', '); - - $max = count($this->getNode('arguments')) - 1; - foreach ($this->getNode('arguments') as $i => $arg) { - $compiler->subcompile($arg); - - if ($i != $max) { - $compiler->raw(', '); - } - } - } - - $compiler->raw(')'); + $this->compileCallable($compiler); } } diff --git a/core/vendor/twig/twig/lib/Twig/Node/Macro.php b/core/vendor/twig/twig/lib/Twig/Node/Macro.php index 8bb5d9dfbe49..347e4b23e71d 100644 --- a/core/vendor/twig/twig/lib/Twig/Node/Macro.php +++ b/core/vendor/twig/twig/lib/Twig/Node/Macro.php @@ -29,14 +29,27 @@ public function __construct($name, Twig_NodeInterface $body, Twig_NodeInterface */ public function compile(Twig_Compiler $compiler) { - $arguments = array(); - foreach ($this->getNode('arguments') as $argument) { - $arguments[] = '$_'.$argument->getAttribute('name').' = null'; + $compiler + ->addDebugInfo($this) + ->write(sprintf("public function get%s(", $this->getAttribute('name'))) + ; + + $count = count($this->getNode('arguments')); + $pos = 0; + foreach ($this->getNode('arguments') as $name => $default) { + $compiler + ->raw('$_'.$name.' = ') + ->subcompile($default) + ; + + if (++$pos < $count) { + $compiler->raw(', '); + } } $compiler - ->addDebugInfo($this) - ->write(sprintf("public function get%s(%s)\n", $this->getAttribute('name'), implode(', ', $arguments)), "{\n") + ->raw(")\n") + ->write("{\n") ->indent() ; @@ -48,11 +61,11 @@ public function compile(Twig_Compiler $compiler) ->indent() ; - foreach ($this->getNode('arguments') as $argument) { + foreach ($this->getNode('arguments') as $name => $default) { $compiler ->write('') - ->string($argument->getAttribute('name')) - ->raw(' => $_'.$argument->getAttribute('name')) + ->string($name) + ->raw(' => $_'.$name) ->raw(",\n") ; } diff --git a/core/vendor/twig/twig/lib/Twig/NodeInterface.php b/core/vendor/twig/twig/lib/Twig/NodeInterface.php index e77782f974dc..44b953befcd5 100644 --- a/core/vendor/twig/twig/lib/Twig/NodeInterface.php +++ b/core/vendor/twig/twig/lib/Twig/NodeInterface.php @@ -14,6 +14,7 @@ * * @package twig * @author Fabien Potencier <fabien@symfony.com> + * @deprecated since 1.12 (to be removed in 2.0) */ interface Twig_NodeInterface extends Countable, IteratorAggregate { diff --git a/core/vendor/twig/twig/lib/Twig/NodeVisitor/Escaper.php b/core/vendor/twig/twig/lib/Twig/NodeVisitor/Escaper.php index cc9a58b12dc8..0d749fe7ba68 100644 --- a/core/vendor/twig/twig/lib/Twig/NodeVisitor/Escaper.php +++ b/core/vendor/twig/twig/lib/Twig/NodeVisitor/Escaper.php @@ -107,22 +107,18 @@ protected function preEscapeFilterNode(Twig_Node_Expression_Filter $filter, Twig { $name = $filter->getNode('filter')->getAttribute('value'); - if (false !== $f = $env->getFilter($name)) { - $type = $f->getPreEscape(); - if (null === $type) { - return $filter; - } - - $node = $filter->getNode('node'); - if ($this->isSafeFor($type, $node, $env)) { - return $filter; - } - - $filter->setNode('node', $this->getEscaperFilter($type, $node)); + $type = $env->getFilter($name)->getPreEscape(); + if (null === $type) { + return $filter; + } + $node = $filter->getNode('node'); + if ($this->isSafeFor($type, $node, $env)) { return $filter; } + $filter->setNode('node', $this->getEscaperFilter($type, $node)); + return $filter; } diff --git a/core/vendor/twig/twig/lib/Twig/ParserInterface.php b/core/vendor/twig/twig/lib/Twig/ParserInterface.php index 4de3999722c0..2783a68a5ff5 100644 --- a/core/vendor/twig/twig/lib/Twig/ParserInterface.php +++ b/core/vendor/twig/twig/lib/Twig/ParserInterface.php @@ -12,8 +12,9 @@ /** * Interface implemented by parser classes. * - * @package twig - * @author Fabien Potencier <fabien@symfony.com> + * @package twig + * @author Fabien Potencier <fabien@symfony.com> + * @deprecated since 1.12 (to be removed in 2.0) */ interface Twig_ParserInterface { diff --git a/core/vendor/twig/twig/lib/Twig/SimpleFilter.php b/core/vendor/twig/twig/lib/Twig/SimpleFilter.php new file mode 100644 index 000000000000..7089a9dfba9b --- /dev/null +++ b/core/vendor/twig/twig/lib/Twig/SimpleFilter.php @@ -0,0 +1,97 @@ +<?php + +/* + * This file is part of Twig. + * + * (c) 2009-2012 Fabien Potencier + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * Represents a template filter. + * + * @package twig + * @author Fabien Potencier <fabien@symfony.com> + */ +class Twig_SimpleFilter +{ + protected $name; + protected $callable; + protected $options; + protected $arguments = array(); + + public function __construct($name, $callable, array $options = array()) + { + $this->name = $name; + $this->callable = $callable; + $this->options = array_merge(array( + 'needs_environment' => false, + 'needs_context' => false, + 'is_safe' => null, + 'is_safe_callback' => null, + 'pre_escape' => null, + 'preserves_safety' => null, + 'node_class' => 'Twig_Node_Expression_Filter', + ), $options); + } + + public function getName() + { + return $this->name; + } + + public function getCallable() + { + return $this->callable; + } + + public function getNodeClass() + { + return $this->options['node_class']; + } + + public function setArguments($arguments) + { + $this->arguments = $arguments; + } + + public function getArguments() + { + return $this->arguments; + } + + public function needsEnvironment() + { + return $this->options['needs_environment']; + } + + public function needsContext() + { + return $this->options['needs_context']; + } + + public function getSafe(Twig_Node $filterArgs) + { + if (null !== $this->options['is_safe']) { + return $this->options['is_safe']; + } + + if (null !== $this->options['is_safe_callback']) { + return call_user_func($this->options['is_safe_callback'], $filterArgs); + } + + return null; + } + + public function getPreservesSafety() + { + return $this->options['preserves_safety']; + } + + public function getPreEscape() + { + return $this->options['pre_escape']; + } +} diff --git a/core/vendor/twig/twig/lib/Twig/SimpleFunction.php b/core/vendor/twig/twig/lib/Twig/SimpleFunction.php new file mode 100644 index 000000000000..9924154ef0f1 --- /dev/null +++ b/core/vendor/twig/twig/lib/Twig/SimpleFunction.php @@ -0,0 +1,85 @@ +<?php + +/* + * This file is part of Twig. + * + * (c) 2010-2012 Fabien Potencier + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * Represents a template function. + * + * @package twig + * @author Fabien Potencier <fabien@symfony.com> + */ +class Twig_SimpleFunction +{ + protected $name; + protected $callable; + protected $options; + protected $arguments = array(); + + public function __construct($name, $callable, array $options = array()) + { + $this->name = $name; + $this->callable = $callable; + $this->options = array_merge(array( + 'needs_environment' => false, + 'needs_context' => false, + 'is_safe' => null, + 'is_safe_callback' => null, + 'node_class' => 'Twig_Node_Expression_Function', + ), $options); + } + + public function getName() + { + return $this->name; + } + + public function getCallable() + { + return $this->callable; + } + + public function getNodeClass() + { + return $this->options['node_class']; + } + + public function setArguments($arguments) + { + $this->arguments = $arguments; + } + + public function getArguments() + { + return $this->arguments; + } + + public function needsEnvironment() + { + return $this->options['needs_environment']; + } + + public function needsContext() + { + return $this->options['needs_context']; + } + + public function getSafe(Twig_Node $functionArgs) + { + if (null !== $this->options['is_safe']) { + return $this->options['is_safe']; + } + + if (null !== $this->options['is_safe_callback']) { + return call_user_func($this->options['is_safe_callback'], $functionArgs); + } + + return array(); + } +} diff --git a/core/vendor/twig/twig/lib/Twig/SimpleTest.php b/core/vendor/twig/twig/lib/Twig/SimpleTest.php new file mode 100644 index 000000000000..7502c79eb77a --- /dev/null +++ b/core/vendor/twig/twig/lib/Twig/SimpleTest.php @@ -0,0 +1,47 @@ +<?php + +/* + * This file is part of Twig. + * + * (c) 2010-2012 Fabien Potencier + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * Represents a template test. + * + * @package twig + * @author Fabien Potencier <fabien@symfony.com> + */ +class Twig_SimpleTest +{ + protected $name; + protected $callable; + protected $options; + + public function __construct($name, $callable, array $options = array()) + { + $this->name = $name; + $this->callable = $callable; + $this->options = array_merge(array( + 'node_class' => 'Twig_Node_Expression_Test', + ), $options); + } + + public function getName() + { + return $this->name; + } + + public function getCallable() + { + return $this->callable; + } + + public function getNodeClass() + { + return $this->options['node_class']; + } +} diff --git a/core/vendor/twig/twig/lib/Twig/TemplateInterface.php b/core/vendor/twig/twig/lib/Twig/TemplateInterface.php index 5d7b02717bad..d2a2c398749e 100644 --- a/core/vendor/twig/twig/lib/Twig/TemplateInterface.php +++ b/core/vendor/twig/twig/lib/Twig/TemplateInterface.php @@ -12,8 +12,9 @@ /** * Interface implemented by all compiled templates. * - * @package twig - * @author Fabien Potencier <fabien@symfony.com> + * @package twig + * @author Fabien Potencier <fabien@symfony.com> + * @deprecated since 1.12 (to be removed in 2.0) */ interface Twig_TemplateInterface { diff --git a/core/vendor/twig/twig/lib/Twig/Test.php b/core/vendor/twig/twig/lib/Twig/Test.php new file mode 100644 index 000000000000..7fef1b476a14 --- /dev/null +++ b/core/vendor/twig/twig/lib/Twig/Test.php @@ -0,0 +1,35 @@ +<?php + +/* + * This file is part of Twig. + * + * (c) 2012 Fabien Potencier + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * Represents a template test. + * + * @package twig + * @author Fabien Potencier <fabien@symfony.com> + * @deprecated since 1.12 (to be removed in 2.0) + */ +abstract class Twig_Test implements Twig_TestInterface, Twig_TestCallableInterface +{ + protected $options; + protected $arguments = array(); + + public function __construct(array $options = array()) + { + $this->options = array_merge(array( + 'callable' => null, + ), $options); + } + + public function getCallable() + { + return $this->options['callable']; + } +} diff --git a/core/vendor/twig/twig/lib/Twig/Test/Function.php b/core/vendor/twig/twig/lib/Twig/Test/Function.php index 1240a0f12dc8..d0ff4904be77 100644 --- a/core/vendor/twig/twig/lib/Twig/Test/Function.php +++ b/core/vendor/twig/twig/lib/Twig/Test/Function.php @@ -14,13 +14,18 @@ * * @package twig * @author Fabien Potencier <fabien@symfony.com> + * @deprecated since 1.12 (to be removed in 2.0) */ -class Twig_Test_Function implements Twig_TestInterface +class Twig_Test_Function extends Twig_Test { protected $function; - public function __construct($function) + public function __construct($function, array $options = array()) { + $options['callable'] = $function; + + parent::__construct($options); + $this->function = $function; } diff --git a/core/vendor/twig/twig/lib/Twig/Test/Method.php b/core/vendor/twig/twig/lib/Twig/Test/Method.php index a8d1d9b042bf..5a5f37f3d9ac 100644 --- a/core/vendor/twig/twig/lib/Twig/Test/Method.php +++ b/core/vendor/twig/twig/lib/Twig/Test/Method.php @@ -14,14 +14,19 @@ * * @package twig * @author Fabien Potencier <fabien@symfony.com> + * @deprecated since 1.12 (to be removed in 2.0) */ -class Twig_Test_Method implements Twig_TestInterface +class Twig_Test_Method extends Twig_Test { protected $extension; protected $method; - public function __construct(Twig_ExtensionInterface $extension, $method) + public function __construct(Twig_ExtensionInterface $extension, $method, array $options = array()) { + $options['callable'] = array($extension, $method); + + parent::__construct($options); + $this->extension = $extension; $this->method = $method; } diff --git a/core/vendor/twig/twig/lib/Twig/Test/Node.php b/core/vendor/twig/twig/lib/Twig/Test/Node.php index 47a978e38dfb..eee48f93a312 100644 --- a/core/vendor/twig/twig/lib/Twig/Test/Node.php +++ b/core/vendor/twig/twig/lib/Twig/Test/Node.php @@ -14,13 +14,16 @@ * * @package twig * @author Fabien Potencier <fabien@symfony.com> + * @deprecated since 1.12 (to be removed in 2.0) */ -class Twig_Test_Node implements Twig_TestInterface +class Twig_Test_Node extends Twig_Test { protected $class; - public function __construct($class) + public function __construct($class, array $options = array()) { + parent::__construct($options); + $this->class = $class; } diff --git a/core/vendor/twig/twig/lib/Twig/TestCallableInterface.php b/core/vendor/twig/twig/lib/Twig/TestCallableInterface.php new file mode 100644 index 000000000000..18a9ca28e902 --- /dev/null +++ b/core/vendor/twig/twig/lib/Twig/TestCallableInterface.php @@ -0,0 +1,22 @@ +<?php + +/* + * This file is part of Twig. + * + * (c) 2012 Fabien Potencier + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * Represents a callable template test. + * + * @package twig + * @author Fabien Potencier <fabien@symfony.com> + * @deprecated since 1.12 (to be removed in 2.0) + */ +interface Twig_TestCallableInterface +{ + public function getCallable(); +} diff --git a/core/vendor/twig/twig/lib/Twig/TestInterface.php b/core/vendor/twig/twig/lib/Twig/TestInterface.php index 96db428264b8..c1a21186d443 100644 --- a/core/vendor/twig/twig/lib/Twig/TestInterface.php +++ b/core/vendor/twig/twig/lib/Twig/TestInterface.php @@ -14,6 +14,7 @@ * * @package twig * @author Fabien Potencier <fabien@symfony.com> + * @deprecated since 1.12 (to be removed in 2.0) */ interface Twig_TestInterface { diff --git a/core/vendor/twig/twig/lib/Twig/TokenParser/For.php b/core/vendor/twig/twig/lib/Twig/TokenParser/For.php index 2cbb58000218..98a6d079d169 100644 --- a/core/vendor/twig/twig/lib/Twig/TokenParser/For.php +++ b/core/vendor/twig/twig/lib/Twig/TokenParser/For.php @@ -33,25 +33,26 @@ class Twig_TokenParser_For extends Twig_TokenParser public function parse(Twig_Token $token) { $lineno = $token->getLine(); + $stream = $this->parser->getStream(); $targets = $this->parser->getExpressionParser()->parseAssignmentExpression(); - $this->parser->getStream()->expect(Twig_Token::OPERATOR_TYPE, 'in'); + $stream->expect(Twig_Token::OPERATOR_TYPE, 'in'); $seq = $this->parser->getExpressionParser()->parseExpression(); $ifexpr = null; - if ($this->parser->getStream()->test(Twig_Token::NAME_TYPE, 'if')) { - $this->parser->getStream()->next(); + if ($stream->test(Twig_Token::NAME_TYPE, 'if')) { + $stream->next(); $ifexpr = $this->parser->getExpressionParser()->parseExpression(); } - $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE); + $stream->expect(Twig_Token::BLOCK_END_TYPE); $body = $this->parser->subparse(array($this, 'decideForFork')); - if ($this->parser->getStream()->next()->getValue() == 'else') { - $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE); + if ($stream->next()->getValue() == 'else') { + $stream->expect(Twig_Token::BLOCK_END_TYPE); $else = $this->parser->subparse(array($this, 'decideForEnd'), true); } else { $else = null; } - $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE); + $stream->expect(Twig_Token::BLOCK_END_TYPE); if (count($targets) > 1) { $keyTarget = $targets->getNode(0); @@ -64,6 +65,11 @@ public function parse(Twig_Token $token) $valueTarget = new Twig_Node_Expression_AssignName($valueTarget->getAttribute('name'), $valueTarget->getLine()); } + if ($ifexpr) { + $this->checkLoopUsageCondition($stream, $ifexpr); + $this->checkLoopUsageBody($stream, $body); + } + return new Twig_Node_For($keyTarget, $valueTarget, $seq, $ifexpr, $body, $else, $lineno, $this->getTag()); } @@ -77,6 +83,47 @@ public function decideForEnd(Twig_Token $token) return $token->test('endfor'); } + // the loop variable cannot be used in the condition + protected function checkLoopUsageCondition(Twig_TokenStream $stream, Twig_NodeInterface $node) + { + if ($node instanceof Twig_Node_Expression_GetAttr && $node->getNode('node') instanceof Twig_Node_Expression_Name && 'loop' == $node->getNode('node')->getAttribute('name')) { + throw new Twig_Error_Syntax('The "loop" variable cannot be used in a looping condition', $node->getLine(), $stream->getFilename()); + } + + foreach ($node as $n) { + if (!$n) { + continue; + } + + $this->checkLoopUsageCondition($stream, $n); + } + } + + // check usage of non-defined loop-items + // it does not catch all problems (for instance when a for is included into another or when the variable is used in an include) + protected function checkLoopUsageBody(Twig_TokenStream $stream, Twig_NodeInterface $node) + { + if ($node instanceof Twig_Node_Expression_GetAttr && $node->getNode('node') instanceof Twig_Node_Expression_Name && 'loop' == $node->getNode('node')->getAttribute('name')) { + $attribute = $node->getNode('attribute'); + if ($attribute instanceof Twig_Node_Expression_Constant && in_array($attribute->getAttribute('value'), array('length', 'revindex0', 'revindex', 'last'))) { + throw new Twig_Error_Syntax(sprintf('The "loop.%s" variable is not defined when looping with a condition', $attribute->getAttribute('value')), $node->getLine(), $stream->getFilename()); + } + } + + // should check for parent.loop.XXX usage + if ($node instanceof Twig_Node_For) { + return; + } + + foreach ($node as $n) { + if (!$n) { + continue; + } + + $this->checkLoopUsageBody($stream, $n); + } + } + /** * Gets the tag name associated with this token parser. * diff --git a/core/vendor/twig/twig/lib/Twig/TokenParser/Macro.php b/core/vendor/twig/twig/lib/Twig/TokenParser/Macro.php index de100591b507..c2a033608d32 100644 --- a/core/vendor/twig/twig/lib/Twig/TokenParser/Macro.php +++ b/core/vendor/twig/twig/lib/Twig/TokenParser/Macro.php @@ -33,7 +33,7 @@ public function parse(Twig_Token $token) $stream = $this->parser->getStream(); $name = $stream->expect(Twig_Token::NAME_TYPE)->getValue(); - $arguments = $this->parser->getExpressionParser()->parseArguments(); + $arguments = $this->parser->getExpressionParser()->parseArguments(true, true); $stream->expect(Twig_Token::BLOCK_END_TYPE); $this->parser->pushLocalScope(); diff --git a/core/vendor/twig/twig/lib/Twig/TokenParserBroker.php b/core/vendor/twig/twig/lib/Twig/TokenParserBroker.php index f2c27ee488ff..23474de3789b 100644 --- a/core/vendor/twig/twig/lib/Twig/TokenParserBroker.php +++ b/core/vendor/twig/twig/lib/Twig/TokenParserBroker.php @@ -13,8 +13,9 @@ /** * Default implementation of a token parser broker. * - * @package twig - * @author Arnaud Le Blanc <arnaud.lb@gmail.com> + * @package twig + * @author Arnaud Le Blanc <arnaud.lb@gmail.com> + * @deprecated since 1.12 (to be removed in 2.0) */ class Twig_TokenParserBroker implements Twig_TokenParserBrokerInterface { @@ -54,6 +55,19 @@ public function addTokenParser(Twig_TokenParserInterface $parser) $this->parsers[$parser->getTag()] = $parser; } + /** + * Removes a TokenParser. + * + * @param Twig_TokenParserInterface $parser A Twig_TokenParserInterface instance + */ + public function removeTokenParser(Twig_TokenParserInterface $parser) + { + $name = $parser->getTag(); + if (isset($this->parsers[$name]) && $parser === $this->parsers[$name]) { + unset($this->parsers[$name]); + } + } + /** * Adds a TokenParserBroker. * @@ -64,6 +78,18 @@ public function addTokenParserBroker(Twig_TokenParserBroker $broker) $this->brokers[] = $broker; } + /** + * Removes a TokenParserBroker. + * + * @param Twig_TokenParserBroker $broker A Twig_TokenParserBroker instance + */ + public function removeTokenParserBroker(Twig_TokenParserBroker $broker) + { + if (false !== $pos = array_search($broker, $this->brokers)) { + unset($this->brokers[$pos]); + } + } + /** * Gets a suitable TokenParser for a tag. * diff --git a/core/vendor/twig/twig/lib/Twig/TokenParserBrokerInterface.php b/core/vendor/twig/twig/lib/Twig/TokenParserBrokerInterface.php index b8e3c2341b99..ac7e7cdeab83 100644 --- a/core/vendor/twig/twig/lib/Twig/TokenParserBrokerInterface.php +++ b/core/vendor/twig/twig/lib/Twig/TokenParserBrokerInterface.php @@ -15,8 +15,9 @@ * * Token parser brokers allows to implement custom logic in the process of resolving a token parser for a given tag name. * - * @package twig - * @author Arnaud Le Blanc <arnaud.lb@gmail.com> + * @package twig + * @author Arnaud Le Blanc <arnaud.lb@gmail.com> + * @deprecated since 1.12 (to be removed in 2.0) */ interface Twig_TokenParserBrokerInterface { diff --git a/core/vendor/twig/twig/lib/Twig/TokenStream.php b/core/vendor/twig/twig/lib/Twig/TokenStream.php index 292c11fb339f..fcb10eb7d760 100644 --- a/core/vendor/twig/twig/lib/Twig/TokenStream.php +++ b/core/vendor/twig/twig/lib/Twig/TokenStream.php @@ -58,7 +58,7 @@ public function injectTokens(array $tokens) public function next() { if (!isset($this->tokens[++$this->current])) { - throw new Twig_Error_Syntax('Unexpected end of template', $this->token[$this->current - 1]->getLine(), $this->filename); + throw new Twig_Error_Syntax('Unexpected end of template', $this->tokens[$this->current - 1]->getLine(), $this->filename); } return $this->tokens[$this->current - 1]; @@ -97,7 +97,7 @@ public function expect($type, $value = null, $message = null) public function look($number = 1) { if (!isset($this->tokens[$this->current + $number])) { - throw new Twig_Error_Syntax('Unexpected end of template', $this->token[$this->current + $number - 1]->getLine(), $this->filename); + throw new Twig_Error_Syntax('Unexpected end of template', $this->tokens[$this->current + $number - 1]->getLine(), $this->filename); } return $this->tokens[$this->current + $number]; diff --git a/core/vendor/twig/twig/package.xml.tpl b/core/vendor/twig/twig/package.xml.tpl deleted file mode 100644 index f9a9b892ea95..000000000000 --- a/core/vendor/twig/twig/package.xml.tpl +++ /dev/null @@ -1,64 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<package packagerversion="1.8.0" version="2.0" xmlns="http://pear.php.net/dtd/package-2.0" xmlns:tasks="http://pear.php.net/dtd/tasks-1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://pear.php.net/dtd/tasks-1.0 - http://pear.php.net/dtd/tasks-1.0.xsd - http://pear.php.net/dtd/package-2.0 - http://pear.php.net/dtd/package-2.0.xsd"> - <name>Twig</name> - <channel>pear.twig-project.org</channel> - <summary>Twig is a PHP template engine.</summary> - <description> - Twig is a template language for PHP, released under the new BSD license - (code and documentation). - - Twig uses a syntax similar to the Django and Jinja template languages which - inspired the Twig runtime environment. - </description> - <lead> - <name>Fabien Potencier</name> - <user>fabpot</user> - <email>fabien.potencier@symfony-project.org</email> - <active>yes</active> - </lead> - <lead> - <name>Armin Ronacher</name> - <user>armin</user> - <email>armin.ronacher@active-4.com</email> - <active>no</active> - </lead> - <date>{{ date }}</date> - <time>{{ time }}</time> - <version> - <release>{{ version }}</release> - <api>{{ api_version }}</api> - </version> - <stability> - <release>{{ stability }}</release> - <api>{{ stability }}</api> - </stability> - <license uri="http://www.opensource.org/licenses/bsd-license.php">BSD Style</license> - <notes>-</notes> - <contents> - <dir name="/"> - <file name="AUTHORS" role="doc" /> - <file name="CHANGELOG" role="doc" /> - <file name="LICENSE" role="doc" /> - <file name="README.markdown" role="doc" /> - <dir name="lib"> - <dir name="Twig"> -{{ files }} - </dir> - </dir> - </dir> - </contents> - <dependencies> - <required> - <php> - <min>5.2.4</min> - </php> - <pearinstaller> - <min>1.4.0</min> - </pearinstaller> - </required> - </dependencies> - <phprelease /> -</package> diff --git a/core/vendor/twig/twig/test/Twig/Tests/EnvironmentTest.php b/core/vendor/twig/twig/test/Twig/Tests/EnvironmentTest.php index 76731ea043f4..fc2cef8b1485 100644 --- a/core/vendor/twig/twig/test/Twig/Tests/EnvironmentTest.php +++ b/core/vendor/twig/twig/test/Twig/Tests/EnvironmentTest.php @@ -32,4 +32,241 @@ public function escapingStrategyCallback($filename) { return $filename; } + + public function testGlobals() + { + // globals can be added after calling getGlobals + $twig = new Twig_Environment(new Twig_Loader_String()); + $twig->addGlobal('foo', 'foo'); + $globals = $twig->getGlobals(); + $twig->addGlobal('foo', 'bar'); + $globals = $twig->getGlobals(); + $this->assertEquals('bar', $globals['foo']); + + // globals can be modified after runtime init + $twig = new Twig_Environment(new Twig_Loader_String()); + $twig->addGlobal('foo', 'foo'); + $globals = $twig->getGlobals(); + $twig->initRuntime(); + $twig->addGlobal('foo', 'bar'); + $globals = $twig->getGlobals(); + $this->assertEquals('bar', $globals['foo']); + + // globals can be modified after extensions init + $twig = new Twig_Environment(new Twig_Loader_String()); + $twig->addGlobal('foo', 'foo'); + $globals = $twig->getGlobals(); + $twig->getFunctions(); + $twig->addGlobal('foo', 'bar'); + $globals = $twig->getGlobals(); + $this->assertEquals('bar', $globals['foo']); + + // globals can be modified after extensions and runtime init + $twig = new Twig_Environment(new Twig_Loader_String()); + $twig->addGlobal('foo', 'foo'); + $globals = $twig->getGlobals(); + $twig->getFunctions(); + $twig->initRuntime(); + $twig->addGlobal('foo', 'bar'); + $globals = $twig->getGlobals(); + $this->assertEquals('bar', $globals['foo']); + + /* to be uncomment in Twig 2.0 + // globals cannot be added after runtime init + $twig = new Twig_Environment(new Twig_Loader_String()); + $twig->addGlobal('foo', 'foo'); + $globals = $twig->getGlobals(); + $twig->initRuntime(); + try { + $twig->addGlobal('bar', 'bar'); + $this->fail(); + } catch (LogicException $e) { + $this->assertFalse(array_key_exists('bar', $twig->getGlobals())); + } + + // globals cannot be added after extensions init + $twig = new Twig_Environment(new Twig_Loader_String()); + $twig->addGlobal('foo', 'foo'); + $globals = $twig->getGlobals(); + $twig->getFunctions(); + try { + $twig->addGlobal('bar', 'bar'); + $this->fail(); + } catch (LogicException $e) { + $this->assertFalse(array_key_exists('bar', $twig->getGlobals())); + } + + // globals cannot be added after extensions and runtime init + $twig = new Twig_Environment(new Twig_Loader_String()); + $twig->addGlobal('foo', 'foo'); + $globals = $twig->getGlobals(); + $twig->getFunctions(); + $twig->initRuntime(); + try { + $twig->addGlobal('bar', 'bar'); + $this->fail(); + } catch (LogicException $e) { + $this->assertFalse(array_key_exists('bar', $twig->getGlobals())); + } + + // test adding globals after initRuntime without call to getGlobals + $twig = new Twig_Environment(new Twig_Loader_String()); + $twig->initRuntime(); + try { + $twig->addGlobal('bar', 'bar'); + $this->fail(); + } catch (LogicException $e) { + $this->assertFalse(array_key_exists('bar', $twig->getGlobals())); + } + */ + } + + public function testExtensionsAreNotInitializedWhenRenderingACompiledTemplate() + { + $options = array('cache' => sys_get_temp_dir().'/twig', 'auto_reload' => false, 'debug' => false); + + // force compilation + $twig = new Twig_Environment(new Twig_Loader_String(), $options); + $cache = $twig->getCacheFilename('{{ foo }}'); + if (!is_dir(dirname($cache))) { + mkdir(dirname($cache), 0777, true); + } + file_put_contents($cache, $twig->compileSource('{{ foo }}', '{{ foo }}')); + + // check that extensions won't be initialized when rendering a template that is already in the cache + $twig = $this + ->getMockBuilder('Twig_Environment') + ->setConstructorArgs(array(new Twig_Loader_String(), $options)) + ->setMethods(array('initExtensions')) + ->getMock() + ; + + $twig->expects($this->never())->method('initExtensions'); + + // render template + $output = $twig->render('{{ foo }}', array('foo' => 'bar')); + $this->assertEquals('bar', $output); + + unlink($cache); + } + + public function testAddExtension() + { + $twig = new Twig_Environment(new Twig_Loader_String()); + $twig->addExtension(new Twig_Tests_EnvironmentTest_Extension()); + + $this->assertArrayHasKey('test', $twig->getTags()); + $this->assertArrayHasKey('foo_filter', $twig->getFilters()); + $this->assertArrayHasKey('foo_function', $twig->getFunctions()); + $this->assertArrayHasKey('foo_test', $twig->getTests()); + $this->assertArrayHasKey('foo_unary', $twig->getUnaryOperators()); + $this->assertArrayHasKey('foo_binary', $twig->getBinaryOperators()); + $this->assertArrayHasKey('foo_global', $twig->getGlobals()); + $visitors = $twig->getNodeVisitors(); + $this->assertEquals('Twig_Tests_EnvironmentTest_NodeVisitor', get_class($visitors[2])); + } + + public function testRemoveExtension() + { + $twig = new Twig_Environment(new Twig_Loader_String()); + $twig->addExtension(new Twig_Tests_EnvironmentTest_Extension()); + $twig->removeExtension('test'); + + $this->assertFalse(array_key_exists('test', $twig->getTags())); + $this->assertFalse(array_key_exists('foo_filter', $twig->getFilters())); + $this->assertFalse(array_key_exists('foo_function', $twig->getFunctions())); + $this->assertFalse(array_key_exists('foo_test', $twig->getTests())); + $this->assertFalse(array_key_exists('foo_unary', $twig->getUnaryOperators())); + $this->assertFalse(array_key_exists('foo_binary', $twig->getBinaryOperators())); + $this->assertFalse(array_key_exists('foo_global', $twig->getGlobals())); + $this->assertCount(2, $twig->getNodeVisitors()); + } +} + +class Twig_Tests_EnvironmentTest_Extension extends Twig_Extension +{ + public function getTokenParsers() + { + return array( + new Twig_Tests_EnvironmentTest_TokenParser(), + ); + } + + public function getNodeVisitors() + { + return array( + new Twig_Tests_EnvironmentTest_NodeVisitor(), + ); + } + + public function getFilters() + { + return array( + 'foo_filter' => new Twig_Filter_Function('foo_filter'), + ); + } + + public function getTests() + { + return array( + 'foo_test' => new Twig_Test_Function('foo_test'), + ); + } + + public function getFunctions() + { + return array( + 'foo_function' => new Twig_Function_Function('foo_function'), + ); + } + + public function getOperators() + { + return array( + array('foo_unary' => array()), + array('foo_binary' => array()), + ); + } + + public function getGlobals() + { + return array( + 'foo_global' => 'foo_global', + ); + } + + public function getName() + { + return 'test'; + } +} + +class Twig_Tests_EnvironmentTest_TokenParser extends Twig_TokenParser +{ + public function parse(Twig_Token $token) + { + } + + public function getTag() + { + return 'test'; + } +} + +class Twig_Tests_EnvironmentTest_NodeVisitor implements Twig_NodeVisitorInterface +{ + public function enterNode(Twig_NodeInterface $node, Twig_Environment $env) + { + return $node; + } + + public function leaveNode(Twig_NodeInterface $node, Twig_Environment $env) + { + return $node; + } + + public function getPriority() + { + return 0; + } } diff --git a/core/vendor/twig/twig/test/Twig/Tests/ExpressionParserTest.php b/core/vendor/twig/twig/test/Twig/Tests/ExpressionParserTest.php index b3f300fae6b5..8ec6537a9c40 100644 --- a/core/vendor/twig/twig/test/Twig/Tests/ExpressionParserTest.php +++ b/core/vendor/twig/twig/test/Twig/Tests/ExpressionParserTest.php @@ -214,4 +214,119 @@ public function getTestsForString() ), ); } + + /** + * @expectedException Twig_Error_Syntax + */ + public function testAttributeCallDoesNotSupportNamedArguments() + { + $env = new Twig_Environment(new Twig_Loader_String(), array('cache' => false, 'autoescape' => false)); + $parser = new Twig_Parser($env); + + $parser->parse($env->tokenize('{{ foo.bar(name="Foo") }}', 'index')); + } + + /** + * @expectedException Twig_Error_Syntax + */ + public function testMacroCallDoesNotSupportNamedArguments() + { + $env = new Twig_Environment(new Twig_Loader_String(), array('cache' => false, 'autoescape' => false)); + $parser = new Twig_Parser($env); + + $parser->parse($env->tokenize('{% from _self import foo %}{% macro foo() %}{% endmacro %}{{ foo(name="Foo") }}', 'index')); + } + + /** + * @expectedException Twig_Error_Syntax + * @expectedExceptionMessage An argument must be a name. Unexpected token "string" of value "a" ("name" expected) in "index" at line 1 + */ + public function testMacroDefinitionDoesNotSupportNonNameVariableName() + { + $env = new Twig_Environment(new Twig_Loader_String(), array('cache' => false, 'autoescape' => false)); + $parser = new Twig_Parser($env); + + $parser->parse($env->tokenize('{% macro foo("a") %}{% endmacro %}', 'index')); + } + + /** + * @expectedException Twig_Error_Syntax + * @expectedExceptionMessage A default value for an argument must be a constant (a boolean, a string, a number, or an array) in "index" at line 1 + * @dataProvider getMacroDefinitionDoesNotSupportNonConstantDefaultValues + */ + public function testMacroDefinitionDoesNotSupportNonConstantDefaultValues($template) + { + $env = new Twig_Environment(new Twig_Loader_String(), array('cache' => false, 'autoescape' => false)); + $parser = new Twig_Parser($env); + + $parser->parse($env->tokenize($template, 'index')); + } + + public function getMacroDefinitionDoesNotSupportNonConstantDefaultValues() + { + return array( + array('{% macro foo(name = "a #{foo} a") %}{% endmacro %}'), + array('{% macro foo(name = [["b", "a #{foo} a"]]) %}{% endmacro %}'), + ); + } + + /** + * @dataProvider getMacroDefinitionSupportsConstantDefaultValues + */ + public function testMacroDefinitionSupportsConstantDefaultValues($template) + { + $env = new Twig_Environment(new Twig_Loader_String(), array('cache' => false, 'autoescape' => false)); + $parser = new Twig_Parser($env); + + $parser->parse($env->tokenize($template, 'index')); + } + + public function getMacroDefinitionSupportsConstantDefaultValues() + { + return array( + array('{% macro foo(name = "aa") %}{% endmacro %}'), + array('{% macro foo(name = 12) %}{% endmacro %}'), + array('{% macro foo(name = true) %}{% endmacro %}'), + array('{% macro foo(name = ["a"]) %}{% endmacro %}'), + array('{% macro foo(name = [["a"]]) %}{% endmacro %}'), + array('{% macro foo(name = {a: "a"}) %}{% endmacro %}'), + array('{% macro foo(name = {a: {b: "a"}}) %}{% endmacro %}'), + ); + } + + /** + * @expectedException Twig_Error_Syntax + * @expectedExceptionMessage The function "cycl" does not exist. Did you mean "cycle" in "index" at line 1 + */ + public function testUnknownFunction() + { + $env = new Twig_Environment(new Twig_Loader_String(), array('cache' => false, 'autoescape' => false)); + $parser = new Twig_Parser($env); + + $parser->parse($env->tokenize('{{ cycl() }}', 'index')); + } + + /** + * @expectedException Twig_Error_Syntax + * @expectedExceptionMessage The filter "lowe" does not exist. Did you mean "lower" in "index" at line 1 + */ + public function testUnknownFilter() + { + $env = new Twig_Environment(new Twig_Loader_String(), array('cache' => false, 'autoescape' => false)); + $parser = new Twig_Parser($env); + + $parser->parse($env->tokenize('{{ 1|lowe }}', 'index')); + } + + /** + * @expectedException Twig_Error_Syntax + * @expectedExceptionMessage The test "nul" does not exist. Did you mean "null" in "index" at line 1 + */ + public function testUnknownTest() + { + $env = new Twig_Environment(new Twig_Loader_String(), array('cache' => false, 'autoescape' => false)); + $parser = new Twig_Parser($env); + + $parser->parse($env->tokenize('{{ 1 is nul }}', 'index')); + } } diff --git a/core/vendor/twig/twig/test/Twig/Tests/Fixtures/expressions/ternary_operator_noelse.test b/core/vendor/twig/twig/test/Twig/Tests/Fixtures/expressions/ternary_operator_noelse.test new file mode 100644 index 000000000000..fdc660fc5e73 --- /dev/null +++ b/core/vendor/twig/twig/test/Twig/Tests/Fixtures/expressions/ternary_operator_noelse.test @@ -0,0 +1,10 @@ +--TEST-- +Twig supports the ternary operator +--TEMPLATE-- +{{ 1 ? 'YES' }} +{{ 0 ? 'YES' }} +--DATA-- +return array() +--EXPECT-- +YES + diff --git a/core/vendor/twig/twig/test/Twig/Tests/Fixtures/expressions/ternary_operator_nothen.test b/core/vendor/twig/twig/test/Twig/Tests/Fixtures/expressions/ternary_operator_nothen.test new file mode 100644 index 000000000000..9057e837018b --- /dev/null +++ b/core/vendor/twig/twig/test/Twig/Tests/Fixtures/expressions/ternary_operator_nothen.test @@ -0,0 +1,10 @@ +--TEST-- +Twig supports the ternary operator +--TEMPLATE-- +{{ 'YES' ?: 'NO' }} +{{ 0 ?: 'NO' }} +--DATA-- +return array() +--EXPECT-- +YES +NO diff --git a/core/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/date_namedargs.test b/core/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/date_namedargs.test new file mode 100644 index 000000000000..6ca2049ddec4 --- /dev/null +++ b/core/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/date_namedargs.test @@ -0,0 +1,15 @@ +--TEST-- +"date" filter +--TEMPLATE-- +{{ date|date(format='d/m/Y H:i:s P', timezone='America/Chicago') }} +{{ date|date(timezone='America/Chicago', format='d/m/Y H:i:s P') }} +{{ date|date(timezone='America/Chicago', 'd/m/Y H:i:s P') }} +{{ date|date('d/m/Y H:i:s P', timezone='America/Chicago') }} +--DATA-- +date_default_timezone_set('UTC'); +return array('date' => mktime(13, 45, 0, 10, 4, 2010)) +--EXPECT-- +04/10/2010 08:45:00 -05:00 +04/10/2010 08:45:00 -05:00 +04/10/2010 08:45:00 -05:00 +04/10/2010 08:45:00 -05:00 diff --git a/core/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/reverse.test b/core/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/reverse.test index 3c5f410a2395..7948ac45fece 100644 --- a/core/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/reverse.test +++ b/core/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/reverse.test @@ -4,9 +4,15 @@ {{ [1, 2, 3, 4]|reverse|join('') }} {{ '1234évènement'|reverse }} {{ arr|reverse|join('') }} +{{ {'a': 'c', 'b': 'a'}|reverse()|join(',') }} +{{ {'a': 'c', 'b': 'a'}|reverse(preserveKeys=true)|join(glue=',') }} +{{ {'a': 'c', 'b': 'a'}|reverse(preserve_keys=true)|join(glue=',') }} --DATA-- return array('arr' => new ArrayObject(array(1, 2, 3, 4))) --EXPECT-- 4321 tnemenèvé4321 4321 +a,c +a,c +a,c diff --git a/core/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/slice.test b/core/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/slice.test index bb32dfbc59eb..b37ad6514ae6 100644 --- a/core/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/slice.test +++ b/core/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/slice.test @@ -18,6 +18,7 @@ {{ [1, 2, 3, 4][1:]|join('') }} {{ '1234'|slice(1) }} {{ '1234'[1:] }} +{{ '1234'[:1] }} --DATA-- return array('start' => 1, 'length' => 2, 'arr' => new ArrayObject(array(1, 2, 3, 4))) --EXPECT-- @@ -38,3 +39,4 @@ bc 234 234 234 +1 diff --git a/core/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/constant.test b/core/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/constant.test index 6d4b374c41ba..63128791f557 100644 --- a/core/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/constant.test +++ b/core/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/constant.test @@ -1,12 +1,10 @@ --TEST-- "constant" function --TEMPLATE-- -{% if constant('DATE_W3C') == expect %} -true -{% else %} -false -{% endif %} +{{ constant('DATE_W3C') == expect ? 'true' : 'false' }} +{{ constant('ARRAY_AS_PROPS', object) }} --DATA-- -return array('expect' => DATE_W3C); +return array('expect' => DATE_W3C, 'object' => new ArrayObject(array('hi'))); --EXPECT-- true +2 diff --git a/core/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/date_namedargs.test b/core/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/date_namedargs.test new file mode 100644 index 000000000000..b9dd9e38329f --- /dev/null +++ b/core/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/date_namedargs.test @@ -0,0 +1,11 @@ +--TEST-- +"date" function +--TEMPLATE-- +{{ date(date, "America/New_York")|date('d/m/Y H:i:s P', false) }} +{{ date(timezone="America/New_York", date=date)|date('d/m/Y H:i:s P', false) }} +--DATA-- +date_default_timezone_set('UTC'); +return array('date' => mktime(13, 45, 0, 10, 4, 2010)) +--EXPECT-- +04/10/2010 09:45:00 -04:00 +04/10/2010 09:45:00 -04:00 diff --git a/core/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/include/basic.test b/core/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/include/basic.test new file mode 100644 index 000000000000..a434182a214b --- /dev/null +++ b/core/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/include/basic.test @@ -0,0 +1,17 @@ +--TEST-- +"include" function +--TEMPLATE-- +FOO +{{ include("foo.twig") }} + +BAR +--TEMPLATE(foo.twig)-- +FOOBAR +--DATA-- +return array() +--EXPECT-- +FOO + +FOOBAR + +BAR diff --git a/core/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/include/expression.test b/core/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/include/expression.test new file mode 100644 index 000000000000..aba30ce3fcb9 --- /dev/null +++ b/core/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/include/expression.test @@ -0,0 +1,17 @@ +--TEST-- +"include" function allows expressions for the template to include +--TEMPLATE-- +FOO +{{ include(foo) }} + +BAR +--TEMPLATE(foo.twig)-- +FOOBAR +--DATA-- +return array('foo' => 'foo.twig') +--EXPECT-- +FOO + +FOOBAR + +BAR diff --git a/core/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/include/ignore_missing.test b/core/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/include/ignore_missing.test new file mode 100644 index 000000000000..43a2ccc2c895 --- /dev/null +++ b/core/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/include/ignore_missing.test @@ -0,0 +1,10 @@ +--TEST-- +"include" function +--TEMPLATE-- +{{ include(["foo.twig", "bar.twig"], ignore_missing = true) }} +{{ include("foo.twig", ignore_missing = true) }} +{{ include("foo.twig", ignore_missing = true, variables = {}) }} +{{ include("foo.twig", ignore_missing = true, variables = {}, with_context = true) }} +--DATA-- +return array() +--EXPECT-- diff --git a/core/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/include/missing.test b/core/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/include/missing.test new file mode 100644 index 000000000000..4d2f6cf136ce --- /dev/null +++ b/core/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/include/missing.test @@ -0,0 +1,8 @@ +--TEST-- +"include" function +--TEMPLATE-- +{{ include("foo.twig") }} +--DATA-- +return array(); +--EXCEPTION-- +Twig_Error_Loader: Template "foo.twig" is not defined in "index.twig" at line 2. diff --git a/core/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/include/missing_nested.test b/core/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/include/missing_nested.test new file mode 100644 index 000000000000..78fddc7a683a --- /dev/null +++ b/core/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/include/missing_nested.test @@ -0,0 +1,16 @@ +--TEST-- +"include" function +--TEMPLATE-- +{% extends "base.twig" %} + +{% block content %} + {{ parent() }} +{% endblock %} +--TEMPLATE(base.twig)-- +{% block content %} + {{ include("foo.twig") }} +{% endblock %} +--DATA-- +return array(); +--EXCEPTION-- +Twig_Error_Loader: Template "foo.twig" is not defined in "base.twig" at line 3. diff --git a/core/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/include/sandbox.test b/core/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/include/sandbox.test new file mode 100644 index 000000000000..788a2ab0bddf --- /dev/null +++ b/core/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/include/sandbox.test @@ -0,0 +1,10 @@ +--TEST-- +"include" tag sandboxed +--TEMPLATE-- +{{ include("foo.twig", sandboxed = true) }} +--TEMPLATE(foo.twig)-- +{{ foo|e }} +--DATA-- +return array() +--EXCEPTION-- +Twig_Sandbox_SecurityError: Filter "e" is not allowed in "index.twig" at line 2. diff --git a/core/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/include/template_instance.test b/core/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/include/template_instance.test new file mode 100644 index 000000000000..18d405a02e3a --- /dev/null +++ b/core/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/include/template_instance.test @@ -0,0 +1,10 @@ +--TEST-- +"include" function accepts Twig_Template instance +--TEMPLATE-- +{{ include(foo) }} FOO +--TEMPLATE(foo.twig)-- +BAR +--DATA-- +return array('foo' => $twig->loadTemplate('foo.twig')) +--EXPECT-- +BAR FOO diff --git a/core/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/include/templates_as_array.test b/core/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/include/templates_as_array.test new file mode 100644 index 000000000000..1a8100687cd3 --- /dev/null +++ b/core/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/include/templates_as_array.test @@ -0,0 +1,12 @@ +--TEST-- +"include" function +--TEMPLATE-- +{{ include(["foo.twig", "bar.twig"]) }} +{{- include(["bar.twig", "foo.twig"]) }} +--TEMPLATE(foo.twig)-- +foo +--DATA-- +return array() +--EXPECT-- +foo +foo diff --git a/core/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/include/with_context.test b/core/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/include/with_context.test new file mode 100644 index 000000000000..35611fbb9c68 --- /dev/null +++ b/core/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/include/with_context.test @@ -0,0 +1,16 @@ +--TEST-- +"include" function accept variables and with_context +--TEMPLATE-- +{{ include("foo.twig") }} +{{- include("foo.twig", with_context = false) }} +{{- include("foo.twig", {'foo1': 'bar'}) }} +{{- include("foo.twig", {'foo1': 'bar'}, with_context = false) }} +--TEMPLATE(foo.twig)-- +{% for k, v in _context %}{{ k }},{% endfor %} +--DATA-- +return array('foo' => 'bar') +--EXPECT-- +foo,global,_parent, +global,_parent, +foo,global,foo1,_parent, +foo1,global,_parent, diff --git a/core/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/include/with_variables.test b/core/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/include/with_variables.test new file mode 100644 index 000000000000..b2ace940e955 --- /dev/null +++ b/core/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/include/with_variables.test @@ -0,0 +1,12 @@ +--TEST-- +"include" function accept variables +--TEMPLATE-- +{{ include("foo.twig", {'foo': 'bar'}) }} +{{- include("foo.twig", vars) }} +--TEMPLATE(foo.twig)-- +{{ foo }} +--DATA-- +return array('vars' => array('foo' => 'bar')) +--EXPECT-- +bar +bar diff --git a/core/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/range.test b/core/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/range.test new file mode 100644 index 000000000000..e0377c8d41d3 --- /dev/null +++ b/core/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/range.test @@ -0,0 +1,8 @@ +--TEST-- +"range" function +--TEMPLATE-- +{{ range(low=0+1, high=10+0, step=2)|join(',') }} +--DATA-- +return array() +--EXPECT-- +1,3,5,7,9 diff --git a/core/vendor/twig/twig/test/Twig/Tests/Fixtures/macros/default_values.test b/core/vendor/twig/twig/test/Twig/Tests/Fixtures/macros/default_values.test new file mode 100644 index 000000000000..4ccff7b67017 --- /dev/null +++ b/core/vendor/twig/twig/test/Twig/Tests/Fixtures/macros/default_values.test @@ -0,0 +1,16 @@ +--TEST-- +macro +--TEMPLATE-- +{% from _self import test %} + +{% macro test(a, b = 'bar') -%} +{{ a }}{{ b }} +{%- endmacro %} + +{{ test('foo') }} +{{ test('bar', 'foo') }} +--DATA-- +return array(); +--EXPECT-- +foobar +barfoo diff --git a/core/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/for/condition.test b/core/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/for/condition.test index 9e4eb9b2d1c9..380531f7809e 100644 --- a/core/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/for/condition.test +++ b/core/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/for/condition.test @@ -2,13 +2,13 @@ "for" tag takes a condition --TEMPLATE-- {% for i in 1..5 if i is odd -%} - {{ loop.index }}.{{ i }} + {{ loop.index }}.{{ i }}{{ foo.bar }} {% endfor %} --DATA-- -return array() +return array('foo' => array('bar' => 'X')) --CONFIG-- return array('strict_variables' => false) --EXPECT-- -1.1 -2.3 -3.5 +1.1X +2.3X +3.5X diff --git a/core/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/for/loop_not_defined.test b/core/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/for/loop_not_defined.test new file mode 100644 index 000000000000..4301ef2ffbe3 --- /dev/null +++ b/core/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/for/loop_not_defined.test @@ -0,0 +1,10 @@ +--TEST-- +"for" tag +--TEMPLATE-- +{% for i, item in items if i > 0 %} + {{ loop.last }} +{% endfor %} +--DATA-- +return array('items' => array('a', 'b')) +--EXCEPTION-- +Twig_Error_Syntax: The "loop.last" variable is not defined when looping with a condition in "index.twig" at line 3 diff --git a/core/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/for/loop_not_defined_cond.test b/core/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/for/loop_not_defined_cond.test new file mode 100644 index 000000000000..c7e723a51b41 --- /dev/null +++ b/core/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/for/loop_not_defined_cond.test @@ -0,0 +1,9 @@ +--TEST-- +"for" tag +--TEMPLATE-- +{% for i, item in items if loop.last > 0 %} +{% endfor %} +--DATA-- +return array('items' => array('a', 'b')) +--EXCEPTION-- +Twig_Error_Syntax: The "loop" variable cannot be used in a looping condition in "index.twig" at line 2 diff --git a/core/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/raw/mixed_usage_with_raw.test b/core/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/raw/mixed_usage_with_raw.test new file mode 100644 index 000000000000..2fd9fb26d022 --- /dev/null +++ b/core/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/raw/mixed_usage_with_raw.test @@ -0,0 +1,10 @@ +--TEST-- +"raw" tag +--TEMPLATE-- +{% raw %} +{{ foo }} +{% endverbatim %} +--DATA-- +return array() +--EXCEPTION-- +Twig_Error_Syntax: Unexpected end of file: Unclosed "raw" block in "index.twig" at line 2 diff --git a/core/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/verbatim/basic.test b/core/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/verbatim/basic.test new file mode 100644 index 000000000000..a95be5572adf --- /dev/null +++ b/core/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/verbatim/basic.test @@ -0,0 +1,10 @@ +--TEST-- +"verbatim" tag +--TEMPLATE-- +{% verbatim %} +{{ foo }} +{% endverbatim %} +--DATA-- +return array() +--EXPECT-- +{{ foo }} diff --git a/core/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/verbatim/mixed_usage_with_raw.test b/core/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/verbatim/mixed_usage_with_raw.test new file mode 100644 index 000000000000..941dddcceaf5 --- /dev/null +++ b/core/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/verbatim/mixed_usage_with_raw.test @@ -0,0 +1,10 @@ +--TEST-- +"verbatim" tag +--TEMPLATE-- +{% verbatim %} +{{ foo }} +{% endraw %} +--DATA-- +return array() +--EXCEPTION-- +Twig_Error_Syntax: Unexpected end of file: Unclosed "verbatim" block in "index.twig" at line 2 diff --git a/core/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/verbatim/whitespace_control.test b/core/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/verbatim/whitespace_control.test new file mode 100644 index 000000000000..eb610444604b --- /dev/null +++ b/core/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/verbatim/whitespace_control.test @@ -0,0 +1,56 @@ +--TEST-- +"verbatim" tag +--TEMPLATE-- +1*** + +{%- verbatim %} + {{ 'bla' }} +{% endverbatim %} + +1*** +2*** + +{%- verbatim -%} + {{ 'bla' }} +{% endverbatim %} + +2*** +3*** + +{%- verbatim -%} + {{ 'bla' }} +{% endverbatim -%} + +3*** +4*** + +{%- verbatim -%} + {{ 'bla' }} +{%- endverbatim %} + +4*** +5*** + +{%- verbatim -%} + {{ 'bla' }} +{%- endverbatim -%} + +5*** +--DATA-- +return array() +--EXPECT-- +1*** + {{ 'bla' }} + + +1*** +2***{{ 'bla' }} + + +2*** +3***{{ 'bla' }} +3*** +4***{{ 'bla' }} + +4*** +5***{{ 'bla' }}5*** diff --git a/core/vendor/twig/twig/test/Twig/Tests/Node/Expression/FilterTest.php b/core/vendor/twig/twig/test/Twig/Tests/Node/Expression/FilterTest.php index d37dd220fa9e..8089b9cb1c06 100644 --- a/core/vendor/twig/twig/test/Twig/Tests/Node/Expression/FilterTest.php +++ b/core/vendor/twig/twig/test/Twig/Tests/Node/Expression/FilterTest.php @@ -35,19 +35,6 @@ public function testCompile($node, $source, $environment = null) parent::testCompile($node, $source, $environment); } - /** - * @covers Twig_Node_Expression_Filter::compile - * @expectedException Twig_Error_Syntax - * @expectedExceptionMessage The filter "lowe" does not exist. Did you mean "lower" at line 1 - */ - public function testCompileUnknownFilter() - { - $expr = new Twig_Node_Expression_Constant('foo', 1); - $node = $this->createFilter($expr, 'lowe', array(new Twig_Node_Expression_Constant('bar', 1), new Twig_Node_Expression_Constant('foobar', 1))); - - $node->compile($this->getCompiler()); - } - public function getTests() { $tests = array(); @@ -62,18 +49,69 @@ public function getTests() $tests[] = array($node, 'twig_number_format_filter($this->env, strtoupper("foo"), 2, ".", ",")'); } + // named arguments + $date = new Twig_Node_Expression_Constant(0, 1); + $node = $this->createFilter($date, 'date', array( + 'timezone' => new Twig_Node_Expression_Constant('America/Chicago', 1), + 'format' => new Twig_Node_Expression_Constant('d/m/Y H:i:s P', 1), + )); + $tests[] = array($node, 'twig_date_format_filter($this->env, 0, "d/m/Y H:i:s P", "America/Chicago")'); + + // skip an optional argument + $date = new Twig_Node_Expression_Constant(0, 1); + $node = $this->createFilter($date, 'date', array( + 'timezone' => new Twig_Node_Expression_Constant('America/Chicago', 1), + )); + $tests[] = array($node, 'twig_date_format_filter($this->env, 0, null, "America/Chicago")'); + + // underscores vs camelCase for named arguments + $string = new Twig_Node_Expression_Constant('abc', 1); + $node = $this->createFilter($string, 'reverse', array( + 'preserve_keys' => new Twig_Node_Expression_Constant(true, 1), + )); + $tests[] = array($node, 'twig_reverse_filter($this->env, "abc", true)'); + $node = $this->createFilter($string, 'reverse', array( + 'preserveKeys' => new Twig_Node_Expression_Constant(true, 1), + )); + $tests[] = array($node, 'twig_reverse_filter($this->env, "abc", true)'); + + // filter as an anonymous function + if (version_compare(phpversion(), '5.3.0', '>=')) { + $node = $this->createFilter(new Twig_Node_Expression_Constant('foo', 1), 'anonymous'); + $tests[] = array($node, 'call_user_func_array($this->env->getFilter(\'anonymous\')->getCallable(), array("foo"))'); + } + return $tests; } /** - * @covers Twig_Node_Expression_Filter::compile * @expectedException Twig_Error_Syntax - * @expectedExceptionMessage The filter "uppe" does not exist. Did you mean "upper" at line 1 + * @expectedExceptionMessage Unknown argument "foobar" for filter "date". */ - public function testUnknownFilter() + public function testCompileWithWrongNamedArgumentName() { - $node = $this->createFilter(new Twig_Node_Expression_Constant('foo', 1), 'uppe'); - $node->compile($this->getCompiler()); + $date = new Twig_Node_Expression_Constant(0, 1); + $node = $this->createFilter($date, 'date', array( + 'foobar' => new Twig_Node_Expression_Constant('America/Chicago', 1), + )); + + $compiler = $this->getCompiler(); + $compiler->compile($node); + } + + /** + * @expectedException Twig_Error_Syntax + * @expectedExceptionMessage Value for argument "from" is required for filter "replace". + */ + public function testCompileWithMissingNamedArgument() + { + $value = new Twig_Node_Expression_Constant(0, 1); + $node = $this->createFilter($value, 'replace', array( + 'to' => new Twig_Node_Expression_Constant('foo', 1), + )); + + $compiler = $this->getCompiler(); + $compiler->compile($node); } protected function createFilter($node, $name, array $arguments = array()) @@ -83,4 +121,13 @@ protected function createFilter($node, $name, array $arguments = array()) return new Twig_Node_Expression_Filter($node, $name, $arguments, 1); } + + protected function getEnvironment() + { + if (version_compare(phpversion(), '5.3.0', '>=')) { + return include 'PHP53/FilterInclude.php'; + } + + return parent::getEnvironment(); + } } diff --git a/core/vendor/twig/twig/test/Twig/Tests/Node/Expression/FunctionTest.php b/core/vendor/twig/twig/test/Twig/Tests/Node/Expression/FunctionTest.php index 13f48232645d..431dc387c790 100644 --- a/core/vendor/twig/twig/test/Twig/Tests/Node/Expression/FunctionTest.php +++ b/core/vendor/twig/twig/test/Twig/Tests/Node/Expression/FunctionTest.php @@ -33,17 +33,6 @@ public function testCompile($node, $source, $environment = null) parent::testCompile($node, $source, $environment); } - /** - * @covers Twig_Node_Expression_Filter::compile - * @expectedException Twig_Error_Syntax - * @expectedExceptionMessage The function "cycl" does not exist. Did you mean "cycle" at line 1 - */ - public function testUnknownFunction() - { - $node = $this->createFunction('cycl', array()); - $node->compile($this->getCompiler()); - } - public function getTests() { $environment = new Twig_Environment(); @@ -78,6 +67,19 @@ public function getTests() $node = $this->createFunction('foobar', array(new Twig_Node_Expression_Constant('bar', 1))); $tests[] = array($node, 'foobar($this->env, $context, "bar")', $environment); + // named arguments + $node = $this->createFunction('date', array( + 'timezone' => new Twig_Node_Expression_Constant('America/Chicago', 1), + 'date' => new Twig_Node_Expression_Constant(0, 1), + )); + $tests[] = array($node, 'twig_date_converter($this->env, 0, "America/Chicago")'); + + // function as an anonymous function + if (version_compare(phpversion(), '5.3.0', '>=')) { + $node = $this->createFunction('anonymous', array(new Twig_Node_Expression_Constant('foo', 1))); + $tests[] = array($node, 'call_user_func_array($this->env->getFunction(\'anonymous\')->getCallable(), array("foo"))'); + } + return $tests; } @@ -85,4 +87,13 @@ protected function createFunction($name, array $arguments = array()) { return new Twig_Node_Expression_Function($name, new Twig_Node($arguments), 1); } + + protected function getEnvironment() + { + if (version_compare(phpversion(), '5.3.0', '>=')) { + return include 'PHP53/FunctionInclude.php'; + } + + return parent::getEnvironment(); + } } diff --git a/core/vendor/twig/twig/test/Twig/Tests/Node/Expression/PHP53/FilterInclude.php b/core/vendor/twig/twig/test/Twig/Tests/Node/Expression/PHP53/FilterInclude.php new file mode 100644 index 000000000000..15e3aa960a61 --- /dev/null +++ b/core/vendor/twig/twig/test/Twig/Tests/Node/Expression/PHP53/FilterInclude.php @@ -0,0 +1,6 @@ +<?php + +$env = new Twig_Environment(); +$env->addFilter(new Twig_SimpleFilter('anonymous', function () {})); + +return $env; diff --git a/core/vendor/twig/twig/test/Twig/Tests/Node/Expression/PHP53/FunctionInclude.php b/core/vendor/twig/twig/test/Twig/Tests/Node/Expression/PHP53/FunctionInclude.php new file mode 100644 index 000000000000..d2170ed2e3e8 --- /dev/null +++ b/core/vendor/twig/twig/test/Twig/Tests/Node/Expression/PHP53/FunctionInclude.php @@ -0,0 +1,6 @@ +<?php + +$env = new Twig_Environment(); +$env->addFunction(new Twig_SimpleFunction('anonymous', function () {})); + +return $env; diff --git a/core/vendor/twig/twig/test/Twig/Tests/Node/Expression/PHP53/TestInclude.php b/core/vendor/twig/twig/test/Twig/Tests/Node/Expression/PHP53/TestInclude.php new file mode 100644 index 000000000000..636628649f39 --- /dev/null +++ b/core/vendor/twig/twig/test/Twig/Tests/Node/Expression/PHP53/TestInclude.php @@ -0,0 +1,6 @@ +<?php + +$env = new Twig_Environment(); +$env->addTest(new Twig_SimpleTest('anonymous', function () {})); + +return $env; diff --git a/core/vendor/twig/twig/test/Twig/Tests/Node/Expression/TestTest.php b/core/vendor/twig/twig/test/Twig/Tests/Node/Expression/TestTest.php index 4d0cf41c8886..0664150a5dd1 100644 --- a/core/vendor/twig/twig/test/Twig/Tests/Node/Expression/TestTest.php +++ b/core/vendor/twig/twig/test/Twig/Tests/Node/Expression/TestTest.php @@ -41,25 +41,28 @@ public function getTests() $expr = new Twig_Node_Expression_Constant('foo', 1); $node = new Twig_Node_Expression_Test_Null($expr, 'null', new Twig_Node(array()), 1); - $tests[] = array($node, '(null === "foo")'); + // test as an anonymous function + if (version_compare(phpversion(), '5.3.0', '>=')) { + $node = $this->createTest(new Twig_Node_Expression_Constant('foo', 1), 'anonymous', array(new Twig_Node_Expression_Constant('foo', 1))); + $tests[] = array($node, 'call_user_func_array($this->env->getTest(\'anonymous\')->getCallable(), array("foo", "foo"))'); + } + return $tests; } - /** - * @covers Twig_Node_Expression_Filter::compile - * @expectedException Twig_Error_Syntax - * @expectedExceptionMessage The test "nul" does not exist. Did you mean "null" at line 1 - */ - public function testUnknownTest() + protected function createTest($node, $name, array $arguments = array()) { - $node = $this->createTest(new Twig_Node_Expression_Constant('foo', 1), 'nul'); - $node->compile($this->getCompiler()); + return new Twig_Node_Expression_Test($node, $name, new Twig_Node($arguments), 1); } - protected function createTest($node, $name, array $arguments = array()) + protected function getEnvironment() { - return new Twig_Node_Expression_Test($node, $name, new Twig_Node($arguments), 1); + if (version_compare(phpversion(), '5.3.0', '>=')) { + return include 'PHP53/TestInclude.php'; + } + + return parent::getEnvironment(); } } diff --git a/core/vendor/twig/twig/test/Twig/Tests/Node/MacroTest.php b/core/vendor/twig/twig/test/Twig/Tests/Node/MacroTest.php index 39e81315a9ce..4d2f641befb1 100644 --- a/core/vendor/twig/twig/test/Twig/Tests/Node/MacroTest.php +++ b/core/vendor/twig/twig/test/Twig/Tests/Node/MacroTest.php @@ -37,16 +37,20 @@ public function testCompile($node, $source, $environment = null) public function getTests() { $body = new Twig_Node_Text('foo', 1); - $arguments = new Twig_Node(array(new Twig_Node_Expression_Name('foo', 1)), array(), 1); + $arguments = new Twig_Node(array( + 'foo' => new Twig_Node_Expression_Constant(null, 1), + 'bar' => new Twig_Node_Expression_Constant('Foo', 1), + ), array(), 1); $node = new Twig_Node_Macro('foo', $body, $arguments, 1); return array( array($node, <<<EOF // line 1 -public function getfoo(\$_foo = null) +public function getfoo(\$_foo = null, \$_bar = "Foo") { \$context = \$this->env->mergeGlobals(array( "foo" => \$_foo, + "bar" => \$_bar, )); \$blocks = array(); diff --git a/core/vendor/twig/twig/test/Twig/Tests/NodeVisitor/OptimizerTest.php b/core/vendor/twig/twig/test/Twig/Tests/NodeVisitor/OptimizerTest.php index a55d98eeb4eb..d35740d5c58c 100644 --- a/core/vendor/twig/twig/test/Twig/Tests/NodeVisitor/OptimizerTest.php +++ b/core/vendor/twig/twig/test/Twig/Tests/NodeVisitor/OptimizerTest.php @@ -13,7 +13,6 @@ class Twig_Tests_NodeVisitor_OptimizerTest extends PHPUnit_Framework_TestCase public function testRenderBlockOptimizer() { $env = new Twig_Environment(new Twig_Loader_String(), array('cache' => false, 'autoescape' => false)); - $env->addExtension(new Twig_Extension_Optimizer()); $stream = $env->parse($env->tokenize('{{ block("foo") }}', 'index')); @@ -26,7 +25,6 @@ public function testRenderBlockOptimizer() public function testRenderParentBlockOptimizer() { $env = new Twig_Environment(new Twig_Loader_String(), array('cache' => false, 'autoescape' => false)); - $env->addExtension(new Twig_Extension_Optimizer()); $stream = $env->parse($env->tokenize('{% extends "foo" %}{% block content %}{{ parent() }}{% endblock %}', 'index')); @@ -43,7 +41,6 @@ public function testRenderVariableBlockOptimizer() } $env = new Twig_Environment(new Twig_Loader_String(), array('cache' => false, 'autoescape' => false)); - $env->addExtension(new Twig_Extension_Optimizer()); $stream = $env->parse($env->tokenize('{{ block(name|lower) }}', 'index')); $node = $stream->getNode('body')->getNode(0)->getNode(1); @@ -58,7 +55,6 @@ public function testRenderVariableBlockOptimizer() public function testForOptimizer($template, $expected) { $env = new Twig_Environment(new Twig_Loader_String(), array('cache' => false)); - $env->addExtension(new Twig_Extension_Optimizer()); $stream = $env->parse($env->tokenize($template, 'index')); diff --git a/core/vendor/twig/twig/test/Twig/Tests/TemplateTest.php b/core/vendor/twig/twig/test/Twig/Tests/TemplateTest.php index 75103d15d988..448bdf895646 100644 --- a/core/vendor/twig/twig/test/Twig/Tests/TemplateTest.php +++ b/core/vendor/twig/twig/test/Twig/Tests/TemplateTest.php @@ -61,6 +61,84 @@ public function getAttributeExceptions() return $tests; } + /** + * @dataProvider getGetAttributeWithSandbox + */ + public function testGetAttributeWithSandbox($object, $item, $allowed, $useExt) + { + $twig = new Twig_Environment(); + $policy = new Twig_Sandbox_SecurityPolicy(array(), array(), array(/*methid*/), array(/*peop*/), array()); + $twig->addExtension(new Twig_Extension_Sandbox($policy, !$allowed)); + $template = new Twig_TemplateTest($twig, $useExt); + + try { + $template->getAttribute($object, $item, array(), 'any'); + + if (!$allowed) { + $this->fail(); + } + } catch (Twig_Sandbox_SecurityError $e) { + if ($allowed) { + $this->fail(); + } + + $this->assertContains('is not allowed', $e->getMessage()); + } + } + + public function getGetAttributeWithSandbox() + { + $tests = array( + array(new Twig_TemplatePropertyObject(), 'defined', false, false), + array(new Twig_TemplatePropertyObject(), 'defined', true, false), + array(new Twig_TemplateMethodObject(), 'defined', false, false), + array(new Twig_TemplateMethodObject(), 'defined', true, false), + ); + + if (function_exists('twig_template_get_attributes')) { + foreach (array_slice($tests, 0) as $test) { + $test[3] = true; + $tests[] = $test; + } + } + + return $tests; + } + + /** + * @dataProvider getGetAttributeWithTemplateAsObject + */ + public function testGetAttributeWithTemplateAsObject($useExt) + { + $template = new Twig_TemplateTest(new Twig_Environment(), $useExt); + $template1 = new Twig_TemplateTest(new Twig_Environment(), false); + + $this->assertInstanceof('Twig_Markup', $template->getAttribute($template1, 'string')); + $this->assertEquals('some_string', $template->getAttribute($template1, 'string')); + + $this->assertInstanceof('Twig_Markup', $template->getAttribute($template1, 'true')); + $this->assertEquals('1', $template->getAttribute($template1, 'true')); + + $this->assertInstanceof('Twig_Markup', $template->getAttribute($template1, 'zero')); + $this->assertEquals('0', $template->getAttribute($template1, 'zero')); + + $this->assertNotInstanceof('Twig_Markup', $template->getAttribute($template1, 'empty')); + $this->assertSame('', $template->getAttribute($template1, 'empty')); + } + + public function getGetAttributeWithTemplateAsObject() + { + $bools = array( + array(false), + ); + + if (function_exists('twig_template_get_attributes')) { + $bools[] = array(true); + } + + return $bools; + } + /** * @dataProvider getGetAttributeTests */ @@ -120,6 +198,7 @@ public function getGetAttributeTests() 'zero' => 0, 'null' => null, '1' => 1, + 'bar' => true, ); $objectArray = new Twig_TemplateArrayAccessObject(); @@ -144,6 +223,7 @@ public function getGetAttributeTests() array(true, 1, 1), array(true, 1, 1.0), array(true, null, 'null'), + array(true, true, 'bar'), ); $testObjects = array( // array(object, type of fetch) @@ -243,6 +323,26 @@ public function __construct(Twig_Environment $env, $useExtGetAttribute = false) Twig_Template::clearCache(); } + public function getZero() + { + return 0; + } + + public function getEmpty() + { + return ''; + } + + public function getString() + { + return 'some_string'; + } + + public function getTrue() + { + return true; + } + public function getTemplateName() { } @@ -279,6 +379,7 @@ class Twig_TemplateArrayAccessObject implements ArrayAccess 'zero' => 0, 'null' => null, '1' => 1, + 'bar' => true, ); public function offsetExists($name) @@ -308,6 +409,7 @@ class Twig_TemplateMagicPropertyObject 'zero' => 0, 'null' => null, '1' => 1, + 'bar' => true, ); protected $protected = 'protected'; @@ -328,6 +430,7 @@ class Twig_TemplatePropertyObject public $defined = 'defined'; public $zero = 0; public $null = null; + public $bar = true; protected $protected = 'protected'; } @@ -385,6 +488,11 @@ public function getNull() return null; } + public function isBar() + { + return true; + } + protected function getProtected() { return 'protected'; diff --git a/core/vendor/twig/twig/test/Twig/Tests/TokenStreamTest.php b/core/vendor/twig/twig/test/Twig/Tests/TokenStreamTest.php index 4edb8c31d8b0..fd4ec633767e 100644 --- a/core/vendor/twig/twig/test/Twig/Tests/TokenStreamTest.php +++ b/core/vendor/twig/twig/test/Twig/Tests/TokenStreamTest.php @@ -38,4 +38,33 @@ public function testNext() } $this->assertEquals('1, 2, 3, 4, 5, 6, 7', implode(', ', $repr), '->next() advances the pointer and returns the current token'); } + + /** + * @expectedException Twig_Error_Syntax + * @expectedMessage Unexpected end of template + */ + public function testEndOfTemplateNext() + { + $stream = new Twig_TokenStream(array( + new Twig_Token(Twig_Token::BLOCK_START_TYPE, 1, 1), + )); + while (!$stream->isEOF()) { + $stream->next(); + } + } + + /** + * @expectedException Twig_Error_Syntax + * @expectedMessage Unexpected end of template + */ + public function testEndOfTemplateLook() + { + $stream = new Twig_TokenStream(array( + new Twig_Token(Twig_Token::BLOCK_START_TYPE, 1, 1), + )); + while (!$stream->isEOF()) { + $stream->look(); + $stream->next(); + } + } } -- GitLab