RSS Git Download  Clone
Raw View History
Blames found: 1 Mode: text Binary: false


Hang on, we reloading big blames...
<?php /* * This file is part of the Silex framework. * * (c) Fabien Potencier <fabien@symfony.com> * * This source file is subject to the MIT license that is bundled * with this source code in the file LICENSE. */ Phar::mapPhar('silex.phar'); require_once 'phar://silex.phar/vendor/autoload.php'; if ('cli' === php_sapi_name() && basename(__FILE__) === basename($_SERVER['argv'][0]) && isset($_SERVER['argv'][1])) { switch ($_SERVER['argv'][1]) { case 'update': $remoteFilename = 'http://silex.sensiolabs.org/get/silex.phar'; $localFilename = __DIR__.'/silex.phar'; file_put_contents($localFilename, file_get_contents($remoteFilename)); break; case 'check': $latest = trim(file_get_contents('http://silex.sensiolabs.org/get/version')); if ($latest != Silex\Application::VERSION) { printf("A newer Silex version is available (%s).\n", $latest); } else { print("You are using the latest Silex version.\n"); } break; case 'version': printf("Silex version %s\n", Silex\Application::VERSION); break; default: printf("Unknown command '%s' (available commands: version, check, and update).\n", $_SERVER['argv'][1]); } exit(0); } __HALT_COMPILER(); ?> ij� silex.pharsrc/Silex/Application.php�)8H�O�)�q':�src/Silex/Controller.php)8H�O)E� �"src/Silex/ControllerCollection.php�8H�O��b��)src/Silex/ControllerProviderInterface.php|8H�O|���4� src/Silex/ControllerResolver.php 8H�O Ė2�1src/Silex/Exception/ControllerFrozenException.phpo8H�OoR���src/Silex/ExceptionHandler.php�8H�O�O��ж&src/Silex/GetResponseForErrorEvent.php�8H�O��Iq�src/Silex/HttpCache.phpc8H�Ocb;b�src/Silex/LazyUrlMatcher.phpj8H�Oj6μ��.src/Silex/Provider/DoctrineServiceProvider.php 8H�O 9�:��*src/Silex/Provider/FormServiceProvider.php8H�O�Po�/src/Silex/Provider/HttpCacheServiceProvider.php8H�OS��׶-src/Silex/Provider/MonologServiceProvider.php�8H�O�6F]�-src/Silex/Provider/SessionServiceProvider.php�8H�O���?t�1src/Silex/Provider/SwiftmailerServiceProvider.php{ 8H�O{ +]�>�4src/Silex/Provider/SymfonyBridgesServiceProvider.php�8H�O�*Shƶ1src/Silex/Provider/TranslationServiceProvider.php�8H�O��P+��(src/Silex/Provider/TwigCoreExtension.php8H�O?����*src/Silex/Provider/TwigServiceProvider.php�8H�O�����2src/Silex/Provider/UrlGeneratorServiceProvider.php�8H�O�,��{�/src/Silex/Provider/ValidatorServiceProvider.php8H�O;oy�$src/Silex/RedirectableUrlMatcher.php�8H�O�|6.ٶ&src/Silex/ServiceProviderInterface.phpx8H�Ox�J��src/Silex/SilexEvents.php�8H�O�n�Ƕ%src/Silex/StringResponseConverter.php 8H�O E=V�src/Silex/WebTestCase.php�8H�O�܋�Ӷ#vendor/pimple/pimple/lib/Pimple.phpO8H�OO\)ś�Lvendor/symfony/class-loader/Symfony/Component/ClassLoader/ApcClassLoader.php,8H�O,�~�Uvendor/symfony/class-loader/Symfony/Component/ClassLoader/ApcUniversalClassLoader.php?8H�O?��϶Svendor/symfony/class-loader/Symfony/Component/ClassLoader/ClassCollectionLoader.php� 8H�O� 4�y��Ivendor/symfony/class-loader/Symfony/Component/ClassLoader/ClassLoader.php�8H�O�Oǔ��Ovendor/symfony/class-loader/Symfony/Component/ClassLoader/ClassMapGenerator.php~8H�O~6� 8�Nvendor/symfony/class-loader/Symfony/Component/ClassLoader/DebugClassLoader.php�8H�O���߶Wvendor/symfony/class-loader/Symfony/Component/ClassLoader/DebugUniversalClassLoader.php 8H�O i��1�Lvendor/symfony/class-loader/Symfony/Component/ClassLoader/MapClassLoader.phpt8H�Ot�j�Rvendor/symfony/class-loader/Symfony/Component/ClassLoader/UniversalClassLoader.phpz 8H�Oz �}z{�Ovendor/symfony/class-loader/Symfony/Component/ClassLoader/XcacheClassLoader.phpU8H�OU�WVS�cvendor/symfony/event-dispatcher/Symfony/Component/EventDispatcher/ContainerAwareEventDispatcher.php� 8H�O� �o��mvendor/symfony/event-dispatcher/Symfony/Component/EventDispatcher/Debug/TraceableEventDispatcherInterface.php�8H�O��U���Kvendor/symfony/event-dispatcher/Symfony/Component/EventDispatcher/Event.php�8H�O�\1P�Uvendor/symfony/event-dispatcher/Symfony/Component/EventDispatcher/EventDispatcher.phpU 8H�OU ��[N�^vendor/symfony/event-dispatcher/Symfony/Component/EventDispatcher/EventDispatcherInterface.php!8H�O!��,�^vendor/symfony/event-dispatcher/Symfony/Component/EventDispatcher/EventSubscriberInterface.php�8H�O��X�V�Rvendor/symfony/event-dispatcher/Symfony/Component/EventDispatcher/GenericEvent.php'8H�O'��ɶQvendor/symfony/http-foundation/Symfony/Component/HttpFoundation/ApacheRequest.phpC8H�OCrp���Jvendor/symfony/http-foundation/Symfony/Component/HttpFoundation/Cookie.php�8H�O�ѕ�/�hvendor/symfony/http-foundation/Symfony/Component/HttpFoundation/File/Exception/AccessDeniedException.php�8H�O����6�`vendor/symfony/http-foundation/Symfony/Component/HttpFoundation/File/Exception/FileException.php�8H�O���!��hvendor/symfony/http-foundation/Symfony/Component/HttpFoundation/File/Exception/FileNotFoundException.php�8H�O���r�jvendor/symfony/http-foundation/Symfony/Component/HttpFoundation/File/Exception/UnexpectedTypeException.phpK8H�OK�ˤ�bvendor/symfony/http-foundation/Symfony/Component/HttpFoundation/File/Exception/UploadException.php�8H�O�T��Mvendor/symfony/http-foundation/Symfony/Component/HttpFoundation/File/File.php�8H�O��#��bvendor/symfony/http-foundation/Symfony/Component/HttpFoundation/File/MimeType/ExtensionGuesser.php�8H�O���rh�kvendor/symfony/http-foundation/Symfony/Component/HttpFoundation/File/MimeType/ExtensionGuesserInterface.php�8H�O���ʶkvendor/symfony/http-foundation/Symfony/Component/HttpFoundation/File/MimeType/FileBinaryMimeTypeGuesser.php�8H�O�YbS�ivendor/symfony/http-foundation/Symfony/Component/HttpFoundation/File/MimeType/FileinfoMimeTypeGuesser.php�8H�O�8��jvendor/symfony/http-foundation/Symfony/Component/HttpFoundation/File/MimeType/MimeTypeExtensionGuesser.phpdk8H�Odkl�?��avendor/symfony/http-foundation/Symfony/Component/HttpFoundation/File/MimeType/MimeTypeGuesser.php)8H�O)P�� �jvendor/symfony/http-foundation/Symfony/Component/HttpFoundation/File/MimeType/MimeTypeGuesserInterface.php�8H�O�a�(�Uvendor/symfony/http-foundation/Symfony/Component/HttpFoundation/File/UploadedFile.phpw8H�Owlp�$�Kvendor/symfony/http-foundation/Symfony/Component/HttpFoundation/FileBag.php�8H�O���时Mvendor/symfony/http-foundation/Symfony/Component/HttpFoundation/HeaderBag.php�8H�O�?0�ܶPvendor/symfony/http-foundation/Symfony/Component/HttpFoundation/JsonResponse.php�8H�O����ƶPvendor/symfony/http-foundation/Symfony/Component/HttpFoundation/ParameterBag.php� 8H�O� �!�y�Tvendor/symfony/http-foundation/Symfony/Component/HttpFoundation/RedirectResponse.phpa8H�Oasj�b�Kvendor/symfony/http-foundation/Symfony/Component/HttpFoundation/Request.phpXM8H�OXM�|i��Rvendor/symfony/http-foundation/Symfony/Component/HttpFoundation/RequestMatcher.php� 8H�O� C~��[vendor/symfony/http-foundation/Symfony/Component/HttpFoundation/RequestMatcherInterface.php�8H�O�w�� �kvendor/symfony/http-foundation/Symfony/Component/HttpFoundation/Resources/stubs/SessionHandlerInterface.php28H�O2��a�Lvendor/symfony/http-foundation/Symfony/Component/HttpFoundation/Response.php18H�O1R�)=�Uvendor/symfony/http-foundation/Symfony/Component/HttpFoundation/ResponseHeaderBag.php�8H�O�C�k�Mvendor/symfony/http-foundation/Symfony/Component/HttpFoundation/ServerBag.php�8H�O�H���bvendor/symfony/http-foundation/Symfony/Component/HttpFoundation/Session/Attribute/AttributeBag.php;8H�O;�xj�kvendor/symfony/http-foundation/Symfony/Component/HttpFoundation/Session/Attribute/AttributeBagInterface.php�8H�O���.u�lvendor/symfony/http-foundation/Symfony/Component/HttpFoundation/Session/Attribute/NamespacedAttributeBag.php�8H�O�A���dvendor/symfony/http-foundation/Symfony/Component/HttpFoundation/Session/Flash/AutoExpireFlashBag.php�8H�O� ��Zvendor/symfony/http-foundation/Symfony/Component/HttpFoundation/Session/Flash/FlashBag.php�8H�O�f�J1�cvendor/symfony/http-foundation/Symfony/Component/HttpFoundation/Session/Flash/FlashBagInterface.php8H�OI���Svendor/symfony/http-foundation/Symfony/Component/HttpFoundation/Session/Session.php�8H�O����_vendor/symfony/http-foundation/Symfony/Component/HttpFoundation/Session/SessionBagInterface.php�8H�O�M�O�\vendor/symfony/http-foundation/Symfony/Component/HttpFoundation/Session/SessionInterface.php�8H�O�o:>e�svendor/symfony/http-foundation/Symfony/Component/HttpFoundation/Session/Storage/Handler/MemcachedSessionHandler.php:8H�O:%0v˶rvendor/symfony/http-foundation/Symfony/Component/HttpFoundation/Session/Storage/Handler/MemcacheSessionHandler.php 8H�O 9���qvendor/symfony/http-foundation/Symfony/Component/HttpFoundation/Session/Storage/Handler/MongoDbSessionHandler.php}8H�O}5�b�tvendor/symfony/http-foundation/Symfony/Component/HttpFoundation/Session/Storage/Handler/NativeFileSessionHandler.php�8H�O��',�yvendor/symfony/http-foundation/Symfony/Component/HttpFoundation/Session/Storage/Handler/NativeMemcachedSessionHandler.php�8H�O�B*}�xvendor/symfony/http-foundation/Symfony/Component/HttpFoundation/Session/Storage/Handler/NativeMemcacheSessionHandler.php58H�O5Z�md�uvendor/symfony/http-foundation/Symfony/Component/HttpFoundation/Session/Storage/Handler/NativeRedisSessionHandler.php8H�O�yZ�pvendor/symfony/http-foundation/Symfony/Component/HttpFoundation/Session/Storage/Handler/NativeSessionHandler.php�8H�O�e �_�vvendor/symfony/http-foundation/Symfony/Component/HttpFoundation/Session/Storage/Handler/NativeSqliteSessionHandler.php�8H�O�RJ�b�nvendor/symfony/http-foundation/Symfony/Component/HttpFoundation/Session/Storage/Handler/NullSessionHandler.php�8H�O�3�"�mvendor/symfony/http-foundation/Symfony/Component/HttpFoundation/Session/Storage/Handler/PdoSessionHandler.php�8H�O��G\�_vendor/symfony/http-foundation/Symfony/Component/HttpFoundation/Session/Storage/MetadataBag.php#8H�O#�⩶kvendor/symfony/http-foundation/Symfony/Component/HttpFoundation/Session/Storage/MockArraySessionStorage.php� 8H�O� #)�jvendor/symfony/http-foundation/Symfony/Component/HttpFoundation/Session/Storage/MockFileSessionStorage.php-8H�O- -0�hvendor/symfony/http-foundation/Symfony/Component/HttpFoundation/Session/Storage/NativeSessionStorage.php8H�O���gvendor/symfony/http-foundation/Symfony/Component/HttpFoundation/Session/Storage/Proxy/AbstractProxy.php8H�ON��+�evendor/symfony/http-foundation/Symfony/Component/HttpFoundation/Session/Storage/Proxy/NativeProxy.php8H�O����mvendor/symfony/http-foundation/Symfony/Component/HttpFoundation/Session/Storage/Proxy/SessionHandlerProxy.php!8H�O!RM#��kvendor/symfony/http-foundation/Symfony/Component/HttpFoundation/Session/Storage/SessionStorageInterface.php�8H�O��^��Tvendor/symfony/http-foundation/Symfony/Component/HttpFoundation/StreamedResponse.phpz8H�Oz��C{�Ivendor/symfony/http-kernel/Symfony/Component/HttpKernel/Bundle/Bundle.php� 8H�O� .��Rvendor/symfony/http-kernel/Symfony/Component/HttpKernel/Bundle/BundleInterface.php�8H�O�3%�{�^vendor/symfony/http-kernel/Symfony/Component/HttpKernel/CacheClearer/CacheClearerInterface.php�8H�O���\��Zvendor/symfony/http-kernel/Symfony/Component/HttpKernel/CacheClearer/ChainCacheClearer.php�8H�O���:�Svendor/symfony/http-kernel/Symfony/Component/HttpKernel/CacheWarmer/CacheWarmer.php�8H�O��m�7�\vendor/symfony/http-kernel/Symfony/Component/HttpKernel/CacheWarmer/CacheWarmerAggregate.php?8H�O?RM޶\vendor/symfony/http-kernel/Symfony/Component/HttpKernel/CacheWarmer/CacheWarmerInterface.php�8H�O�7�7�Yvendor/symfony/http-kernel/Symfony/Component/HttpKernel/CacheWarmer/WarmableInterface.php�8H�O�L�?�Bvendor/symfony/http-kernel/Symfony/Component/HttpKernel/Client.php 8H�O !�Y��Nvendor/symfony/http-kernel/Symfony/Component/HttpKernel/Config/FileLocator.php�8H�O�/�Ri�Yvendor/symfony/http-kernel/Symfony/Component/HttpKernel/Controller/ControllerResolver.php� 8H�O� @�.�bvendor/symfony/http-kernel/Symfony/Component/HttpKernel/Controller/ControllerResolverInterface.php(8H�O(0�� �]vendor/symfony/http-kernel/Symfony/Component/HttpKernel/DataCollector/ConfigDataCollector.php�8H�O�� ��Wvendor/symfony/http-kernel/Symfony/Component/HttpKernel/DataCollector/DataCollector.phpp8H�Op�g}Ƕ`vendor/symfony/http-kernel/Symfony/Component/HttpKernel/DataCollector/DataCollectorInterface.php�8H�O����C�\vendor/symfony/http-kernel/Symfony/Component/HttpKernel/DataCollector/EventDataCollector.phpm8H�Omg��&�`vendor/symfony/http-kernel/Symfony/Component/HttpKernel/DataCollector/ExceptionDataCollector.php�8H�O�;�Ӏ�]vendor/symfony/http-kernel/Symfony/Component/HttpKernel/DataCollector/LoggerDataCollector.php�8H�O�>mn��]vendor/symfony/http-kernel/Symfony/Component/HttpKernel/DataCollector/MemoryDataCollector.php�8H�O� Ķ^vendor/symfony/http-kernel/Symfony/Component/HttpKernel/DataCollector/RequestDataCollector.phpV8H�OV�T<�[vendor/symfony/http-kernel/Symfony/Component/HttpKernel/DataCollector/TimeDataCollector.php68H�O6�W�hvendor/symfony/http-kernel/Symfony/Component/HttpKernel/Debug/ContainerAwareTraceableEventDispatcher.php 8H�O E�$��Nvendor/symfony/http-kernel/Symfony/Component/HttpKernel/Debug/ErrorHandler.php8H�Oλ#��Rvendor/symfony/http-kernel/Symfony/Component/HttpKernel/Debug/ExceptionHandler.php� 8H�O� tw.۶Kvendor/symfony/http-kernel/Symfony/Component/HttpKernel/Debug/Stopwatch.php 8H�O :=�̶Pvendor/symfony/http-kernel/Symfony/Component/HttpKernel/Debug/StopwatchEvent.php�8H�O���϶evendor/symfony/http-kernel/Symfony/Component/HttpKernel/DependencyInjection/AddClassesToCachePass.php98H�O9�CGs�evendor/symfony/http-kernel/Symfony/Component/HttpKernel/DependencyInjection/ConfigurableExtension.php�8H�O��&��Yvendor/symfony/http-kernel/Symfony/Component/HttpKernel/DependencyInjection/Extension.phpT8H�OT��-�ovendor/symfony/http-kernel/Symfony/Component/HttpKernel/DependencyInjection/MergeExtensionConfigurationPass.php�8H�O���s�Wvendor/symfony/http-kernel/Symfony/Component/HttpKernel/Event/FilterControllerEvent.php�8H�O�S����Uvendor/symfony/http-kernel/Symfony/Component/HttpKernel/Event/FilterResponseEvent.php�8H�O�V�h��Rvendor/symfony/http-kernel/Symfony/Component/HttpKernel/Event/GetResponseEvent.php�8H�O���evendor/symfony/http-kernel/Symfony/Component/HttpKernel/Event/GetResponseForControllerResultEvent.php<8H�O<u8kM�^vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Event/GetResponseForExceptionEvent.phpm8H�Om2Dĭ�Mvendor/symfony/http-kernel/Symfony/Component/HttpKernel/Event/KernelEvent.php�8H�O�>�L�Svendor/symfony/http-kernel/Symfony/Component/HttpKernel/Event/PostResponseEvent.php�8H�O�����Uvendor/symfony/http-kernel/Symfony/Component/HttpKernel/EventListener/EsiListener.phpy8H�Oy[��k�[vendor/symfony/http-kernel/Symfony/Component/HttpKernel/EventListener/ExceptionListener.php� 8H�O� �O��Xvendor/symfony/http-kernel/Symfony/Component/HttpKernel/EventListener/LocaleListener.php�8H�O�r4�3�Zvendor/symfony/http-kernel/Symfony/Component/HttpKernel/EventListener/ProfilerListener.php# 8H�O# �&Z~�Zvendor/symfony/http-kernel/Symfony/Component/HttpKernel/EventListener/ResponseListener.phpp8H�OpQ����Xvendor/symfony/http-kernel/Symfony/Component/HttpKernel/EventListener/RouterListener.php� 8H�O� ڡ�~�bvendor/symfony/http-kernel/Symfony/Component/HttpKernel/EventListener/StreamedResponseListener.php+8H�O+[`2a�_vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Exception/AccessDeniedHttpException.php"8H�O"����Vvendor/symfony/http-kernel/Symfony/Component/HttpKernel/Exception/FlattenException.phpq8H�OqH?ﻶSvendor/symfony/http-kernel/Symfony/Component/HttpKernel/Exception/HttpException.php*8H�O*WmK��\vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Exception/HttpExceptionInterface.php�8H�O�M�#�cvendor/symfony/http-kernel/Symfony/Component/HttpKernel/Exception/MethodNotAllowedHttpException.phpv8H�Ov-u{F�[vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Exception/NotFoundHttpException.php8H�O��Ivendor/symfony/http-kernel/Symfony/Component/HttpKernel/HttpCache/Esi.php�8H�O�f�A��^vendor/symfony/http-kernel/Symfony/Component/HttpKernel/HttpCache/EsiResponseCacheStrategy.phpb8H�Ob���gvendor/symfony/http-kernel/Symfony/Component/HttpKernel/HttpCache/EsiResponseCacheStrategyInterface.php�8H�O�GaZ�Ovendor/symfony/http-kernel/Symfony/Component/HttpKernel/HttpCache/HttpCache.phpZ'8H�OZ'��s۶Kvendor/symfony/http-kernel/Symfony/Component/HttpKernel/HttpCache/Store.phpj8H�Oj<�ٱ�Tvendor/symfony/http-kernel/Symfony/Component/HttpKernel/HttpCache/StoreInterface.php�8H�O� ���Fvendor/symfony/http-kernel/Symfony/Component/HttpKernel/HttpKernel.php78H�O7r����Ovendor/symfony/http-kernel/Symfony/Component/HttpKernel/HttpKernelInterface.phpS8H�OSg?z�Bvendor/symfony/http-kernel/Symfony/Component/HttpKernel/Kernel.phpp18H�Op1�׼w�Hvendor/symfony/http-kernel/Symfony/Component/HttpKernel/KernelEvents.php8H�O1���Kvendor/symfony/http-kernel/Symfony/Component/HttpKernel/KernelInterface.php�8H�O����Tvendor/symfony/http-kernel/Symfony/Component/HttpKernel/Log/DebugLoggerInterface.php�8H�O��s���Ovendor/symfony/http-kernel/Symfony/Component/HttpKernel/Log/LoggerInterface.php8H�O�|��Jvendor/symfony/http-kernel/Symfony/Component/HttpKernel/Log/NullLogger.php�8H�O�<�(��`vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Profiler/BaseMemcacheProfilerStorage.php�8H�O�=^ǀ�Xvendor/symfony/http-kernel/Symfony/Component/HttpKernel/Profiler/FileProfilerStorage.php�8H�O�q���]vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Profiler/MemcachedProfilerStorage.php%8H�O%��Y�\vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Profiler/MemcacheProfilerStorage.php�8H�O���!z�[vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Profiler/MongoDbProfilerStorage.php�8H�O�F=�Yvendor/symfony/http-kernel/Symfony/Component/HttpKernel/Profiler/MysqlProfilerStorage.php�8H�O�5�\�Wvendor/symfony/http-kernel/Symfony/Component/HttpKernel/Profiler/PdoProfilerStorage.php�8H�O�� �Lvendor/symfony/http-kernel/Symfony/Component/HttpKernel/Profiler/Profile.php�8H�O�S����Mvendor/symfony/http-kernel/Symfony/Component/HttpKernel/Profiler/Profiler.phpF 8H�OF �s�]vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Profiler/ProfilerStorageInterface.php8H�O!)���Yvendor/symfony/http-kernel/Symfony/Component/HttpKernel/Profiler/RedisProfilerStorage.php�8H�O��ѓȶZvendor/symfony/http-kernel/Symfony/Component/HttpKernel/Profiler/SqliteProfilerStorage.phpY 8H�OY ��.��Ovendor/symfony/http-kernel/Symfony/Component/HttpKernel/TerminableInterface.php8H�O�z��Evendor/symfony/routing/Symfony/Component/Routing/Annotation/Route.php 8H�O w}<^�Bvendor/symfony/routing/Symfony/Component/Routing/CompiledRoute.php8H�O���˶Qvendor/symfony/routing/Symfony/Component/Routing/Exception/ExceptionInterface.phph8H�Oh�a���Xvendor/symfony/routing/Symfony/Component/Routing/Exception/InvalidParameterException.php�8H�O��gj0�Xvendor/symfony/routing/Symfony/Component/Routing/Exception/MethodNotAllowedException.php�8H�O��癶bvendor/symfony/routing/Symfony/Component/Routing/Exception/MissingMandatoryParametersException.php�8H�O�A^ r�Xvendor/symfony/routing/Symfony/Component/Routing/Exception/ResourceNotFoundException.php�8H�O��J�#�Uvendor/symfony/routing/Symfony/Component/Routing/Exception/RouteNotFoundException.php�8H�O��\�Uvendor/symfony/routing/Symfony/Component/Routing/Generator/Dumper/GeneratorDumper.phpc8H�Oc=�/%�^vendor/symfony/routing/Symfony/Component/Routing/Generator/Dumper/GeneratorDumperInterface.php�8H�O������Xvendor/symfony/routing/Symfony/Component/Routing/Generator/Dumper/PhpGeneratorDumper.php�8H�O��3AF�Kvendor/symfony/routing/Symfony/Component/Routing/Generator/UrlGenerator.phpI 8H�OI ����Tvendor/symfony/routing/Symfony/Component/Routing/Generator/UrlGeneratorInterface.phpa8H�OaR�L�Qvendor/symfony/routing/Symfony/Component/Routing/Loader/AnnotationClassLoader.php� 8H�O� hр�Uvendor/symfony/routing/Symfony/Component/Routing/Loader/AnnotationDirectoryLoader.php�8H�O�{4zͶPvendor/symfony/routing/Symfony/Component/Routing/Loader/AnnotationFileLoader.php&8H�O&-�K��Ivendor/symfony/routing/Symfony/Component/Routing/Loader/ClosureLoader.php~8H�O~�ӎ��Ivendor/symfony/routing/Symfony/Component/Routing/Loader/PhpFileLoader.php�8H�O�`�ضIvendor/symfony/routing/Symfony/Component/Routing/Loader/XmlFileLoader.php�8H�O��f;�Jvendor/symfony/routing/Symfony/Component/Routing/Loader/YamlFileLoader.phpn 8H�On ���J�Mvendor/symfony/routing/Symfony/Component/Routing/Matcher/ApacheUrlMatcher.php]8H�O]��N9�Wvendor/symfony/routing/Symfony/Component/Routing/Matcher/Dumper/ApacheMatcherDumper.php& 8H�O& K���Qvendor/symfony/routing/Symfony/Component/Routing/Matcher/Dumper/MatcherDumper.phpb8H�Ob�^��Zvendor/symfony/routing/Symfony/Component/Routing/Matcher/Dumper/MatcherDumperInterface.php�8H�O��>�I�Tvendor/symfony/routing/Symfony/Component/Routing/Matcher/Dumper/PhpMatcherDumper.php�8H�O��?̶Svendor/symfony/routing/Symfony/Component/Routing/Matcher/RedirectableUrlMatcher.php�8H�O�N\�l�\vendor/symfony/routing/Symfony/Component/Routing/Matcher/RedirectableUrlMatcherInterface.php�8H�O�)彶Pvendor/symfony/routing/Symfony/Component/Routing/Matcher/TraceableUrlMatcher.php� 8H�O� ��c�Gvendor/symfony/routing/Symfony/Component/Routing/Matcher/UrlMatcher.php� 8H�O� �į��Pvendor/symfony/routing/Symfony/Component/Routing/Matcher/UrlMatcherInterface.phpy8H�Oyd���Cvendor/symfony/routing/Symfony/Component/Routing/RequestContext.php& 8H�O& L\ŶQvendor/symfony/routing/Symfony/Component/Routing/RequestContextAwareInterface.php�8H�O��-L �:vendor/symfony/routing/Symfony/Component/Routing/Route.phpp8H�Op���Dvendor/symfony/routing/Symfony/Component/Routing/RouteCollection.php-8H�O-T�"l�Bvendor/symfony/routing/Symfony/Component/Routing/RouteCompiler.phpZ 8H�OZ x����Kvendor/symfony/routing/Symfony/Component/Routing/RouteCompilerInterface.php�8H�O�d���;vendor/symfony/routing/Symfony/Component/Routing/Router.phpM8H�OMՍ�B�Dvendor/symfony/routing/Symfony/Component/Routing/RouterInterface.php-8H�O-_�Bvendor/symfony/browser-kit/Symfony/Component/BrowserKit/Client.php�8H�O�� N�Bvendor/symfony/browser-kit/Symfony/Component/BrowserKit/Cookie.php�8H�O�t��G�Evendor/symfony/browser-kit/Symfony/Component/BrowserKit/CookieJar.phpc 8H�Oc B*W��Cvendor/symfony/browser-kit/Symfony/Component/BrowserKit/History.php08H�O0���Cvendor/symfony/browser-kit/Symfony/Component/BrowserKit/Request.php�8H�O�y^�Dvendor/symfony/browser-kit/Symfony/Component/BrowserKit/Response.php8H�O�{³�Ivendor/symfony/css-selector/Symfony/Component/CssSelector/CssSelector.php�8H�O� ����Vvendor/symfony/css-selector/Symfony/Component/CssSelector/Exception/ParseException.phpx8H�OxH%�Mvendor/symfony/css-selector/Symfony/Component/CssSelector/Node/AttribNode.phpA 8H�OA ��d�Lvendor/symfony/css-selector/Symfony/Component/CssSelector/Node/ClassNode.php�8H�O�wLWvendor/symfony/css-selector/Symfony/Component/CssSelector/Node/CombinedSelectorNode.php�8H�O� �e8�Nvendor/symfony/css-selector/Symfony/Component/CssSelector/Node/ElementNode.php8H�O��ݶOvendor/symfony/css-selector/Symfony/Component/CssSelector/Node/FunctionNode.php8H�O^w�@�Kvendor/symfony/css-selector/Symfony/Component/CssSelector/Node/HashNode.php68H�O6���Pvendor/symfony/css-selector/Symfony/Component/CssSelector/Node/NodeInterface.php�8H�O��%���Ivendor/symfony/css-selector/Symfony/Component/CssSelector/Node/OrNode.php�8H�O�r��Mvendor/symfony/css-selector/Symfony/Component/CssSelector/Node/PseudoNode.php� 8H�O� A�'�Cvendor/symfony/css-selector/Symfony/Component/CssSelector/Token.php�8H�O��M�>�Gvendor/symfony/css-selector/Symfony/Component/CssSelector/Tokenizer.php� 8H�O� �G��Ivendor/symfony/css-selector/Symfony/Component/CssSelector/TokenStream.phpc8H�Oc��f�Gvendor/symfony/css-selector/Symfony/Component/CssSelector/XPathExpr.php4 8H�O4 |���Ivendor/symfony/css-selector/Symfony/Component/CssSelector/XPathExprOr.php�8H�O���s[�Cvendor/symfony/dom-crawler/Symfony/Component/DomCrawler/Crawler.php�8H�O�� �.�Qvendor/symfony/dom-crawler/Symfony/Component/DomCrawler/Field/ChoiceFormField.php8H�O �B�Ovendor/symfony/dom-crawler/Symfony/Component/DomCrawler/Field/FileFormField.php�8H�O�R��Kvendor/symfony/dom-crawler/Symfony/Component/DomCrawler/Field/FormField.php�8H�O�gr��Pvendor/symfony/dom-crawler/Symfony/Component/DomCrawler/Field/InputFormField.php�8H�O��*Q�Svendor/symfony/dom-crawler/Symfony/Component/DomCrawler/Field/TextareaFormField.php�8H�O���}ʶ@vendor/symfony/dom-crawler/Symfony/Component/DomCrawler/Form.php98H�O9��/{�@vendor/symfony/dom-crawler/Symfony/Component/DomCrawler/Link.phpM8H�OMS��r�LICENSE$8H�O$�Y�vendor/autoload.php8H�O��a[�vendor/composer/ClassLoader.phpA 8H�OA �s_��'vendor/composer/autoload_namespaces.php�8H�O��&��%vendor/composer/autoload_classmap.phpZ8H�OZ�ᖶ<?php namespace Silex; use Symfony\Component\HttpKernel\HttpKernel; use Symfony\Component\HttpKernel\HttpKernelInterface; use Symfony\Component\HttpKernel\TerminableInterface; use Symfony\Component\HttpKernel\Event\KernelEvent; use Symfony\Component\HttpKernel\Event\GetResponseForControllerResultEvent; use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent; use Symfony\Component\HttpKernel\Event\FilterControllerEvent; use Symfony\Component\HttpKernel\Event\FilterResponseEvent; use Symfony\Component\HttpKernel\Event\GetResponseEvent; use Symfony\Component\HttpKernel\Event\PostResponseEvent; use Symfony\Component\HttpKernel\EventListener\ResponseListener; use Symfony\Component\HttpKernel\EventListener\RouterListener; use Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException; use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface; use Symfony\Component\HttpKernel\Exception\HttpException; use Symfony\Component\HttpKernel\KernelEvents; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpFoundation\RedirectResponse; use Symfony\Component\HttpFoundation\StreamedResponse; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\EventDispatcher\Event; use Symfony\Component\EventDispatcher\EventDispatcher; use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Symfony\Component\Routing\Route; use Symfony\Component\Routing\RouteCollection; use Symfony\Component\Routing\RequestContext; use Symfony\Component\Routing\Exception\ExceptionInterface as RoutingException; use Symfony\Component\Routing\Exception\MethodNotAllowedException; use Symfony\Component\Routing\Exception\ResourceNotFoundException; use Symfony\Component\ClassLoader\UniversalClassLoader; use Silex\RedirectableUrlMatcher; use Silex\ControllerResolver; class Application extends \Pimple implements HttpKernelInterface, EventSubscriberInterface, TerminableInterface { const VERSION = '6ad4c16 2012-05-02 00:11:20 +0200'; public function __construct() { $app = $this; $this['autoloader'] = $this->share(function () { $loader = new UniversalClassLoader(); $loader->register(); return $loader; }); $this['routes'] = $this->share(function () { return new RouteCollection(); }); $this['controllers'] = $this->share(function () use ($app) { return new ControllerCollection(); }); $this['exception_handler'] = $this->share(function () { return new ExceptionHandler(); }); $this['dispatcher'] = $this->share(function () use ($app) { $dispatcher = new EventDispatcher(); $dispatcher->addSubscriber($app); $urlMatcher = new LazyUrlMatcher(function () use ($app) { return $app['url_matcher']; }); $dispatcher->addSubscriber(new RouterListener($urlMatcher)); return $dispatcher; }); $this['resolver'] = $this->share(function () use ($app) { return new ControllerResolver($app); }); $this['kernel'] = $this->share(function () use ($app) { return new HttpKernel($app['dispatcher'], $app['resolver']); }); $this['request_context'] = $this->share(function () use ($app) { $context = new RequestContext(); $context->setHttpPort($app['request.http_port']); $context->setHttpsPort($app['request.https_port']); return $context; }); $this['url_matcher'] = $this->share(function () use ($app) { return new RedirectableUrlMatcher($app['routes'], $app['request_context']); }); $this['route_middlewares_trigger'] = $this->protect(function (KernelEvent $event) use ($app) { foreach ($event->getRequest()->attributes->get('_middlewares', array()) as $callback) { $ret = call_user_func($callback, $event->getRequest()); if ($ret instanceof Response) { $event->setResponse($ret); return; } elseif (null !== $ret) { throw new \RuntimeException('Middleware for route "'.$event->getRequest()->attributes->get('_route').'" returned an invalid response value. Must return null or an instance of Response.'); } } }); $this['request.default_locale'] = 'en'; $this['request'] = function () { throw new \RuntimeException('Accessed request service outside of request scope. Try moving that call to a before handler or controller.'); }; $this['request.http_port'] = 80; $this['request.https_port'] = 443; $this['debug'] = false; $this['charset'] = 'UTF-8'; } public function register(ServiceProviderInterface $provider, array $values = array()) { foreach ($values as $key => $value) { $this[$key] = $value; } $provider->register($this); } public function match($pattern, $to) { return $this['controllers']->match($pattern, $to); } public function get($pattern, $to) { return $this['controllers']->get($pattern, $to); } public function post($pattern, $to) { return $this['controllers']->post($pattern, $to); } public function put($pattern, $to) { return $this['controllers']->put($pattern, $to); } public function delete($pattern, $to) { return $this['controllers']->delete($pattern, $to); } public function before($callback, $priority = 0) { $this['dispatcher']->addListener(SilexEvents::BEFORE, function (GetResponseEvent $event) use ($callback) { $ret = call_user_func($callback, $event->getRequest()); if ($ret instanceof Response) { $event->setResponse($ret); } }, $priority); } public function after($callback, $priority = 0) { $this['dispatcher']->addListener(SilexEvents::AFTER, function (FilterResponseEvent $event) use ($callback) { call_user_func($callback, $event->getRequest(), $event->getResponse()); }, $priority); } public function finish($callback, $priority = 0) { $this['dispatcher']->addListener(SilexEvents::FINISH, function (PostResponseEvent $event) use ($callback) { call_user_func($callback, $event->getRequest(), $event->getResponse()); }, $priority); } public function abort($statusCode, $message = '', array $headers = array()) { throw new HttpException($statusCode, $message, null, $headers); } public function error($callback, $priority = 0) { $this['dispatcher']->addListener(SilexEvents::ERROR, function (GetResponseForErrorEvent $event) use ($callback) { $exception = $event->getException(); $code = $exception instanceof HttpExceptionInterface ? $exception->getStatusCode() : 500; $result = call_user_func($callback, $exception, $code); if (null !== $result) { $event->setStringResponse($result); } }, $priority); } public function flush($prefix = '') { $this['routes']->addCollection($this['controllers']->flush($prefix), $prefix); } public function redirect($url, $status = 302) { return new RedirectResponse($url, $status); } public function stream($callback = null, $status = 200, $headers = array()) { return new StreamedResponse($callback, $status, $headers); } public function escape($text, $flags = ENT_COMPAT, $charset = null, $doubleEncode = true) { return htmlspecialchars($text, $flags, $charset ?: $this['charset'], $doubleEncode); } public function json($data = array(), $status = 200, $headers = array()) { return new JsonResponse($data, $status, $headers); } public function mount($prefix, $app) { if ($app instanceof ControllerProviderInterface) { $app = $app->connect($this); } if (!$app instanceof ControllerCollection) { throw new \LogicException('The "mount" method takes either a ControllerCollection or a ControllerProviderInterface instance.'); } $this['routes']->addCollection($app->flush($prefix), $prefix); } public function run(Request $request = null) { if (null === $request) { $request = Request::createFromGlobals(); } $response = $this->handle($request); $response->send(); $this->terminate($request, $response); } public function handle(Request $request, $type = HttpKernelInterface::MASTER_REQUEST, $catch = true) { $this->beforeDispatched = false; $this['request'] = $request; $this['request']->setDefaultLocale($this['request.default_locale']); $this->flush(); return $this['kernel']->handle($request, $type, $catch); } public function terminate(Request $request, Response $response) { $this['kernel']->terminate($request, $response); } public function onEarlyKernelRequest(GetResponseEvent $event) { if (HttpKernelInterface::MASTER_REQUEST === $event->getRequestType()) { if (isset($this['exception_handler'])) { $this['dispatcher']->addSubscriber($this['exception_handler']); } $this['dispatcher']->addSubscriber(new ResponseListener($this['charset'])); } } public function onKernelRequest(GetResponseEvent $event) { if (HttpKernelInterface::MASTER_REQUEST === $event->getRequestType()) { $this->beforeDispatched = true; $this['dispatcher']->dispatch(SilexEvents::BEFORE, $event); $this['route_middlewares_trigger']($event); } } public function onKernelController(FilterControllerEvent $event) { $request = $event->getRequest(); $route = $this['routes']->get($request->attributes->get('_route')); if ($route && $converters = $route->getOption('_converters')) { foreach ($converters as $name => $callback) { $request->attributes->set($name, call_user_func($callback, $request->attributes->get($name, null), $request)); } } } public function onKernelView(GetResponseForControllerResultEvent $event) { $response = $event->getControllerResult(); $converter = new StringResponseConverter(); $event->setResponse($converter->convert($response)); } public function onKernelResponse(FilterResponseEvent $event) { if (HttpKernelInterface::MASTER_REQUEST === $event->getRequestType()) { $this['dispatcher']->dispatch(SilexEvents::AFTER, $event); } } public function onKernelTerminate(PostResponseEvent $event) { $this['dispatcher']->dispatch(SilexEvents::FINISH, $event); } public function onKernelException(GetResponseForExceptionEvent $event) { if (!$this->beforeDispatched) { $this->beforeDispatched = true; $this['dispatcher']->dispatch(SilexEvents::BEFORE, $event); } $errorEvent = new GetResponseForErrorEvent($this, $event->getRequest(), $event->getRequestType(), $event->getException()); $this['dispatcher']->dispatch(SilexEvents::ERROR, $errorEvent); if ($errorEvent->hasResponse()) { $event->setResponse($errorEvent->getResponse()); } } static public function getSubscribedEvents() { return array( KernelEvents::REQUEST => array( array('onEarlyKernelRequest', 256), array('onKernelRequest') ), KernelEvents::CONTROLLER => 'onKernelController', KernelEvents::RESPONSE => 'onKernelResponse', KernelEvents::EXCEPTION => 'onKernelException', KernelEvents::TERMINATE => 'onKernelTerminate', KernelEvents::VIEW => array('onKernelView', -10), ); } } <?php namespace Silex; use Silex\Exception\ControllerFrozenException; use Symfony\Component\Routing\Route; class Controller { private $route; private $routeName; private $isFrozen = false; public function __construct(Route $route) { $this->route = $route; } public function getRoute() { return $this->route; } public function getRouteName() { return $this->routeName; } public function bind($routeName) { if ($this->isFrozen) { throw new ControllerFrozenException(sprintf('Calling %s on frozen %s instance.', __METHOD__, __CLASS__)); } $this->routeName = $routeName; return $this; } public function assert($variable, $regexp) { $this->route->setRequirement($variable, $regexp); return $this; } public function value($variable, $default) { $this->route->setDefault($variable, $default); return $this; } public function convert($variable, $callback) { $converters = $this->route->getOption('_converters'); $converters[$variable] = $callback; $this->route->setOption('_converters', $converters); return $this; } public function method($method) { $this->route->setRequirement('_method', $method); return $this; } public function requireHttp() { $this->route->setRequirement('_scheme', 'http'); return $this; } public function requireHttps() { $this->route->setRequirement('_scheme', 'https'); return $this; } public function middleware($callback) { $middlewareCallbacks = $this->route->getDefault('_middlewares'); $middlewareCallbacks[] = $callback; $this->route->setDefault('_middlewares', $middlewareCallbacks); return $this; } public function freeze() { $this->isFrozen = true; } public function bindDefaultRouteName($prefix) { $requirements = $this->route->getRequirements(); $method = isset($requirements['_method']) ? $requirements['_method'] : ''; $routeName = $prefix.$method.$this->route->getPattern(); $routeName = str_replace(array('/', ':', '|', '-'), '_', $routeName); $routeName = preg_replace('/[^a-z0-9A-Z_.]+/', '', $routeName); $this->routeName = $routeName; } } <?php namespace Silex; use Symfony\Component\Routing\RouteCollection; use Symfony\Component\Routing\Route; use Silex\Controller; class ControllerCollection { protected $controllers = array(); public function match($pattern, $to) { $route = new Route($pattern, array('_controller' => $to)); $controller = new Controller($route); $this->add($controller); return $controller; } public function get($pattern, $to) { return $this->match($pattern, $to)->method('GET'); } public function post($pattern, $to) { return $this->match($pattern, $to)->method('POST'); } public function put($pattern, $to) { return $this->match($pattern, $to)->method('PUT'); } public function delete($pattern, $to) { return $this->match($pattern, $to)->method('DELETE'); } public function add(Controller $controller) { $this->controllers[] = $controller; } public function flush($prefix = '') { $routes = new RouteCollection(); foreach ($this->controllers as $controller) { if (!$controller->getRouteName()) { $controller->bindDefaultRouteName($prefix); } $routes->add($controller->getRouteName(), $controller->getRoute()); $controller->freeze(); } $this->controllers = array(); return $routes; } } <?php namespace Silex; interface ControllerProviderInterface { function connect(Application $app); } <?php namespace Silex; use Symfony\Component\HttpKernel\Controller\ControllerResolver as BaseControllerResolver; use Symfony\Component\HttpKernel\Log\LoggerInterface; use Symfony\Component\HttpFoundation\Request; class ControllerResolver extends BaseControllerResolver { protected $app; public function __construct(Application $app, LoggerInterface $logger = null) { $this->app = $app; parent::__construct($logger); } protected function doGetArguments(Request $request, $controller, array $parameters) { foreach ($parameters as $param) { if ($param->getClass() && $param->getClass()->isInstance($this->app)) { $request->attributes->set($param->getName(), $this->app); break; } } return parent::doGetArguments($request, $controller, $parameters); } } <?php namespace Silex\Exception; class ControllerFrozenException extends \RuntimeException { } <?php namespace Silex; use Silex\Application; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\Debug\ExceptionHandler as DebugExceptionHandler; use Symfony\Component\EventDispatcher\EventSubscriberInterface; class ExceptionHandler implements EventSubscriberInterface { public function onSilexError(GetResponseForErrorEvent $event) { $app = $event->getKernel(); $handler = new DebugExceptionHandler($app['debug']); $event->setResponse($handler->createResponse($event->getException())); } static public function getSubscribedEvents() { return array(SilexEvents::ERROR => array('onSilexError', -255)); } } <?php namespace Silex; use Symfony\Component\HttpKernel\HttpKernelInterface; use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent; use Symfony\Component\HttpFoundation\Request; class GetResponseForErrorEvent extends GetResponseForExceptionEvent { public function setStringResponse($response) { $converter = new StringResponseConverter(); $this->setResponse($converter->convert($response)); } } <?php namespace Silex; use Symfony\Component\HttpKernel\HttpCache\HttpCache as BaseHttpCache; use Symfony\Component\HttpFoundation\Request; class HttpCache extends BaseHttpCache { public function run(Request $request = null) { if (null === $request) { $request = Request::createFromGlobals(); } $this->handle($request)->send(); } } <?php namespace Silex; use Symfony\Component\Routing\RequestContext; use Symfony\Component\Routing\Matcher\UrlMatcherInterface; class LazyUrlMatcher implements UrlMatcherInterface { private $factory; private $urlMatcher; public function __construct(\Closure $factory) { $this->factory = $factory; } public function getUrlMatcher() { $urlMatcher = call_user_func($this->factory); if (!$urlMatcher instanceof UrlMatcherInterface) { throw new \LogicException("Factory supplied to LazyUrlMatcher must return implementation of UrlMatcherInterface."); } return $urlMatcher; } public function match($pathinfo) { return $this->getUrlMatcher()->match($pathinfo); } public function setContext(RequestContext $context) { $this->getUrlMatcher()->setContext($context); } public function getContext() { return $this->getUrlMatcher()->getContext(); } } <?php namespace Silex\Provider; use Silex\Application; use Silex\ServiceProviderInterface; use Doctrine\DBAL\DriverManager; use Doctrine\DBAL\Configuration; use Doctrine\Common\EventManager; class DoctrineServiceProvider implements ServiceProviderInterface { public function register(Application $app) { $app['db.default_options'] = array( 'driver' => 'pdo_mysql', 'dbname' => null, 'host' => 'localhost', 'user' => 'root', 'password' => null, ); $app['dbs.options.initializer'] = $app->protect(function () use ($app) { static $initialized = false; if ($initialized) { return; } $initialized = true; if (!isset($app['dbs.options'])) { $app['dbs.options'] = array('default' => isset($app['db.options']) ? $app['db.options'] : array()); } $tmp = $app['dbs.options']; foreach ($tmp as $name => &$options) { $options = array_replace($app['db.default_options'], $options); if (!isset($app['dbs.default'])) { $app['dbs.default'] = $name; } } $app['dbs.options'] = $tmp; }); $app['dbs'] = $app->share(function () use ($app) { $app['dbs.options.initializer'](); $dbs = new \Pimple(); foreach ($app['dbs.options'] as $name => $options) { if ($app['dbs.default'] === $name) { $config = $app['db.config']; $manager = $app['db.event_manager']; } else { $config = $app['dbs.config'][$name]; $manager = $app['dbs.event_manager'][$name]; } $dbs[$name] = DriverManager::getConnection($options, $config, $manager); } return $dbs; }); $app['dbs.config'] = $app->share(function () use ($app) { $app['dbs.options.initializer'](); $configs = new \Pimple(); foreach ($app['dbs.options'] as $name => $options) { $configs[$name] = new Configuration(); } return $configs; }); $app['dbs.event_manager'] = $app->share(function () use ($app) { $app['dbs.options.initializer'](); $managers = new \Pimple(); foreach ($app['dbs.options'] as $name => $options) { $managers[$name] = new EventManager(); } return $managers; }); $app['db'] = $app->share(function() use ($app) { $dbs = $app['dbs']; return $dbs[$app['dbs.default']]; }); $app['db.config'] = $app->share(function() use ($app) { $dbs = $app['dbs.config']; return $dbs[$app['dbs.default']]; }); $app['db.event_manager'] = $app->share(function() use ($app) { $dbs = $app['dbs.event_manager']; return $dbs[$app['dbs.default']]; }); if (isset($app['db.dbal.class_path'])) { $app['autoloader']->registerNamespace('Doctrine\\DBAL', $app['db.dbal.class_path']); } if (isset($app['db.common.class_path'])) { $app['autoloader']->registerNamespace('Doctrine\\Common', $app['db.common.class_path']); } } } <?php namespace Silex\Provider; use Silex\Application; use Silex\ServiceProviderInterface; use Symfony\Component\Form\Extension\Csrf\CsrfProvider\DefaultCsrfProvider; use Symfony\Component\Form\Extension\Csrf\CsrfProvider\SessionCsrfProvider; use Symfony\Component\Form\FormFactory; use Symfony\Component\Form\Extension\Core\CoreExtension; use Symfony\Component\Form\Extension\Validator\ValidatorExtension as FormValidatorExtension; use Symfony\Component\Form\Extension\Csrf\CsrfExtension; class FormServiceProvider implements ServiceProviderInterface { public function register(Application $app) { $app['form.secret'] = md5(__DIR__); $app['form.factory'] = $app->share(function () use ($app) { $extensions = array( new CoreExtension(), new CsrfExtension($app['form.csrf_provider']), ); if (isset($app['validator'])) { $extensions[] = new FormValidatorExtension($app['validator']); } return new FormFactory($extensions); }); $app['form.csrf_provider'] = $app->share(function () use ($app) { if (isset($app['session'])) { return new SessionCsrfProvider($app['session'], $app['form.secret']); } return new DefaultCsrfProvider($app['form.secret']); }); if (isset($app['form.class_path'])) { $app['autoloader']->registerNamespace('Symfony\\Component\\Form', $app['form.class_path']); } } } <?php namespace Silex\Provider; use Silex\Application; use Silex\ServiceProviderInterface; use Silex\HttpCache; use Symfony\Component\HttpKernel\HttpCache\Esi; use Symfony\Component\HttpKernel\HttpCache\Store; class HttpCacheServiceProvider implements ServiceProviderInterface { public function register(Application $app) { $app['http_cache'] = $app->share(function () use ($app) { return new HttpCache($app, $app['http_cache.store'], $app['http_cache.esi'], $app['http_cache.options']); }); $app['http_cache.esi'] = $app->share(function () use ($app) { return new Esi(); }); $app['http_cache.store'] = $app->share(function () use ($app) { return new Store($app['http_cache.cache_dir']); }); if (!isset($app['http_cache.options'])) { $app['http_cache.options'] = array(); } } } <?php namespace Silex\Provider; use Monolog\Logger; use Monolog\Handler\StreamHandler; use Silex\Application; use Silex\ServiceProviderInterface; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\Exception\HttpException; class MonologServiceProvider implements ServiceProviderInterface { public function register(Application $app) { $app['monolog'] = $app->share(function () use ($app) { $log = new Logger(isset($app['monolog.name']) ? $app['monolog.name'] : 'myapp'); $app['monolog.configure']($log); return $log; }); $app['monolog.configure'] = $app->protect(function ($log) use ($app) { $log->pushHandler($app['monolog.handler']); }); $app['monolog.handler'] = function () use ($app) { return new StreamHandler($app['monolog.logfile'], $app['monolog.level']); }; if (!isset($app['monolog.level'])) { $app['monolog.level'] = function () { return Logger::DEBUG; }; } if (isset($app['monolog.class_path'])) { $app['autoloader']->registerNamespace('Monolog', $app['monolog.class_path']); } $app->before(function (Request $request) use ($app) { $app['monolog']->addInfo('> '.$request->getMethod().' '.$request->getRequestUri()); }); $app->error(function (\Exception $e) use ($app) { $app['monolog']->addError($e->getMessage()); }); $app->after(function (Request $request, Response $response) use ($app) { $app['monolog']->addInfo('< '.$response->getStatusCode()); }); } } <?php namespace Silex\Provider; use Silex\Application; use Silex\ServiceProviderInterface; use Symfony\Component\HttpFoundation\Session\Storage\Handler\NativeFileSessionHandler; use Symfony\Component\HttpFoundation\Session\Storage\NativeSessionStorage; use Symfony\Component\HttpFoundation\Session\Session; use Symfony\Component\HttpKernel\KernelEvents; class SessionServiceProvider implements ServiceProviderInterface { private $app; public function register(Application $app) { $this->app = $app; $app['session'] = $app->share(function () use ($app) { return new Session($app['session.storage']); }); $app['session.storage.handler'] = $app->share(function () use ($app) { return new NativeFileSessionHandler( isset($app['session.storage.save_path']) ? $app['session.storage.save_path'] : null ); }); $app['session.storage'] = $app->share(function () use ($app) { return new NativeSessionStorage( $app['session.storage.options'], $app['session.storage.handler'] ); }); $app['dispatcher']->addListener(KernelEvents::REQUEST, array($this, 'onKernelRequest'), 128); if (!isset($app['session.storage.options'])) { $app['session.storage.options'] = array(); } if (!isset($app['session.default_locale'])) { $app['session.default_locale'] = 'en'; } } public function onKernelRequest($event) { $request = $event->getRequest(); $request->setSession($this->app['session']); if ($request->hasPreviousSession()) { $request->getSession()->start(); } } } <?php namespace Silex\Provider; use Silex\Application; use Silex\ServiceProviderInterface; class SwiftmailerServiceProvider implements ServiceProviderInterface { public function register(Application $app) { $app['swiftmailer.options'] = array_replace(array( 'host' => 'localhost', 'port' => 25, 'username' => '', 'password' => '', 'encryption' => null, 'auth_mode' => null, ), isset($app['swiftmailer.options']) ? $app['swiftmailer.options'] : array()); $app['mailer'] = $app->share(function () use ($app) { $r = new \ReflectionClass('Swift_Mailer'); require_once dirname($r->getFilename()).'/../../swift_init.php'; return new \Swift_Mailer($app['swiftmailer.spooltransport']); }); $app['swiftmailer.spooltransport'] = $app->share(function () use ($app) { return new \Swift_SpoolTransport(new \Swift_MemorySpool()); }); $app['swiftmailer.transport'] = $app->share(function () use ($app) { $transport = new \Swift_Transport_EsmtpTransport( $app['swiftmailer.transport.buffer'], array($app['swiftmailer.transport.authhandler']), $app['swiftmailer.transport.eventdispatcher'] ); $transport->setHost($app['swiftmailer.options']['host']); $transport->setPort($app['swiftmailer.options']['port']); $transport->setEncryption($app['swiftmailer.options']['encryption']); $transport->setUsername($app['swiftmailer.options']['username']); $transport->setPassword($app['swiftmailer.options']['password']); $transport->setAuthMode($app['swiftmailer.options']['auth_mode']); return $transport; }); $app['swiftmailer.transport.buffer'] = $app->share(function () { return new \Swift_Transport_StreamBuffer(new \Swift_StreamFilters_StringReplacementFilterFactory()); }); $app['swiftmailer.transport.authhandler'] = $app->share(function () { return new \Swift_Transport_Esmtp_AuthHandler(array( new \Swift_Transport_Esmtp_Auth_CramMd5Authenticator(), new \Swift_Transport_Esmtp_Auth_LoginAuthenticator(), new \Swift_Transport_Esmtp_Auth_PlainAuthenticator(), )); }); $app['swiftmailer.transport.eventdispatcher'] = $app->share(function () { return new \Swift_Events_SimpleEventDispatcher(); }); $app->finish(function () use ($app) { $app['swiftmailer.spooltransport']->getSpool()->flushQueue($app['swiftmailer.transport']); }); if (isset($app['swiftmailer.class_path'])) { require_once $app['swiftmailer.class_path'].'/Swift.php'; \Swift::registerAutoload($app['swiftmailer.class_path'].'/../swift_init.php'); } } } <?php namespace Silex\Provider; use Silex\Application; use Silex\ServiceProviderInterface; class SymfonyBridgesServiceProvider implements ServiceProviderInterface { public function register(Application $app) { $app['symfony_bridges'] = true; if (isset($app['symfony_bridges.class_path'])) { $app['autoloader']->registerNamespace('Symfony\\Bridge', $app['symfony_bridges.class_path']); } } } <?php namespace Silex\Provider; use Silex\Application; use Silex\ServiceProviderInterface; use Symfony\Component\Translation\Translator; use Symfony\Component\Translation\MessageSelector; use Symfony\Component\Translation\Loader\ArrayLoader; class TranslationServiceProvider implements ServiceProviderInterface { public function register(Application $app) { $app['translator'] = $app->share(function () use ($app) { $translator = new Translator(isset($app['locale']) ? $app['locale'] : 'en', $app['translator.message_selector']); if (isset($app['locale_fallback'])) { $translator->setFallbackLocale($app['locale_fallback']); } $translator->addLoader('array', $app['translator.loader']); foreach ($app['translator.messages'] as $locale => $messages) { $translator->addResource('array', $messages, $locale); } return $translator; }); $app['translator.loader'] = $app->share(function () { return new ArrayLoader(); }); $app['translator.message_selector'] = $app->share(function () { return new MessageSelector(); }); if (isset($app['translation.class_path'])) { $app['autoloader']->registerNamespace('Symfony\\Component\\Translation', $app['translation.class_path']); } } } <?php namespace Silex\Provider; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpKernel\HttpKernelInterface; class TwigCoreExtension extends \Twig_Extension { public function getFunctions() { return array( 'render' => new \Twig_Function_Method($this, 'render', array('needs_environment' => true, 'is_safe' => array('html'))), ); } public function render(\Twig_Environment $twig, $uri) { $globals = $twig->getGlobals(); $request = $globals['app']['request']; $subRequest = Request::create($uri, 'get', array(), $request->cookies->all(), array(), $request->server->all()); if ($request->getSession()) { $subRequest->setSession($request->getSession()); } $response = $globals['app']->handle($subRequest, HttpKernelInterface::SUB_REQUEST, false); if (!$response->isSuccessful()) { throw new \RuntimeException(sprintf('Error when rendering "%s" (Status code is %s).', $request->getUri(), $response->getStatusCode())); } return $response->getContent(); } public function getName() { return 'silex'; } } <?php namespace Silex\Provider; use Silex\Application; use Silex\ServiceProviderInterface; use Symfony\Bridge\Twig\Extension\RoutingExtension as TwigRoutingExtension; use Symfony\Bridge\Twig\Extension\TranslationExtension as TwigTranslationExtension; use Symfony\Bridge\Twig\Extension\FormExtension as TwigFormExtension; class TwigServiceProvider implements ServiceProviderInterface { public function register(Application $app) { $app['twig'] = $app->share(function () use ($app) { $app['twig.options'] = array_replace( array( 'charset' => $app['charset'], 'debug' => $app['debug'], 'strict_variables' => $app['debug'], ), isset($app['twig.options']) ? $app['twig.options'] : array() ); $twig = new \Twig_Environment($app['twig.loader'], $app['twig.options']); $twig->addGlobal('app', $app); $twig->addExtension(new TwigCoreExtension()); if (isset($app['symfony_bridges'])) { if (isset($app['url_generator'])) { $twig->addExtension(new TwigRoutingExtension($app['url_generator'])); } if (isset($app['translator'])) { $twig->addExtension(new TwigTranslationExtension($app['translator'])); } if (isset($app['form.factory'])) { if (!isset($app['twig.form.templates'])) { $app['twig.form.templates'] = array('form_div_layout.html.twig'); } $twig->addExtension(new TwigFormExtension($app['form.csrf_provider'], $app['twig.form.templates'])); $reflected = new \ReflectionClass('Symfony\Bridge\Twig\Extension\FormExtension'); $path = dirname($reflected->getFileName()).'/../Resources/views/Form'; $app['twig.loader']->addLoader(new \Twig_Loader_Filesystem($path)); } } if (isset($app['twig.configure'])) { $app['twig.configure']($twig); } return $twig; }); $app['twig.loader.filesystem'] = $app->share(function () use ($app) { return new \Twig_Loader_Filesystem(isset($app['twig.path']) ? $app['twig.path'] : array()); }); $app['twig.loader.array'] = $app->share(function () use ($app) { return new \Twig_Loader_Array(isset($app['twig.templates']) ? $app['twig.templates'] : array()); }); $app['twig.loader'] = $app->share(function () use ($app) { return new \Twig_Loader_Chain(array( $app['twig.loader.filesystem'], $app['twig.loader.array'], )); }); if (isset($app['twig.class_path'])) { $app['autoloader']->registerPrefix('Twig_', $app['twig.class_path']); } } } <?php namespace Silex\Provider; use Silex\Application; use Silex\ServiceProviderInterface; use Symfony\Component\Routing\Generator\UrlGenerator; class UrlGeneratorServiceProvider implements ServiceProviderInterface { public function register(Application $app) { $app['url_generator'] = $app->share(function () use ($app) { $app->flush(); return new UrlGenerator($app['routes'], $app['request_context']); }); } } <?php namespace Silex\Provider; use Silex\Application; use Silex\ServiceProviderInterface; use Symfony\Component\Validator\Validator; use Symfony\Component\Validator\Mapping\ClassMetadataFactory; use Symfony\Component\Validator\Mapping\Loader\StaticMethodLoader; use Symfony\Component\Validator\ConstraintValidatorFactory; class ValidatorServiceProvider implements ServiceProviderInterface { public function register(Application $app) { $app['validator'] = $app->share(function () use ($app) { return new Validator( $app['validator.mapping.class_metadata_factory'], $app['validator.validator_factory'] ); }); $app['validator.mapping.class_metadata_factory'] = $app->share(function () use ($app) { return new ClassMetadataFactory(new StaticMethodLoader()); }); $app['validator.validator_factory'] = $app->share(function () { return new ConstraintValidatorFactory(); }); if (isset($app['validator.class_path'])) { $app['autoloader']->registerNamespace('Symfony\\Component\\Validator', $app['validator.class_path']); } } } <?php namespace Silex; use Symfony\Component\HttpFoundation\RedirectResponse; use Symfony\Component\Routing\Matcher\RedirectableUrlMatcher as BaseRedirectableUrlMatcher; use Symfony\Component\Routing\Matcher\RedirectableUrlMatcherInterface; class RedirectableUrlMatcher extends BaseRedirectableUrlMatcher { public function redirect($path, $route, $scheme = null) { $url = $this->context->getBaseUrl().$path; if ($this->context->getHost()) { if ($scheme) { $port = ''; if ('http' === $scheme && 80 != $this->context->getHttpPort()) { $port = ':'.$this->context->getHttpPort(); } elseif ('https' === $scheme && 443 != $this->context->getHttpsPort()) { $port = ':'.$this->context->getHttpsPort(); } $url = $scheme.'://'.$this->context->getHost().$port.$url; } } return array( '_controller' => function ($url) { return new RedirectResponse($url, 301); }, 'url' => $url, ); } } <?php namespace Silex; interface ServiceProviderInterface { function register(Application $app); } <?php namespace Silex; final class SilexEvents { const BEFORE = 'silex.before'; const AFTER = 'silex.after'; const FINISH = 'silex.finish'; const ERROR = 'silex.error'; } <?php namespace Silex; use Symfony\Component\HttpFoundation\Response; class StringResponseConverter { public function convert($response) { if (!$response instanceof Response) { return new Response((string) $response); } return $response; } } <?php namespace Silex; use Symfony\Component\HttpKernel\Client; use Symfony\Component\HttpKernel\Test\WebTestCase as BaseWebTestCase; abstract class WebTestCase extends \PHPUnit_Framework_TestCase { protected $app; public function setUp() { $this->app = $this->createApplication(); } abstract public function createApplication(); public function createClient(array $options = array(), array $server = array()) { return new Client($this->app); } } <?php class Pimple implements ArrayAccess { private $values; function __construct (array $values = array()) { $this->values = $values; } function offsetSet($id, $value) { $this->values[$id] = $value; } function offsetGet($id) { if (!array_key_exists($id, $this->values)) { throw new InvalidArgumentException(sprintf('Identifier "%s" is not defined.', $id)); } return $this->values[$id] instanceof Closure ? $this->values[$id]($this) : $this->values[$id]; } function offsetExists($id) { return isset($this->values[$id]); } function offsetUnset($id) { unset($this->values[$id]); } function share(Closure $callable) { return function ($c) use ($callable) { static $object; if (is_null($object)) { $object = $callable($c); } return $object; }; } function protect(Closure $callable) { return function ($c) use ($callable) { return $callable; }; } function raw($id) { if (!array_key_exists($id, $this->values)) { throw new InvalidArgumentException(sprintf('Identifier "%s" is not defined.', $id)); } return $this->values[$id]; } function extend($id, Closure $callable) { if (!array_key_exists($id, $this->values)) { throw new InvalidArgumentException(sprintf('Identifier "%s" is not defined.', $id)); } $factory = $this->values[$id]; if (!($factory instanceof Closure)) { throw new InvalidArgumentException(sprintf('Identifier "%s" does not contain an object definition.', $id)); } return $this->values[$id] = function ($c) use ($callable, $factory) { return $callable($factory($c), $c); }; } } <?php namespace Symfony\Component\ClassLoader; class ApcClassLoader { private $prefix; private $classFinder; public function __construct($prefix, $classFinder) { if (!extension_loaded('apc')) { throw new \RuntimeException('Unable to use ApcUniversalClassLoader as APC is not enabled.'); } if (!method_exists($classFinder, 'findFile')) { throw new \InvalidArgumentException('The class finder must implement a "findFile" method.'); } $this->prefix = $prefix; $this->classFinder = $classFinder; } public function register($prepend = false) { spl_autoload_register(array($this, 'loadClass'), true, $prepend); } public function unregister() { spl_autoload_unregister(array($this, 'loadClass')); } public function loadClass($class) { if ($file = $this->findFile($class)) { require $file; return true; } } public function findFile($class) { if (false === $file = apc_fetch($this->prefix.$class)) { apc_store($this->prefix.$class, $file = $this->classFinder->findFile($class)); } return $file; } } <?php namespace Symfony\Component\ClassLoader; class ApcUniversalClassLoader extends UniversalClassLoader { private $prefix; public function __construct($prefix) { if (!extension_loaded('apc')) { throw new \RuntimeException('Unable to use ApcUniversalClassLoader as APC is not enabled.'); } $this->prefix = $prefix; } public function findFile($class) { if (false === $file = apc_fetch($this->prefix.$class)) { apc_store($this->prefix.$class, $file = parent::findFile($class)); } return $file; } } <?php namespace Symfony\Component\ClassLoader; class ClassCollectionLoader { static private $loaded; static public function load($classes, $cacheDir, $name, $autoReload, $adaptive = false, $extension = '.php') { if (isset(self::$loaded[$name])) { return; } self::$loaded[$name] = true; if ($adaptive) { $classes = array_diff($classes, get_declared_classes(), get_declared_interfaces()); $name = $name.'-'.substr(md5(implode('|', $classes)), 0, 5); } $cache = $cacheDir.'/'.$name.$extension; $reload = false; if ($autoReload) { $metadata = $cacheDir.'/'.$name.$extension.'.meta'; if (!is_file($metadata) || !is_file($cache)) { $reload = true; } else { $time = filemtime($cache); $meta = unserialize(file_get_contents($metadata)); if ($meta[1] != $classes) { $reload = true; } else { foreach ($meta[0] as $resource) { if (!is_file($resource) || filemtime($resource) > $time) { $reload = true; break; } } } } } if (!$reload && is_file($cache)) { require_once $cache; return; } $files = array(); $content = ''; foreach ($classes as $class) { if (!class_exists($class) && !interface_exists($class) && (!function_exists('trait_exists') || !trait_exists($class))) { throw new \InvalidArgumentException(sprintf('Unable to load class "%s"', $class)); } $r = new \ReflectionClass($class); $files[] = $r->getFileName(); $c = preg_replace(array('/^\s*<\?php/', '/\?>\s*$/'), '', file_get_contents($r->getFileName())); if (!$r->inNamespace()) { $c = "\nnamespace\n{\n".self::stripComments($c)."\n}\n"; } else { $c = self::fixNamespaceDeclarations('<?php '.$c); $c = preg_replace('/^\s*<\?php/', '', $c); } $content .= $c; } if (!is_dir(dirname($cache))) { mkdir(dirname($cache), 0777, true); } self::writeCacheFile($cache, '<?php '.$content); if ($autoReload) { self::writeCacheFile($metadata, serialize(array($files, $classes))); } } static public function fixNamespaceDeclarations($source) { if (!function_exists('token_get_all')) { return $source; } $output = ''; $inNamespace = false; $tokens = token_get_all($source); for ($i = 0, $max = count($tokens); $i < $max; $i++) { $token = $tokens[$i]; if (is_string($token)) { $output .= $token; } elseif (in_array($token[0], array(T_COMMENT, T_DOC_COMMENT))) { continue; } elseif (T_NAMESPACE === $token[0]) { if ($inNamespace) { $output .= "}\n"; } $output .= $token[1]; while (($t = $tokens[++$i]) && is_array($t) && in_array($t[0], array(T_WHITESPACE, T_NS_SEPARATOR, T_STRING))) { $output .= $t[1]; } if (is_string($t) && '{' === $t) { $inNamespace = false; --$i; } else { $output .= "\n{"; $inNamespace = true; } } else { $output .= $token[1]; } } if ($inNamespace) { $output .= "}\n"; } return $output; } static private function writeCacheFile($file, $content) { $tmpFile = tempnam(dirname($file), basename($file)); if (false !== @file_put_contents($tmpFile, $content) && @rename($tmpFile, $file)) { chmod($file, 0666 & ~umask()); return; } throw new \RuntimeException(sprintf('Failed to write cache file "%s".', $file)); } static private function stripComments($source) { if (!function_exists('token_get_all')) { return $source; } $output = ''; foreach (token_get_all($source) as $token) { if (is_string($token)) { $output .= $token; } elseif (!in_array($token[0], array(T_COMMENT, T_DOC_COMMENT))) { $output .= $token[1]; } } $output = preg_replace(array('/\s+$/Sm', '/\n+/S'), "\n", $output); return $output; } } <?php namespace Symfony\Component\ClassLoader; class ClassLoader { private $prefixes = array(); private $fallbackDirs = array(); private $useIncludePath = false; public function getPrefixes() { return $this->prefixes; } public function getFallbackDirs() { return $this->fallbackDirs; } public function addPrefixes(array $prefixes) { foreach ($prefixes as $prefix => $path) { $this->addPrefix($prefix, $path); } } public function addPrefix($prefix, $paths) { if (!$prefix) { foreach ((array) $paths as $path) { $this->fallbackDirs[] = $path; } return; } if (isset($this->prefixes[$prefix])) { $this->prefixes[$prefix] = array_merge( $this->prefixes[$prefix], (array) $paths ); } else { $this->prefixes[$prefix] = (array) $paths; } } public function setUseIncludePath($useIncludePath) { $this->useIncludePath = $useIncludePath; } public function getUseIncludePath() { return $this->useIncludePath; } public function register($prepend = false) { spl_autoload_register(array($this, 'loadClass'), true, $prepend); } public function unregister() { spl_autoload_unregister(array($this, 'loadClass')); } public function loadClass($class) { if ($file = $this->findFile($class)) { require $file; return true; } } public function findFile($class) { if ('\\' == $class[0]) { $class = substr($class, 1); } if (false !== $pos = strrpos($class, '\\')) { $classPath = str_replace('\\', DIRECTORY_SEPARATOR, substr($class, 0, $pos)) . DIRECTORY_SEPARATOR; $className = substr($class, $pos + 1); } else { $classPath = null; $className = $class; } $classPath .= str_replace('_', DIRECTORY_SEPARATOR, $className) . '.php'; foreach ($this->prefixes as $prefix => $dirs) { if (0 === strpos($class, $prefix)) { foreach ($dirs as $dir) { if (file_exists($dir . DIRECTORY_SEPARATOR . $classPath)) { return $dir . DIRECTORY_SEPARATOR . $classPath; } } } } foreach ($this->fallbackDirs as $dir) { if (file_exists($dir . DIRECTORY_SEPARATOR . $classPath)) { return $dir . DIRECTORY_SEPARATOR . $classPath; } } if ($this->useIncludePath && $file = stream_resolve_include_path($classPath)) { return $file; } } } <?php namespace Symfony\Component\ClassLoader; class ClassMapGenerator { static public function dump($dirs, $file) { $dirs = (array) $dirs; $maps = array(); foreach ($dirs as $dir) { $maps = array_merge($maps, static::createMap($dir)); } file_put_contents($file, sprintf('<?php return %s;', var_export($maps, true))); } static public function createMap($dir) { if (is_string($dir)) { $dir = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($dir)); } $map = array(); foreach ($dir as $file) { if (!$file->isFile()) { continue; } $path = $file->getRealPath(); if (pathinfo($path, PATHINFO_EXTENSION) !== 'php') { continue; } $classes = self::findClasses($path); foreach ($classes as $class) { $map[$class] = $path; } } return $map; } static private function findClasses($path) { $contents = file_get_contents($path); $tokens = token_get_all($contents); $T_TRAIT = version_compare(PHP_VERSION, '5.4', '<') ? -1 : T_TRAIT; $classes = array(); $namespace = ''; for ($i = 0, $max = count($tokens); $i < $max; $i++) { $token = $tokens[$i]; if (is_string($token)) { continue; } $class = ''; switch ($token[0]) { case T_NAMESPACE: $namespace = ''; while (($t = $tokens[++$i]) && is_array($t)) { if (in_array($t[0], array(T_STRING, T_NS_SEPARATOR))) { $namespace .= $t[1]; } } $namespace .= '\\'; break; case T_CLASS: case T_INTERFACE: case $T_TRAIT: while (($t = $tokens[++$i]) && is_array($t)) { if (T_STRING === $t[0]) { $class .= $t[1]; } elseif ($class !== '' && T_WHITESPACE == $t[0]) { break; } } $classes[] = ltrim($namespace . $class, '\\'); break; default: break; } } return $classes; } } <?php namespace Symfony\Component\ClassLoader; class DebugClassLoader { private $classFinder; public function __construct($classFinder) { $this->classFinder = $classFinder; } static public function enable() { if (!is_array($functions = spl_autoload_functions())) { return; } foreach ($functions as $function) { spl_autoload_unregister($function); } foreach ($functions as $function) { if (is_array($function) && method_exists($function[0], 'findFile')) { $function = array(new static($function[0]), 'loadClass'); } spl_autoload_register($function); } } public function unregister() { spl_autoload_unregister(array($this, 'loadClass')); } public function loadClass($class) { if ($file = $this->classFinder->findFile($class)) { require $file; if (!class_exists($class, false) && !interface_exists($class, false) && (!function_exists('trait_exists') || !trait_exists($class, false))) { throw new \RuntimeException(sprintf('The autoloader expected class "%s" to be defined in file "%s". The file was found but the class was not in it, the class name or namespace probably has a typo.', $class, $file)); } return true; } } } <?php namespace Symfony\Component\ClassLoader; class DebugUniversalClassLoader extends UniversalClassLoader { static public function enable() { if (!is_array($functions = spl_autoload_functions())) { return; } foreach ($functions as $function) { spl_autoload_unregister($function); } foreach ($functions as $function) { if (is_array($function) && $function[0] instanceof UniversalClassLoader) { $loader = new static(); $loader->registerNamespaceFallbacks($function[0]->getNamespaceFallbacks()); $loader->registerPrefixFallbacks($function[0]->getPrefixFallbacks()); $loader->registerNamespaces($function[0]->getNamespaces()); $loader->registerPrefixes($function[0]->getPrefixes()); $loader->useIncludePath($function[0]->getUseIncludePath()); $function[0] = $loader; } spl_autoload_register($function); } } public function loadClass($class) { if ($file = $this->findFile($class)) { require $file; if (!class_exists($class, false) && !interface_exists($class, false) && (!function_exists('trait_exists') || !trait_exists($class, false))) { throw new \RuntimeException(sprintf('The autoloader expected class "%s" to be defined in file "%s". The file was found but the class was not in it, the class name or namespace probably has a typo.', $class, $file)); } } } } <?php namespace Symfony\Component\ClassLoader; class MapClassLoader { private $map = array(); public function __construct(array $map) { $this->map = $map; } public function register($prepend = false) { spl_autoload_register(array($this, 'loadClass'), true, $prepend); } public function loadClass($class) { if ('\\' === $class[0]) { $class = substr($class, 1); } if (isset($this->map[$class])) { require $this->map[$class]; } } public function findFile($class) { if ('\\' === $class[0]) { $class = substr($class, 1); } if (isset($this->map[$class])) { return $this->map[$class]; } } } <?php namespace Symfony\Component\ClassLoader; class UniversalClassLoader { private $namespaces = array(); private $prefixes = array(); private $namespaceFallbacks = array(); private $prefixFallbacks = array(); private $useIncludePath = false; public function useIncludePath($useIncludePath) { $this->useIncludePath = $useIncludePath; } public function getUseIncludePath() { return $this->useIncludePath; } public function getNamespaces() { return $this->namespaces; } public function getPrefixes() { return $this->prefixes; } public function getNamespaceFallbacks() { return $this->namespaceFallbacks; } public function getPrefixFallbacks() { return $this->prefixFallbacks; } public function registerNamespaceFallbacks(array $dirs) { $this->namespaceFallbacks = $dirs; } public function registerNamespaceFallback($dir) { $this->namespaceFallbacks[] = $dir; } public function registerPrefixFallbacks(array $dirs) { $this->prefixFallbacks = $dirs; } public function registerPrefixFallback($dir) { $this->prefixFallbacks[] = $dir; } public function registerNamespaces(array $namespaces) { foreach ($namespaces as $namespace => $locations) { $this->namespaces[$namespace] = (array) $locations; } } public function registerNamespace($namespace, $paths) { $this->namespaces[$namespace] = (array) $paths; } public function registerPrefixes(array $classes) { foreach ($classes as $prefix => $locations) { $this->prefixes[$prefix] = (array) $locations; } } public function registerPrefix($prefix, $paths) { $this->prefixes[$prefix] = (array) $paths; } public function register($prepend = false) { spl_autoload_register(array($this, 'loadClass'), true, $prepend); } public function loadClass($class) { if ($file = $this->findFile($class)) { require $file; } } public function findFile($class) { if ('\\' == $class[0]) { $class = substr($class, 1); } if (false !== $pos = strrpos($class, '\\')) { $namespace = substr($class, 0, $pos); $className = substr($class, $pos + 1); $normalizedClass = str_replace('\\', DIRECTORY_SEPARATOR, $namespace).DIRECTORY_SEPARATOR.str_replace('_', DIRECTORY_SEPARATOR, $className).'.php'; foreach ($this->namespaces as $ns => $dirs) { if (0 !== strpos($namespace, $ns)) { continue; } foreach ($dirs as $dir) { $file = $dir.DIRECTORY_SEPARATOR.$normalizedClass; if (is_file($file)) { return $file; } } } foreach ($this->namespaceFallbacks as $dir) { $file = $dir.DIRECTORY_SEPARATOR.$normalizedClass; if (is_file($file)) { return $file; } } } else { $normalizedClass = str_replace('_', DIRECTORY_SEPARATOR, $class).'.php'; foreach ($this->prefixes as $prefix => $dirs) { if (0 !== strpos($class, $prefix)) { continue; } foreach ($dirs as $dir) { $file = $dir.DIRECTORY_SEPARATOR.$normalizedClass; if (is_file($file)) { return $file; } } } foreach ($this->prefixFallbacks as $dir) { $file = $dir.DIRECTORY_SEPARATOR.$normalizedClass; if (is_file($file)) { return $file; } } } if ($this->useIncludePath && $file = stream_resolve_include_path($normalizedClass)) { return $file; } } } <?php namespace Symfony\Component\ClassLoader; class XcacheClassLoader { private $prefix; private $classFinder; public function __construct($prefix, $classFinder) { if (!extension_loaded('Xcache')) { throw new \RuntimeException('Unable to use XcacheClassLoader as Xcache is not enabled.'); } if (!method_exists($classFinder, 'findFile')) { throw new \InvalidArgumentException('The class finder must implement a "findFile" method.'); } $this->prefix = $prefix; $this->classFinder = $classFinder; } public function register($prepend = false) { spl_autoload_register(array($this, 'loadClass'), true, $prepend); } public function unregister() { spl_autoload_unregister(array($this, 'loadClass')); } public function loadClass($class) { if ($file = $this->findFile($class)) { require $file; return true; } } public function findFile($class) { if (xcache_isset($this->prefix.$class)) { $file = xcache_get($this->prefix.$class); } else { xcache_set($this->prefix.$class, $file = $this->classFinder->findFile($class)); } return $file; } } <?php namespace Symfony\Component\EventDispatcher; use Symfony\Component\DependencyInjection\ContainerInterface; class ContainerAwareEventDispatcher extends EventDispatcher { private $container; private $listenerIds = array(); private $listeners = array(); public function __construct(ContainerInterface $container) { $this->container = $container; } public function addListenerService($eventName, $callback, $priority = 0) { if (!is_array($callback) || 2 !== count($callback)) { throw new \InvalidArgumentException('Expected an array("service", "method") argument'); } $this->listenerIds[$eventName][] = array($callback[0], $callback[1], $priority); } public function removeListener($eventName, $listener) { $this->lazyLoad($eventName); if (isset($this->listeners[$eventName])) { foreach ($this->listeners[$eventName] as $key => $l) { foreach ($this->listenerIds[$eventName] as $i => $args) { list($serviceId, $method, $priority) = $args; if ($key === $serviceId.'.'.$method) { if ($listener === array($l, $method)) { unset($this->listeners[$eventName][$key]); if (empty($this->listeners[$eventName])) { unset($this->listeners[$eventName]); } unset($this->listenerIds[$eventName][$i]); if (empty($this->listenerIds[$eventName])) { unset($this->listenerIds[$eventName]); } } } } } } parent::removeListener($eventName, $listener); } public function hasListeners($eventName = null) { if (null === $eventName) { return (Boolean) count($this->listenerIds) || (Boolean) count($this->listeners); } if (isset($this->listenerIds[$eventName])) { return true; } return parent::hasListeners($eventName); } public function getListeners($eventName = null) { if (null === $eventName) { foreach (array_keys($this->listenerIds) as $serviceEventName) { $this->lazyLoad($serviceEventName); } } else { $this->lazyLoad($eventName); } return parent::getListeners($eventName); } public function addSubscriberService($serviceId, $class) { foreach ($class::getSubscribedEvents() as $eventName => $params) { if (is_string($params)) { $this->listenerIds[$eventName][] = array($serviceId, $params, 0); } elseif (is_string($params[0])) { $this->listenerIds[$eventName][] = array($serviceId, $params[0], isset($params[1]) ? $params[1] : 0); } else { foreach ($params as $listener) { $this->listenerIds[$eventName][] = array($serviceId, $listener[0], isset($listener[1]) ? $listener[1] : 0); } } } } public function dispatch($eventName, Event $event = null) { $this->lazyLoad($eventName); return parent::dispatch($eventName, $event); } public function getContainer() { return $this->container; } protected function lazyLoad($eventName) { if (isset($this->listenerIds[$eventName])) { foreach ($this->listenerIds[$eventName] as $args) { list($serviceId, $method, $priority) = $args; $listener = $this->container->get($serviceId); $key = $serviceId.'.'.$method; if (!isset($this->listeners[$eventName][$key])) { $this->addListener($eventName, array($listener, $method), $priority); } elseif ($listener !== $this->listeners[$eventName][$key]) { parent::removeListener($eventName, array($this->listeners[$eventName][$key], $method)); $this->addListener($eventName, array($listener, $method), $priority); } $this->listeners[$eventName][$key] = $listener; } } } } <?php namespace Symfony\Component\EventDispatcher\Debug; interface TraceableEventDispatcherInterface { function getCalledListeners(); function getNotCalledListeners(); } <?php namespace Symfony\Component\EventDispatcher; class Event { private $propagationStopped = false; private $dispatcher; private $name; public function isPropagationStopped() { return $this->propagationStopped; } public function stopPropagation() { $this->propagationStopped = true; } public function setDispatcher(EventDispatcher $dispatcher) { $this->dispatcher = $dispatcher; } public function getDispatcher() { return $this->dispatcher; } public function getName() { return $this->name; } public function setName($name) { $this->name = $name; } } <?php namespace Symfony\Component\EventDispatcher; class EventDispatcher implements EventDispatcherInterface { private $listeners = array(); private $sorted = array(); public function dispatch($eventName, Event $event = null) { if (null === $event) { $event = new Event(); } $event->setDispatcher($this); $event->setName($eventName); if (!isset($this->listeners[$eventName])) { return $event; } $this->doDispatch($this->getListeners($eventName), $eventName, $event); return $event; } public function getListeners($eventName = null) { if (null !== $eventName) { if (!isset($this->sorted[$eventName])) { $this->sortListeners($eventName); } return $this->sorted[$eventName]; } foreach (array_keys($this->listeners) as $eventName) { if (!isset($this->sorted[$eventName])) { $this->sortListeners($eventName); } } return $this->sorted; } public function hasListeners($eventName = null) { return (Boolean) count($this->getListeners($eventName)); } public function addListener($eventName, $listener, $priority = 0) { $this->listeners[$eventName][$priority][] = $listener; unset($this->sorted[$eventName]); } public function removeListener($eventName, $listener) { if (!isset($this->listeners[$eventName])) { return; } foreach ($this->listeners[$eventName] as $priority => $listeners) { if (false !== ($key = array_search($listener, $listeners))) { unset($this->listeners[$eventName][$priority][$key], $this->sorted[$eventName]); } } } public function addSubscriber(EventSubscriberInterface $subscriber) { foreach ($subscriber->getSubscribedEvents() as $eventName => $params) { if (is_string($params)) { $this->addListener($eventName, array($subscriber, $params)); } elseif (is_string($params[0])) { $this->addListener($eventName, array($subscriber, $params[0]), isset($params[1]) ? $params[1] : 0); } else { foreach ($params as $listener) { $this->addListener($eventName, array($subscriber, $listener[0]), isset($listener[1]) ? $listener[1] : 0); } } } } public function removeSubscriber(EventSubscriberInterface $subscriber) { foreach ($subscriber->getSubscribedEvents() as $eventName => $params) { if (is_array($params) && is_array($params[0])) { foreach ($params as $listener) { $this->removeListener($eventName, array($subscriber, $listener[0])); } } else { $this->removeListener($eventName, array($subscriber, is_string($params) ? $params : $params[0])); } } } protected function doDispatch($listeners, $eventName, Event $event) { foreach ($listeners as $listener) { call_user_func($listener, $event); if ($event->isPropagationStopped()) { break; } } } private function sortListeners($eventName) { $this->sorted[$eventName] = array(); if (isset($this->listeners[$eventName])) { krsort($this->listeners[$eventName]); $this->sorted[$eventName] = call_user_func_array('array_merge', $this->listeners[$eventName]); } } } <?php namespace Symfony\Component\EventDispatcher; interface EventDispatcherInterface { function dispatch($eventName, Event $event = null); function addListener($eventName, $listener, $priority = 0); function addSubscriber(EventSubscriberInterface $subscriber); function removeListener($eventName, $listener); function removeSubscriber(EventSubscriberInterface $subscriber); function getListeners($eventName = null); function hasListeners($eventName = null); } <?php namespace Symfony\Component\EventDispatcher; interface EventSubscriberInterface { static function getSubscribedEvents(); } <?php namespace Symfony\Component\EventDispatcher; class GenericEvent extends Event implements \ArrayAccess { protected $subject; protected $arguments; public function __construct($subject = null, array $arguments = array()) { $this->subject = $subject; $this->arguments = $arguments; } public function getSubject() { return $this->subject; } public function getArgument($key) { if ($this->hasArgument($key)) { return $this->arguments[$key]; } throw new \InvalidArgumentException(sprintf('%s not found in %s', $key, $this->getName())); } public function setArgument($key, $value) { $this->arguments[$key] = $value; return $this; } public function getArguments() { return $this->arguments; } public function setArguments(array $args = array()) { $this->arguments = $args; return $this; } public function hasArgument($key) { return array_key_exists($key, $this->arguments); } public function offsetGet($key) { return $this->getArgument($key); } public function offsetSet($key, $value) { $this->setArgument($key, $value); } public function offsetUnset($key) { if ($this->hasArgument($key)) { unset($this->arguments[$key]); } } public function offsetExists($key) { return $this->hasArgument($key); } } <?php namespace Symfony\Component\HttpFoundation; class ApacheRequest extends Request { protected function prepareRequestUri() { return $this->server->get('REQUEST_URI'); } protected function prepareBaseUrl() { $baseUrl = $this->server->get('SCRIPT_NAME'); if (false === strpos($this->server->get('REQUEST_URI'), $baseUrl)) { return rtrim(dirname($baseUrl), '/\\'); } return $baseUrl; } protected function preparePathInfo() { return $this->server->get('PATH_INFO') ?: substr($this->prepareRequestUri(), strlen($this->prepareBaseUrl())) ?: '/'; } } <?php namespace Symfony\Component\HttpFoundation; class Cookie { protected $name; protected $value; protected $domain; protected $expire; protected $path; protected $secure; protected $httpOnly; public function __construct($name, $value = null, $expire = 0, $path = '/', $domain = null, $secure = false, $httpOnly = true) { if (preg_match("/[=,; \t\r\n\013\014]/", $name)) { throw new \InvalidArgumentException(sprintf('The cookie name "%s" contains invalid characters.', $name)); } if (empty($name)) { throw new \InvalidArgumentException('The cookie name cannot be empty.'); } if ($expire instanceof \DateTime) { $expire = $expire->format('U'); } elseif (!is_numeric($expire)) { $expire = strtotime($expire); if (false === $expire || -1 === $expire) { throw new \InvalidArgumentException('The cookie expiration time is not valid.'); } } $this->name = $name; $this->value = $value; $this->domain = $domain; $this->expire = $expire; $this->path = empty($path) ? '/' : $path; $this->secure = (Boolean) $secure; $this->httpOnly = (Boolean) $httpOnly; } public function __toString() { $str = urlencode($this->getName()).'='; if ('' === (string) $this->getValue()) { $str .= 'deleted; expires='.gmdate("D, d-M-Y H:i:s T", time() - 31536001); } else { $str .= urlencode($this->getValue()); if ($this->getExpiresTime() !== 0) { $str .= '; expires='.gmdate("D, d-M-Y H:i:s T", $this->getExpiresTime()); } } if ('/' !== $this->path) { $str .= '; path='.$this->path; } if (null !== $this->getDomain()) { $str .= '; domain='.$this->getDomain(); } if (true === $this->isSecure()) { $str .= '; secure'; } if (true === $this->isHttpOnly()) { $str .= '; httponly'; } return $str; } public function getName() { return $this->name; } public function getValue() { return $this->value; } public function getDomain() { return $this->domain; } public function getExpiresTime() { return $this->expire; } public function getPath() { return $this->path; } public function isSecure() { return $this->secure; } public function isHttpOnly() { return $this->httpOnly; } public function isCleared() { return $this->expire < time(); } } <?php namespace Symfony\Component\HttpFoundation\File\Exception; class AccessDeniedException extends FileException { public function __construct($path) { parent::__construct(sprintf('The file %s could not be accessed', $path)); } } <?php namespace Symfony\Component\HttpFoundation\File\Exception; class FileException extends \RuntimeException { } <?php namespace Symfony\Component\HttpFoundation\File\Exception; class FileNotFoundException extends FileException { public function __construct($path) { parent::__construct(sprintf('The file "%s" does not exist', $path)); } } <?php namespace Symfony\Component\HttpFoundation\File\Exception; class UnexpectedTypeException extends FileException { public function __construct($value, $expectedType) { parent::__construct(sprintf('Expected argument of type %s, %s given', $expectedType, is_object($value) ? get_class($value) : gettype($value))); } } <?php namespace Symfony\Component\HttpFoundation\File\Exception; class UploadException extends FileException { } <?php namespace Symfony\Component\HttpFoundation\File; use Symfony\Component\HttpFoundation\File\Exception\FileException; use Symfony\Component\HttpFoundation\File\Exception\FileNotFoundException; use Symfony\Component\HttpFoundation\File\MimeType\MimeTypeGuesser; use Symfony\Component\HttpFoundation\File\MimeType\ExtensionGuesser; class File extends \SplFileInfo { public function __construct($path, $checkPath = true) { if ($checkPath && !is_file($path)) { throw new FileNotFoundException($path); } parent::__construct($path); } public function guessExtension() { $type = $this->getMimeType(); $guesser = ExtensionGuesser::getInstance(); return $guesser->guess($type); } public function getMimeType() { $guesser = MimeTypeGuesser::getInstance(); return $guesser->guess($this->getPathname()); } public function getExtension() { return pathinfo($this->getBasename(), PATHINFO_EXTENSION); } public function move($directory, $name = null) { if (!is_dir($directory)) { if (false === @mkdir($directory, 0777, true)) { throw new FileException(sprintf('Unable to create the "%s" directory', $directory)); } } elseif (!is_writable($directory)) { throw new FileException(sprintf('Unable to write in the "%s" directory', $directory)); } $target = $directory.DIRECTORY_SEPARATOR.(null === $name ? $this->getBasename() : basename($name)); if (!@rename($this->getPathname(), $target)) { $error = error_get_last(); throw new FileException(sprintf('Could not move the file "%s" to "%s" (%s)', $this->getPathname(), $target, strip_tags($error['message']))); } chmod($target, 0666 & ~umask()); return new File($target); } } <?php namespace Symfony\Component\HttpFoundation\File\MimeType; class ExtensionGuesser implements ExtensionGuesserInterface { static private $instance = null; protected $guessers = array(); static public function getInstance() { if (null === self::$instance) { self::$instance = new self(); } return self::$instance; } private function __construct() { $this->register(new MimeTypeExtensionGuesser()); } public function register(ExtensionGuesserInterface $guesser) { array_unshift($this->guessers, $guesser); } public function guess($mimeType) { foreach ($this->guessers as $guesser) { $extension = $guesser->guess($mimeType); if (null !== $extension) { break; } } return $extension; } } <?php namespace Symfony\Component\HttpFoundation\File\MimeType; interface ExtensionGuesserInterface { function guess($mimeType); } <?php namespace Symfony\Component\HttpFoundation\File\MimeType; use Symfony\Component\HttpFoundation\File\Exception\FileNotFoundException; use Symfony\Component\HttpFoundation\File\Exception\AccessDeniedException; class FileBinaryMimeTypeGuesser implements MimeTypeGuesserInterface { private $cmd; public function __construct($cmd = 'file -b --mime %s 2>/dev/null') { $this->cmd = $cmd; } static public function isSupported() { return !defined('PHP_WINDOWS_VERSION_BUILD'); } public function guess($path) { if (!is_file($path)) { throw new FileNotFoundException($path); } if (!is_readable($path)) { throw new AccessDeniedException($path); } if (!self::isSupported()) { return null; } ob_start(); passthru(sprintf($this->cmd, escapeshellarg($path)), $return); if ($return > 0) { ob_end_clean(); return null; } $type = trim(ob_get_clean()); if (!preg_match('#^([a-z0-9\-]+/[a-z0-9\-]+)#i', $type, $match)) { return null; } return $match[1]; } } <?php namespace Symfony\Component\HttpFoundation\File\MimeType; use Symfony\Component\HttpFoundation\File\Exception\FileNotFoundException; use Symfony\Component\HttpFoundation\File\Exception\AccessDeniedException; class FileinfoMimeTypeGuesser implements MimeTypeGuesserInterface { static public function isSupported() { return function_exists('finfo_open'); } public function guess($path) { if (!is_file($path)) { throw new FileNotFoundException($path); } if (!is_readable($path)) { throw new AccessDeniedException($path); } if (!self::isSupported()) { return null; } if (!$finfo = new \finfo(FILEINFO_MIME_TYPE)) { return null; } return $finfo->file($path); } } <?php namespace Symfony\Component\HttpFoundation\File\Mimetype; class MimeTypeExtensionGuesser implements ExtensionGuesserInterface { protected $defaultExtensions = array( 'application/andrew-inset' => 'ez', 'application/applixware' => 'aw', 'application/atom+xml' => 'atom', 'application/atomcat+xml' => 'atomcat', 'application/atomsvc+xml' => 'atomsvc', 'application/ccxml+xml' => 'ccxml', 'application/cdmi-capability' => 'cdmia', 'application/cdmi-container' => 'cdmic', 'application/cdmi-domain' => 'cdmid', 'application/cdmi-object' => 'cdmio', 'application/cdmi-queue' => 'cdmiq', 'application/cu-seeme' => 'cu', 'application/davmount+xml' => 'davmount', 'application/dssc+der' => 'dssc', 'application/dssc+xml' => 'xdssc', 'application/ecmascript' => 'ecma', 'application/emma+xml' => 'emma', 'application/epub+zip' => 'epub', 'application/exi' => 'exi', 'application/font-tdpfr' => 'pfr', 'application/hyperstudio' => 'stk', 'application/inkml+xml' => 'ink', 'application/ipfix' => 'ipfix', 'application/java-archive' => 'jar', 'application/java-serialized-object' => 'ser', 'application/java-vm' => 'class', 'application/javascript' => 'js', 'application/json' => 'json', 'application/lost+xml' => 'lostxml', 'application/mac-binhex40' => 'hqx', 'application/mac-compactpro' => 'cpt', 'application/mads+xml' => 'mads', 'application/marc' => 'mrc', 'application/marcxml+xml' => 'mrcx', 'application/mathematica' => 'ma', 'application/mathml+xml' => 'mathml', 'application/mbox' => 'mbox', 'application/mediaservercontrol+xml' => 'mscml', 'application/metalink4+xml' => 'meta4', 'application/mets+xml' => 'mets', 'application/mods+xml' => 'mods', 'application/mp21' => 'm21', 'application/mp4' => 'mp4s', 'application/msword' => 'doc', 'application/mxf' => 'mxf', 'application/octet-stream' => 'bin', 'application/oda' => 'oda', 'application/oebps-package+xml' => 'opf', 'application/ogg' => 'ogx', 'application/onenote' => 'onetoc', 'application/oxps' => 'oxps', 'application/patch-ops-error+xml' => 'xer', 'application/pdf' => 'pdf', 'application/pgp-encrypted' => 'pgp', 'application/pgp-signature' => 'asc', 'application/pics-rules' => 'prf', 'application/pkcs10' => 'p10', 'application/pkcs7-mime' => 'p7m', 'application/pkcs7-signature' => 'p7s', 'application/pkcs8' => 'p8', 'application/pkix-attr-cert' => 'ac', 'application/pkix-cert' => 'cer', 'application/pkix-crl' => 'crl', 'application/pkix-pkipath' => 'pkipath', 'application/pkixcmp' => 'pki', 'application/pls+xml' => 'pls', 'application/postscript' => 'ai', 'application/prs.cww' => 'cww', 'application/pskc+xml' => 'pskcxml', 'application/rdf+xml' => 'rdf', 'application/reginfo+xml' => 'rif', 'application/relax-ng-compact-syntax' => 'rnc', 'application/resource-lists+xml' => 'rl', 'application/resource-lists-diff+xml' => 'rld', 'application/rls-services+xml' => 'rs', 'application/rpki-ghostbusters' => 'gbr', 'application/rpki-manifest' => 'mft', 'application/rpki-roa' => 'roa', 'application/rsd+xml' => 'rsd', 'application/rss+xml' => 'rss', 'application/rtf' => 'rtf', 'application/sbml+xml' => 'sbml', 'application/scvp-cv-request' => 'scq', 'application/scvp-cv-response' => 'scs', 'application/scvp-vp-request' => 'spq', 'application/scvp-vp-response' => 'spp', 'application/sdp' => 'sdp', 'application/set-payment-initiation' => 'setpay', 'application/set-registration-initiation' => 'setreg', 'application/shf+xml' => 'shf', 'application/smil+xml' => 'smi', 'application/sparql-query' => 'rq', 'application/sparql-results+xml' => 'srx', 'application/srgs' => 'gram', 'application/srgs+xml' => 'grxml', 'application/sru+xml' => 'sru', 'application/ssml+xml' => 'ssml', 'application/tei+xml' => 'tei', 'application/thraud+xml' => 'tfi', 'application/timestamped-data' => 'tsd', 'application/vnd.3gpp.pic-bw-large' => 'plb', 'application/vnd.3gpp.pic-bw-small' => 'psb', 'application/vnd.3gpp.pic-bw-var' => 'pvb', 'application/vnd.3gpp2.tcap' => 'tcap', 'application/vnd.3m.post-it-notes' => 'pwn', 'application/vnd.accpac.simply.aso' => 'aso', 'application/vnd.accpac.simply.imp' => 'imp', 'application/vnd.acucobol' => 'acu', 'application/vnd.acucorp' => 'atc', 'application/vnd.adobe.air-application-installer-package+zip' => 'air', 'application/vnd.adobe.fxp' => 'fxp', 'application/vnd.adobe.xdp+xml' => 'xdp', 'application/vnd.adobe.xfdf' => 'xfdf', 'application/vnd.ahead.space' => 'ahead', 'application/vnd.airzip.filesecure.azf' => 'azf', 'application/vnd.airzip.filesecure.azs' => 'azs', 'application/vnd.amazon.ebook' => 'azw', 'application/vnd.americandynamics.acc' => 'acc', 'application/vnd.amiga.ami' => 'ami', 'application/vnd.android.package-archive' => 'apk', 'application/vnd.anser-web-certificate-issue-initiation' => 'cii', 'application/vnd.anser-web-funds-transfer-initiation' => 'fti', 'application/vnd.antix.game-component' => 'atx', 'application/vnd.apple.installer+xml' => 'mpkg', 'application/vnd.apple.mpegurl' => 'm3u8', 'application/vnd.aristanetworks.swi' => 'swi', 'application/vnd.astraea-software.iota' => 'iota', 'application/vnd.audiograph' => 'aep', 'application/vnd.blueice.multipass' => 'mpm', 'application/vnd.bmi' => 'bmi', 'application/vnd.businessobjects' => 'rep', 'application/vnd.chemdraw+xml' => 'cdxml', 'application/vnd.chipnuts.karaoke-mmd' => 'mmd', 'application/vnd.cinderella' => 'cdy', 'application/vnd.claymore' => 'cla', 'application/vnd.cloanto.rp9' => 'rp9', 'application/vnd.clonk.c4group' => 'c4g', 'application/vnd.cluetrust.cartomobile-config' => 'c11amc', 'application/vnd.cluetrust.cartomobile-config-pkg' => 'c11amz', 'application/vnd.commonspace' => 'csp', 'application/vnd.contact.cmsg' => 'cdbcmsg', 'application/vnd.cosmocaller' => 'cmc', 'application/vnd.crick.clicker' => 'clkx', 'application/vnd.crick.clicker.keyboard' => 'clkk', 'application/vnd.crick.clicker.palette' => 'clkp', 'application/vnd.crick.clicker.template' => 'clkt', 'application/vnd.crick.clicker.wordbank' => 'clkw', 'application/vnd.criticaltools.wbs+xml' => 'wbs', 'application/vnd.ctc-posml' => 'pml', 'application/vnd.cups-ppd' => 'ppd', 'application/vnd.curl.car' => 'car', 'application/vnd.curl.pcurl' => 'pcurl', 'application/vnd.data-vision.rdz' => 'rdz', 'application/vnd.dece.data' => 'uvf', 'application/vnd.dece.ttml+xml' => 'uvt', 'application/vnd.dece.unspecified' => 'uvx', 'application/vnd.dece.zip' => 'uvz', 'application/vnd.denovo.fcselayout-link' => 'fe_launch', 'application/vnd.dna' => 'dna', 'application/vnd.dolby.mlp' => 'mlp', 'application/vnd.dpgraph' => 'dpg', 'application/vnd.dreamfactory' => 'dfac', 'application/vnd.dvb.ait' => 'ait', 'application/vnd.dvb.service' => 'svc', 'application/vnd.dynageo' => 'geo', 'application/vnd.ecowin.chart' => 'mag', 'application/vnd.enliven' => 'nml', 'application/vnd.epson.esf' => 'esf', 'application/vnd.epson.msf' => 'msf', 'application/vnd.epson.quickanime' => 'qam', 'application/vnd.epson.salt' => 'slt', 'application/vnd.epson.ssf' => 'ssf', 'application/vnd.eszigno3+xml' => 'es3', 'application/vnd.ezpix-album' => 'ez2', 'application/vnd.ezpix-package' => 'ez3', 'application/vnd.fdf' => 'fdf', 'application/vnd.fdsn.mseed' => 'mseed', 'application/vnd.fdsn.seed' => 'seed', 'application/vnd.flographit' => 'gph', 'application/vnd.fluxtime.clip' => 'ftc', 'application/vnd.framemaker' => 'fm', 'application/vnd.frogans.fnc' => 'fnc', 'application/vnd.frogans.ltf' => 'ltf', 'application/vnd.fsc.weblaunch' => 'fsc', 'application/vnd.fujitsu.oasys' => 'oas', 'application/vnd.fujitsu.oasys2' => 'oa2', 'application/vnd.fujitsu.oasys3' => 'oa3', 'application/vnd.fujitsu.oasysgp' => 'fg5', 'application/vnd.fujitsu.oasysprs' => 'bh2', 'application/vnd.fujixerox.ddd' => 'ddd', 'application/vnd.fujixerox.docuworks' => 'xdw', 'application/vnd.fujixerox.docuworks.binder' => 'xbd', 'application/vnd.fuzzysheet' => 'fzs', 'application/vnd.genomatix.tuxedo' => 'txd', 'application/vnd.geogebra.file' => 'ggb', 'application/vnd.geogebra.tool' => 'ggt', 'application/vnd.geometry-explorer' => 'gex', 'application/vnd.geonext' => 'gxt', 'application/vnd.geoplan' => 'g2w', 'application/vnd.geospace' => 'g3w', 'application/vnd.gmx' => 'gmx', 'application/vnd.google-earth.kml+xml' => 'kml', 'application/vnd.google-earth.kmz' => 'kmz', 'application/vnd.grafeq' => 'gqf', 'application/vnd.groove-account' => 'gac', 'application/vnd.groove-help' => 'ghf', 'application/vnd.groove-identity-message' => 'gim', 'application/vnd.groove-injector' => 'grv', 'application/vnd.groove-tool-message' => 'gtm', 'application/vnd.groove-tool-template' => 'tpl', 'application/vnd.groove-vcard' => 'vcg', 'application/vnd.hal+xml' => 'hal', 'application/vnd.handheld-entertainment+xml' => 'zmm', 'application/vnd.hbci' => 'hbci', 'application/vnd.hhe.lesson-player' => 'les', 'application/vnd.hp-hpgl' => 'hpgl', 'application/vnd.hp-hpid' => 'hpid', 'application/vnd.hp-hps' => 'hps', 'application/vnd.hp-jlyt' => 'jlt', 'application/vnd.hp-pcl' => 'pcl', 'application/vnd.hp-pclxl' => 'pclxl', 'application/vnd.hydrostatix.sof-data' => 'sfd-hdstx', 'application/vnd.hzn-3d-crossword' => 'x3d', 'application/vnd.ibm.minipay' => 'mpy', 'application/vnd.ibm.modcap' => 'afp', 'application/vnd.ibm.rights-management' => 'irm', 'application/vnd.ibm.secure-container' => 'sc', 'application/vnd.iccprofile' => 'icc', 'application/vnd.igloader' => 'igl', 'application/vnd.immervision-ivp' => 'ivp', 'application/vnd.immervision-ivu' => 'ivu', 'application/vnd.insors.igm' => 'igm', 'application/vnd.intercon.formnet' => 'xpw', 'application/vnd.intergeo' => 'i2g', 'application/vnd.intu.qbo' => 'qbo', 'application/vnd.intu.qfx' => 'qfx', 'application/vnd.ipunplugged.rcprofile' => 'rcprofile', 'application/vnd.irepository.package+xml' => 'irp', 'application/vnd.is-xpr' => 'xpr', 'application/vnd.isac.fcs' => 'fcs', 'application/vnd.jam' => 'jam', 'application/vnd.jcp.javame.midlet-rms' => 'rms', 'application/vnd.jisp' => 'jisp', 'application/vnd.joost.joda-archive' => 'joda', 'application/vnd.kahootz' => 'ktz', 'application/vnd.kde.karbon' => 'karbon', 'application/vnd.kde.kchart' => 'chrt', 'application/vnd.kde.kformula' => 'kfo', 'application/vnd.kde.kivio' => 'flw', 'application/vnd.kde.kontour' => 'kon', 'application/vnd.kde.kpresenter' => 'kpr', 'application/vnd.kde.kspread' => 'ksp', 'application/vnd.kde.kword' => 'kwd', 'application/vnd.kenameaapp' => 'htke', 'application/vnd.kidspiration' => 'kia', 'application/vnd.kinar' => 'kne', 'application/vnd.koan' => 'skp', 'application/vnd.kodak-descriptor' => 'sse', 'application/vnd.las.las+xml' => 'lasxml', 'application/vnd.llamagraphics.life-balance.desktop' => 'lbd', 'application/vnd.llamagraphics.life-balance.exchange+xml' => 'lbe', 'application/vnd.lotus-1-2-3' => '123', 'application/vnd.lotus-approach' => 'apr', 'application/vnd.lotus-freelance' => 'pre', 'application/vnd.lotus-notes' => 'nsf', 'application/vnd.lotus-organizer' => 'org', 'application/vnd.lotus-screencam' => 'scm', 'application/vnd.lotus-wordpro' => 'lwp', 'application/vnd.macports.portpkg' => 'portpkg', 'application/vnd.mcd' => 'mcd', 'application/vnd.medcalcdata' => 'mc1', 'application/vnd.mediastation.cdkey' => 'cdkey', 'application/vnd.mfer' => 'mwf', 'application/vnd.mfmp' => 'mfm', 'application/vnd.micrografx.flo' => 'flo', 'application/vnd.micrografx.igx' => 'igx', 'application/vnd.mif' => 'mif', 'application/vnd.mobius.daf' => 'daf', 'application/vnd.mobius.dis' => 'dis', 'application/vnd.mobius.mbk' => 'mbk', 'application/vnd.mobius.mqy' => 'mqy', 'application/vnd.mobius.msl' => 'msl', 'application/vnd.mobius.plc' => 'plc', 'application/vnd.mobius.txf' => 'txf', 'application/vnd.mophun.application' => 'mpn', 'application/vnd.mophun.certificate' => 'mpc', 'application/vnd.mozilla.xul+xml' => 'xul', 'application/vnd.ms-artgalry' => 'cil', 'application/vnd.ms-cab-compressed' => 'cab', 'application/vnd.ms-excel' => 'xls', 'application/vnd.ms-excel.addin.macroenabled.12' => 'xlam', 'application/vnd.ms-excel.sheet.binary.macroenabled.12' => 'xlsb', 'application/vnd.ms-excel.sheet.macroenabled.12' => 'xlsm', 'application/vnd.ms-excel.template.macroenabled.12' => 'xltm', 'application/vnd.ms-fontobject' => 'eot', 'application/vnd.ms-htmlhelp' => 'chm', 'application/vnd.ms-ims' => 'ims', 'application/vnd.ms-lrm' => 'lrm', 'application/vnd.ms-officetheme' => 'thmx', 'application/vnd.ms-pki.seccat' => 'cat', 'application/vnd.ms-pki.stl' => 'stl', 'application/vnd.ms-powerpoint' => 'ppt', 'application/vnd.ms-powerpoint.addin.macroenabled.12' => 'ppam', 'application/vnd.ms-powerpoint.presentation.macroenabled.12' => 'pptm', 'application/vnd.ms-powerpoint.slide.macroenabled.12' => 'sldm', 'application/vnd.ms-powerpoint.slideshow.macroenabled.12' => 'ppsm', 'application/vnd.ms-powerpoint.template.macroenabled.12' => 'potm', 'application/vnd.ms-project' => 'mpp', 'application/vnd.ms-word.document.macroenabled.12' => 'docm', 'application/vnd.ms-word.template.macroenabled.12' => 'dotm', 'application/vnd.ms-works' => 'wps', 'application/vnd.ms-wpl' => 'wpl', 'application/vnd.ms-xpsdocument' => 'xps', 'application/vnd.mseq' => 'mseq', 'application/vnd.musician' => 'mus', 'application/vnd.muvee.style' => 'msty', 'application/vnd.mynfc' => 'taglet', 'application/vnd.neurolanguage.nlu' => 'nlu', 'application/vnd.noblenet-directory' => 'nnd', 'application/vnd.noblenet-sealer' => 'nns', 'application/vnd.noblenet-web' => 'nnw', 'application/vnd.nokia.n-gage.data' => 'ngdat', 'application/vnd.nokia.n-gage.symbian.install' => 'n-gage', 'application/vnd.nokia.radio-preset' => 'rpst', 'application/vnd.nokia.radio-presets' => 'rpss', 'application/vnd.novadigm.edm' => 'edm', 'application/vnd.novadigm.edx' => 'edx', 'application/vnd.novadigm.ext' => 'ext', 'application/vnd.oasis.opendocument.chart' => 'odc', 'application/vnd.oasis.opendocument.chart-template' => 'otc', 'application/vnd.oasis.opendocument.database' => 'odb', 'application/vnd.oasis.opendocument.formula' => 'odf', 'application/vnd.oasis.opendocument.formula-template' => 'odft', 'application/vnd.oasis.opendocument.graphics' => 'odg', 'application/vnd.oasis.opendocument.graphics-template' => 'otg', 'application/vnd.oasis.opendocument.image' => 'odi', 'application/vnd.oasis.opendocument.image-template' => 'oti', 'application/vnd.oasis.opendocument.presentation' => 'odp', 'application/vnd.oasis.opendocument.presentation-template' => 'otp', 'application/vnd.oasis.opendocument.spreadsheet' => 'ods', 'application/vnd.oasis.opendocument.spreadsheet-template' => 'ots', 'application/vnd.oasis.opendocument.text' => 'odt', 'application/vnd.oasis.opendocument.text-master' => 'odm', 'application/vnd.oasis.opendocument.text-template' => 'ott', 'application/vnd.oasis.opendocument.text-web' => 'oth', 'application/vnd.olpc-sugar' => 'xo', 'application/vnd.oma.dd2+xml' => 'dd2', 'application/vnd.openofficeorg.extension' => 'oxt', 'application/vnd.openxmlformats-officedocument.presentationml.presentation' => 'pptx', 'application/vnd.openxmlformats-officedocument.presentationml.slide' => 'sldx', 'application/vnd.openxmlformats-officedocument.presentationml.slideshow' => 'ppsx', 'application/vnd.openxmlformats-officedocument.presentationml.template' => 'potx', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' => 'xlsx', 'application/vnd.openxmlformats-officedocument.spreadsheetml.template' => 'xltx', 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' => 'docx', 'application/vnd.openxmlformats-officedocument.wordprocessingml.template' => 'dotx', 'application/vnd.osgeo.mapguide.package' => 'mgp', 'application/vnd.osgi.dp' => 'dp', 'application/vnd.palm' => 'pdb', 'application/vnd.pawaafile' => 'paw', 'application/vnd.pg.format' => 'str', 'application/vnd.pg.osasli' => 'ei6', 'application/vnd.picsel' => 'efif', 'application/vnd.pmi.widget' => 'wg', 'application/vnd.pocketlearn' => 'plf', 'application/vnd.powerbuilder6' => 'pbd', 'application/vnd.previewsystems.box' => 'box', 'application/vnd.proteus.magazine' => 'mgz', 'application/vnd.publishare-delta-tree' => 'qps', 'application/vnd.pvi.ptid1' => 'ptid', 'application/vnd.quark.quarkxpress' => 'qxd', 'application/vnd.realvnc.bed' => 'bed', 'application/vnd.recordare.musicxml' => 'mxl', 'application/vnd.recordare.musicxml+xml' => 'musicxml', 'application/vnd.rig.cryptonote' => 'cryptonote', 'application/vnd.rim.cod' => 'cod', 'application/vnd.rn-realmedia' => 'rm', 'application/vnd.route66.link66+xml' => 'link66', 'application/vnd.sailingtracker.track' => 'st', 'application/vnd.seemail' => 'see', 'application/vnd.sema' => 'sema', 'application/vnd.semd' => 'semd', 'application/vnd.semf' => 'semf', 'application/vnd.shana.informed.formdata' => 'ifm', 'application/vnd.shana.informed.formtemplate' => 'itp', 'application/vnd.shana.informed.interchange' => 'iif', 'application/vnd.shana.informed.package' => 'ipk', 'application/vnd.simtech-mindmapper' => 'twd', 'application/vnd.smaf' => 'mmf', 'application/vnd.smart.teacher' => 'teacher', 'application/vnd.solent.sdkm+xml' => 'sdkm', 'application/vnd.spotfire.dxp' => 'dxp', 'application/vnd.spotfire.sfs' => 'sfs', 'application/vnd.stardivision.calc' => 'sdc', 'application/vnd.stardivision.draw' => 'sda', 'application/vnd.stardivision.impress' => 'sdd', 'application/vnd.stardivision.math' => 'smf', 'application/vnd.stardivision.writer' => 'sdw', 'application/vnd.stardivision.writer-global' => 'sgl', 'application/vnd.stepmania.package' => 'smzip', 'application/vnd.stepmania.stepchart' => 'sm', 'application/vnd.sun.xml.calc' => 'sxc', 'application/vnd.sun.xml.calc.template' => 'stc', 'application/vnd.sun.xml.draw' => 'sxd', 'application/vnd.sun.xml.draw.template' => 'std', 'application/vnd.sun.xml.impress' => 'sxi', 'application/vnd.sun.xml.impress.template' => 'sti', 'application/vnd.sun.xml.math' => 'sxm', 'application/vnd.sun.xml.writer' => 'sxw', 'application/vnd.sun.xml.writer.global' => 'sxg', 'application/vnd.sun.xml.writer.template' => 'stw', 'application/vnd.sus-calendar' => 'sus', 'application/vnd.svd' => 'svd', 'application/vnd.symbian.install' => 'sis', 'application/vnd.syncml+xml' => 'xsm', 'application/vnd.syncml.dm+wbxml' => 'bdm', 'application/vnd.syncml.dm+xml' => 'xdm', 'application/vnd.tao.intent-module-archive' => 'tao', 'application/vnd.tcpdump.pcap' => 'pcap', 'application/vnd.tmobile-livetv' => 'tmo', 'application/vnd.trid.tpt' => 'tpt', 'application/vnd.triscape.mxs' => 'mxs', 'application/vnd.trueapp' => 'tra', 'application/vnd.ufdl' => 'ufd', 'application/vnd.uiq.theme' => 'utz', 'application/vnd.umajin' => 'umj', 'application/vnd.unity' => 'unityweb', 'application/vnd.uoml+xml' => 'uoml', 'application/vnd.vcx' => 'vcx', 'application/vnd.visio' => 'vsd', 'application/vnd.visionary' => 'vis', 'application/vnd.vsf' => 'vsf', 'application/vnd.wap.wbxml' => 'wbxml', 'application/vnd.wap.wmlc' => 'wmlc', 'application/vnd.wap.wmlscriptc' => 'wmlsc', 'application/vnd.webturbo' => 'wtb', 'application/vnd.wolfram.player' => 'nbp', 'application/vnd.wordperfect' => 'wpd', 'application/vnd.wqd' => 'wqd', 'application/vnd.wt.stf' => 'stf', 'application/vnd.xara' => 'xar', 'application/vnd.xfdl' => 'xfdl', 'application/vnd.yamaha.hv-dic' => 'hvd', 'application/vnd.yamaha.hv-script' => 'hvs', 'application/vnd.yamaha.hv-voice' => 'hvp', 'application/vnd.yamaha.openscoreformat' => 'osf', 'application/vnd.yamaha.openscoreformat.osfpvg+xml' => 'osfpvg', 'application/vnd.yamaha.smaf-audio' => 'saf', 'application/vnd.yamaha.smaf-phrase' => 'spf', 'application/vnd.yellowriver-custom-menu' => 'cmp', 'application/vnd.zul' => 'zir', 'application/vnd.zzazz.deck+xml' => 'zaz', 'application/voicexml+xml' => 'vxml', 'application/widget' => 'wgt', 'application/winhlp' => 'hlp', 'application/wsdl+xml' => 'wsdl', 'application/wspolicy+xml' => 'wspolicy', 'application/x-7z-compressed' => '7z', 'application/x-abiword' => 'abw', 'application/x-ace-compressed' => 'ace', 'application/x-authorware-bin' => 'aab', 'application/x-authorware-map' => 'aam', 'application/x-authorware-seg' => 'aas', 'application/x-bcpio' => 'bcpio', 'application/x-bittorrent' => 'torrent', 'application/x-bzip' => 'bz', 'application/x-bzip2' => 'bz2', 'application/x-cdlink' => 'vcd', 'application/x-chat' => 'chat', 'application/x-chess-pgn' => 'pgn', 'application/x-cpio' => 'cpio', 'application/x-csh' => 'csh', 'application/x-debian-package' => 'deb', 'application/x-director' => 'dir', 'application/x-doom' => 'wad', 'application/x-dtbncx+xml' => 'ncx', 'application/x-dtbook+xml' => 'dtb', 'application/x-dtbresource+xml' => 'res', 'application/x-dvi' => 'dvi', 'application/x-font-bdf' => 'bdf', 'application/x-font-ghostscript' => 'gsf', 'application/x-font-linux-psf' => 'psf', 'application/x-font-otf' => 'otf', 'application/x-font-pcf' => 'pcf', 'application/x-font-snf' => 'snf', 'application/x-font-ttf' => 'ttf', 'application/x-font-type1' => 'pfa', 'application/x-font-woff' => 'woff', 'application/x-futuresplash' => 'spl', 'application/x-gnumeric' => 'gnumeric', 'application/x-gtar' => 'gtar', 'application/x-hdf' => 'hdf', 'application/x-java-jnlp-file' => 'jnlp', 'application/x-latex' => 'latex', 'application/x-mobipocket-ebook' => 'prc', 'application/x-ms-application' => 'application', 'application/x-ms-wmd' => 'wmd', 'application/x-ms-wmz' => 'wmz', 'application/x-ms-xbap' => 'xbap', 'application/x-msaccess' => 'mdb', 'application/x-msbinder' => 'obd', 'application/x-mscardfile' => 'crd', 'application/x-msclip' => 'clp', 'application/x-msdownload' => 'exe', 'application/x-msmediaview' => 'mvb', 'application/x-msmetafile' => 'wmf', 'application/x-msmoney' => 'mny', 'application/x-mspublisher' => 'pub', 'application/x-msschedule' => 'scd', 'application/x-msterminal' => 'trm', 'application/x-mswrite' => 'wri', 'application/x-netcdf' => 'nc', 'application/x-pkcs12' => 'p12', 'application/x-pkcs7-certificates' => 'p7b', 'application/x-pkcs7-certreqresp' => 'p7r', 'application/x-rar-compressed' => 'rar', 'application/x-sh' => 'sh', 'application/x-shar' => 'shar', 'application/x-shockwave-flash' => 'swf', 'application/x-silverlight-app' => 'xap', 'application/x-stuffit' => 'sit', 'application/x-stuffitx' => 'sitx', 'application/x-sv4cpio' => 'sv4cpio', 'application/x-sv4crc' => 'sv4crc', 'application/x-tar' => 'tar', 'application/x-tcl' => 'tcl', 'application/x-tex' => 'tex', 'application/x-tex-tfm' => 'tfm', 'application/x-texinfo' => 'texinfo', 'application/x-ustar' => 'ustar', 'application/x-wais-source' => 'src', 'application/x-x509-ca-cert' => 'der', 'application/x-xfig' => 'fig', 'application/x-xpinstall' => 'xpi', 'application/xcap-diff+xml' => 'xdf', 'application/xenc+xml' => 'xenc', 'application/xhtml+xml' => 'xhtml', 'application/xml' => 'xml', 'application/xml-dtd' => 'dtd', 'application/xop+xml' => 'xop', 'application/xslt+xml' => 'xslt', 'application/xspf+xml' => 'xspf', 'application/xv+xml' => 'mxml', 'application/yang' => 'yang', 'application/yin+xml' => 'yin', 'application/zip' => 'zip', 'audio/adpcm' => 'adp', 'audio/basic' => 'au', 'audio/midi' => 'mid', 'audio/mp4' => 'mp4a', 'audio/mpeg' => 'mpga', 'audio/ogg' => 'oga', 'audio/vnd.dece.audio' => 'uva', 'audio/vnd.digital-winds' => 'eol', 'audio/vnd.dra' => 'dra', 'audio/vnd.dts' => 'dts', 'audio/vnd.dts.hd' => 'dtshd', 'audio/vnd.lucent.voice' => 'lvp', 'audio/vnd.ms-playready.media.pya' => 'pya', 'audio/vnd.nuera.ecelp4800' => 'ecelp4800', 'audio/vnd.nuera.ecelp7470' => 'ecelp7470', 'audio/vnd.nuera.ecelp9600' => 'ecelp9600', 'audio/vnd.rip' => 'rip', 'audio/webm' => 'weba', 'audio/x-aac' => 'aac', 'audio/x-aiff' => 'aif', 'audio/x-mpegurl' => 'm3u', 'audio/x-ms-wax' => 'wax', 'audio/x-ms-wma' => 'wma', 'audio/x-pn-realaudio' => 'ram', 'audio/x-pn-realaudio-plugin' => 'rmp', 'audio/x-wav' => 'wav', 'chemical/x-cdx' => 'cdx', 'chemical/x-cif' => 'cif', 'chemical/x-cmdf' => 'cmdf', 'chemical/x-cml' => 'cml', 'chemical/x-csml' => 'csml', 'chemical/x-xyz' => 'xyz', 'image/bmp' => 'bmp', 'image/cgm' => 'cgm', 'image/g3fax' => 'g3', 'image/gif' => 'gif', 'image/ief' => 'ief', 'image/jpeg' => 'jpeg', 'image/ktx' => 'ktx', 'image/png' => 'png', 'image/prs.btif' => 'btif', 'image/svg+xml' => 'svg', 'image/tiff' => 'tiff', 'image/vnd.adobe.photoshop' => 'psd', 'image/vnd.dece.graphic' => 'uvi', 'image/vnd.dvb.subtitle' => 'sub', 'image/vnd.djvu' => 'djvu', 'image/vnd.dwg' => 'dwg', 'image/vnd.dxf' => 'dxf', 'image/vnd.fastbidsheet' => 'fbs', 'image/vnd.fpx' => 'fpx', 'image/vnd.fst' => 'fst', 'image/vnd.fujixerox.edmics-mmr' => 'mmr', 'image/vnd.fujixerox.edmics-rlc' => 'rlc', 'image/vnd.ms-modi' => 'mdi', 'image/vnd.net-fpx' => 'npx', 'image/vnd.wap.wbmp' => 'wbmp', 'image/vnd.xiff' => 'xif', 'image/webp' => 'webp', 'image/x-cmu-raster' => 'ras', 'image/x-cmx' => 'cmx', 'image/x-freehand' => 'fh', 'image/x-icon' => 'ico', 'image/x-pcx' => 'pcx', 'image/x-pict' => 'pic', 'image/x-portable-anymap' => 'pnm', 'image/x-portable-bitmap' => 'pbm', 'image/x-portable-graymap' => 'pgm', 'image/x-portable-pixmap' => 'ppm', 'image/x-rgb' => 'rgb', 'image/x-xbitmap' => 'xbm', 'image/x-xpixmap' => 'xpm', 'image/x-xwindowdump' => 'xwd', 'message/rfc822' => 'eml', 'model/iges' => 'igs', 'model/mesh' => 'msh', 'model/vnd.collada+xml' => 'dae', 'model/vnd.dwf' => 'dwf', 'model/vnd.gdl' => 'gdl', 'model/vnd.gtw' => 'gtw', 'model/vnd.mts' => 'mts', 'model/vnd.vtu' => 'vtu', 'model/vrml' => 'wrl', 'text/calendar' => 'ics', 'text/css' => 'css', 'text/csv' => 'csv', 'text/html' => 'html', 'text/n3' => 'n3', 'text/plain' => 'txt', 'text/prs.lines.tag' => 'dsc', 'text/richtext' => 'rtx', 'text/sgml' => 'sgml', 'text/tab-separated-values' => 'tsv', 'text/troff' => 't', 'text/turtle' => 'ttl', 'text/uri-list' => 'uri', 'text/vcard' => 'vcard', 'text/vnd.curl' => 'curl', 'text/vnd.curl.dcurl' => 'dcurl', 'text/vnd.curl.scurl' => 'scurl', 'text/vnd.curl.mcurl' => 'mcurl', 'text/vnd.dvb.subtitle' => 'sub', 'text/vnd.fly' => 'fly', 'text/vnd.fmi.flexstor' => 'flx', 'text/vnd.graphviz' => 'gv', 'text/vnd.in3d.3dml' => '3dml', 'text/vnd.in3d.spot' => 'spot', 'text/vnd.sun.j2me.app-descriptor' => 'jad', 'text/vnd.wap.wml' => 'wml', 'text/vnd.wap.wmlscript' => 'wmls', 'text/x-asm' => 's', 'text/x-c' => 'c', 'text/x-fortran' => 'f', 'text/x-pascal' => 'p', 'text/x-java-source' => 'java', 'text/x-setext' => 'etx', 'text/x-uuencode' => 'uu', 'text/x-vcalendar' => 'vcs', 'text/x-vcard' => 'vcf', 'video/3gpp' => '3gp', 'video/3gpp2' => '3g2', 'video/h261' => 'h261', 'video/h263' => 'h263', 'video/h264' => 'h264', 'video/jpeg' => 'jpgv', 'video/jpm' => 'jpm', 'video/mj2' => 'mj2', 'video/mp4' => 'mp4', 'video/mpeg' => 'mpeg', 'video/ogg' => 'ogv', 'video/quicktime' => 'qt', 'video/vnd.dece.hd' => 'uvh', 'video/vnd.dece.mobile' => 'uvm', 'video/vnd.dece.pd' => 'uvp', 'video/vnd.dece.sd' => 'uvs', 'video/vnd.dece.video' => 'uvv', 'video/vnd.dvb.file' => 'dvb', 'video/vnd.fvt' => 'fvt', 'video/vnd.mpegurl' => 'mxu', 'video/vnd.ms-playready.media.pyv' => 'pyv', 'video/vnd.uvvu.mp4' => 'uvu', 'video/vnd.vivo' => 'viv', 'video/webm' => 'webm', 'video/x-f4v' => 'f4v', 'video/x-fli' => 'fli', 'video/x-flv' => 'flv', 'video/x-m4v' => 'm4v', 'video/x-ms-asf' => 'asf', 'video/x-ms-wm' => 'wm', 'video/x-ms-wmv' => 'wmv', 'video/x-ms-wmx' => 'wmx', 'video/x-ms-wvx' => 'wvx', 'video/x-msvideo' => 'avi', 'video/x-sgi-movie' => 'movie', 'x-conference/x-cooltalk' => 'ice', ); public function guess($mimeType) { return isset($this->defaultExtensions[$mimeType]) ? $this->defaultExtensions[$mimeType] : null; } } <?php namespace Symfony\Component\HttpFoundation\File\MimeType; use Symfony\Component\HttpFoundation\File\Exception\FileNotFoundException; use Symfony\Component\HttpFoundation\File\Exception\AccessDeniedException; class MimeTypeGuesser implements MimeTypeGuesserInterface { static private $instance = null; protected $guessers = array(); static public function getInstance() { if (null === self::$instance) { self::$instance = new self(); } return self::$instance; } private function __construct() { if (FileBinaryMimeTypeGuesser::isSupported()) { $this->register(new FileBinaryMimeTypeGuesser()); } if (FileinfoMimeTypeGuesser::isSupported()) { $this->register(new FileinfoMimeTypeGuesser()); } } public function register(MimeTypeGuesserInterface $guesser) { array_unshift($this->guessers, $guesser); } public function guess($path) { if (!is_file($path)) { throw new FileNotFoundException($path); } if (!is_readable($path)) { throw new AccessDeniedException($path); } if (!$this->guessers) { throw new \LogicException('Unable to guess the mime type as no guessers are available (Did you enable the php_fileinfo extension?)'); } foreach ($this->guessers as $guesser) { if (null !== $mimeType = $guesser->guess($path)) { return $mimeType; } } } } <?php namespace Symfony\Component\HttpFoundation\File\MimeType; interface MimeTypeGuesserInterface { function guess($path); } <?php namespace Symfony\Component\HttpFoundation\File; use Symfony\Component\HttpFoundation\File\Exception\FileException; use Symfony\Component\HttpFoundation\File\Exception\FileNotFoundException; class UploadedFile extends File { private $test = false; private $originalName; private $mimeType; private $size; private $error; public function __construct($path, $originalName, $mimeType = null, $size = null, $error = null, $test = false) { if (!ini_get('file_uploads')) { throw new FileException(sprintf('Unable to create UploadedFile because "file_uploads" is disabled in your php.ini file (%s)', get_cfg_var('cfg_file_path'))); } $this->originalName = basename($originalName); $this->mimeType = $mimeType ?: 'application/octet-stream'; $this->size = $size; $this->error = $error ?: UPLOAD_ERR_OK; $this->test = (Boolean) $test; parent::__construct($path, UPLOAD_ERR_OK === $this->error); } public function getClientOriginalName() { return $this->originalName; } public function getClientMimeType() { return $this->mimeType; } public function getClientSize() { return $this->size; } public function getError() { return $this->error; } public function isValid() { return $this->error === UPLOAD_ERR_OK; } public function move($directory, $name = null) { if ($this->isValid() && ($this->test || is_uploaded_file($this->getPathname()))) { return parent::move($directory, $name); } throw new FileException(sprintf('The file "%s" has not been uploaded via Http', $this->getPathname())); } static public function getMaxFilesize() { $max = trim(ini_get('upload_max_filesize')); if ('' === $max) { return PHP_INT_MAX; } switch (strtolower(substr($max, -1))) { case 'g': $max *= 1024; case 'm': $max *= 1024; case 'k': $max *= 1024; } return (integer) $max; } } <?php namespace Symfony\Component\HttpFoundation; use Symfony\Component\HttpFoundation\File\UploadedFile; class FileBag extends ParameterBag { static private $fileKeys = array('error', 'name', 'size', 'tmp_name', 'type'); public function __construct(array $parameters = array()) { $this->replace($parameters); } public function replace(array $files = array()) { $this->parameters = array(); $this->add($files); } public function set($key, $value) { if (is_array($value) || $value instanceof UploadedFile) { parent::set($key, $this->convertFileInformation($value)); } else { throw new \InvalidArgumentException('An uploaded file must be an array or an instance of UploadedFile.'); } } public function add(array $files = array()) { foreach ($files as $key => $file) { $this->set($key, $file); } } protected function convertFileInformation($file) { if ($file instanceof UploadedFile) { return $file; } $file = $this->fixPhpFilesArray($file); if (is_array($file)) { $keys = array_keys($file); sort($keys); if ($keys == self::$fileKeys) { if (UPLOAD_ERR_NO_FILE == $file['error']) { $file = null; } else { $file = new UploadedFile($file['tmp_name'], $file['name'], $file['type'], $file['size'], $file['error']); } } else { $file = array_map(array($this, 'convertFileInformation'), $file); } } return $file; } protected function fixPhpFilesArray($data) { if (!is_array($data)) { return $data; } $keys = array_keys($data); sort($keys); if (self::$fileKeys != $keys || !isset($data['name']) || !is_array($data['name'])) { return $data; } $files = $data; foreach (self::$fileKeys as $k) { unset($files[$k]); } foreach (array_keys($data['name']) as $key) { $files[$key] = $this->fixPhpFilesArray(array( 'error' => $data['error'][$key], 'name' => $data['name'][$key], 'type' => $data['type'][$key], 'tmp_name' => $data['tmp_name'][$key], 'size' => $data['size'][$key] )); } return $files; } } <?php namespace Symfony\Component\HttpFoundation; class HeaderBag implements \IteratorAggregate, \Countable { protected $headers; protected $cacheControl; public function __construct(array $headers = array()) { $this->cacheControl = array(); $this->headers = array(); foreach ($headers as $key => $values) { $this->set($key, $values); } } public function __toString() { if (!$this->headers) { return ''; } $max = max(array_map('strlen', array_keys($this->headers))) + 1; $content = ''; ksort($this->headers); foreach ($this->headers as $name => $values) { $name = implode('-', array_map('ucfirst', explode('-', $name))); foreach ($values as $value) { $content .= sprintf("%-{$max}s %s\r\n", $name.':', $value); } } return $content; } public function all() { return $this->headers; } public function keys() { return array_keys($this->headers); } public function replace(array $headers = array()) { $this->headers = array(); $this->add($headers); } public function add(array $headers) { foreach ($headers as $key => $values) { $this->set($key, $values); } } public function get($key, $default = null, $first = true) { $key = strtr(strtolower($key), '_', '-'); if (!array_key_exists($key, $this->headers)) { if (null === $default) { return $first ? null : array(); } return $first ? $default : array($default); } if ($first) { return count($this->headers[$key]) ? $this->headers[$key][0] : $default; } return $this->headers[$key]; } public function set($key, $values, $replace = true) { $key = strtr(strtolower($key), '_', '-'); $values = (array) $values; if (true === $replace || !isset($this->headers[$key])) { $this->headers[$key] = $values; } else { $this->headers[$key] = array_merge($this->headers[$key], $values); } if ('cache-control' === $key) { $this->cacheControl = $this->parseCacheControl($values[0]); } } public function has($key) { return array_key_exists(strtr(strtolower($key), '_', '-'), $this->headers); } public function contains($key, $value) { return in_array($value, $this->get($key, null, false)); } public function remove($key) { $key = strtr(strtolower($key), '_', '-'); unset($this->headers[$key]); if ('cache-control' === $key) { $this->cacheControl = array(); } } public function getDate($key, \DateTime $default = null) { if (null === $value = $this->get($key)) { return $default; } if (false === $date = \DateTime::createFromFormat(DATE_RFC2822, $value)) { throw new \RuntimeException(sprintf('The %s HTTP header is not parseable (%s).', $key, $value)); } return $date; } public function addCacheControlDirective($key, $value = true) { $this->cacheControl[$key] = $value; $this->set('Cache-Control', $this->getCacheControlHeader()); } public function hasCacheControlDirective($key) { return array_key_exists($key, $this->cacheControl); } public function getCacheControlDirective($key) { return array_key_exists($key, $this->cacheControl) ? $this->cacheControl[$key] : null; } public function removeCacheControlDirective($key) { unset($this->cacheControl[$key]); $this->set('Cache-Control', $this->getCacheControlHeader()); } public function getIterator() { return new \ArrayIterator($this->headers); } public function count() { return count($this->headers); } protected function getCacheControlHeader() { $parts = array(); ksort($this->cacheControl); foreach ($this->cacheControl as $key => $value) { if (true === $value) { $parts[] = $key; } else { if (preg_match('#[^a-zA-Z0-9._-]#', $value)) { $value = '"'.$value.'"'; } $parts[] = "$key=$value"; } } return implode(', ', $parts); } protected function parseCacheControl($header) { $cacheControl = array(); preg_match_all('#([a-zA-Z][a-zA-Z_-]*)\s*(?:=(?:"([^"]*)"|([^ \t",;]*)))?#', $header, $matches, PREG_SET_ORDER); foreach ($matches as $match) { $cacheControl[strtolower($match[1])] = isset($match[2]) && $match[2] ? $match[2] : (isset($match[3]) ? $match[3] : true); } return $cacheControl; } } <?php namespace Symfony\Component\HttpFoundation; class JsonResponse extends Response { protected $data; protected $callback; public function __construct($data = array(), $status = 200, $headers = array()) { parent::__construct('', $status, $headers); $this->setData($data); } static public function create($data = array(), $status = 200, $headers = array()) { return new static($data, $status, $headers); } public function setCallback($callback = null) { if ($callback) { $pattern = '/^[$_\p{L}][$_\p{L}\p{Mn}\p{Mc}\p{Nd}\p{Pc}\x{200C}\x{200D}]*+$/u'; if (!preg_match($pattern, $callback)) { throw new \InvalidArgumentException('The callback name is not valid.'); } } $this->callback = $callback; return $this->update(); } public function setData($data = array()) { if (is_array($data) && 0 === count($data)) { $data = new \ArrayObject(); } $this->data = json_encode($data); return $this->update(); } protected function update() { if ($this->callback) { $this->headers->set('Content-Type', 'text/javascript', true); return $this->setContent(sprintf('%s(%s);', $this->callback, $this->data)); } $this->headers->set('Content-Type', 'application/json', false); return $this->setContent($this->data); } } <?php namespace Symfony\Component\HttpFoundation; class ParameterBag implements \IteratorAggregate, \Countable { protected $parameters; public function __construct(array $parameters = array()) { $this->parameters = $parameters; } public function all() { return $this->parameters; } public function keys() { return array_keys($this->parameters); } public function replace(array $parameters = array()) { $this->parameters = $parameters; } public function add(array $parameters = array()) { $this->parameters = array_replace($this->parameters, $parameters); } public function get($path, $default = null, $deep = false) { if (!$deep || false === $pos = strpos($path, '[')) { return array_key_exists($path, $this->parameters) ? $this->parameters[$path] : $default; } $root = substr($path, 0, $pos); if (!array_key_exists($root, $this->parameters)) { return $default; } $value = $this->parameters[$root]; $currentKey = null; for ($i = $pos, $c = strlen($path); $i < $c; $i++) { $char = $path[$i]; if ('[' === $char) { if (null !== $currentKey) { throw new \InvalidArgumentException(sprintf('Malformed path. Unexpected "[" at position %d.', $i)); } $currentKey = ''; } elseif (']' === $char) { if (null === $currentKey) { throw new \InvalidArgumentException(sprintf('Malformed path. Unexpected "]" at position %d.', $i)); } if (!is_array($value) || !array_key_exists($currentKey, $value)) { return $default; } $value = $value[$currentKey]; $currentKey = null; } else { if (null === $currentKey) { throw new \InvalidArgumentException(sprintf('Malformed path. Unexpected "%s" at position %d.', $char, $i)); } $currentKey .= $char; } } if (null !== $currentKey) { throw new \InvalidArgumentException(sprintf('Malformed path. Path must end with "]".')); } return $value; } public function set($key, $value) { $this->parameters[$key] = $value; } public function has($key) { return array_key_exists($key, $this->parameters); } public function remove($key) { unset($this->parameters[$key]); } public function getAlpha($key, $default = '', $deep = false) { return preg_replace('/[^[:alpha:]]/', '', $this->get($key, $default, $deep)); } public function getAlnum($key, $default = '', $deep = false) { return preg_replace('/[^[:alnum:]]/', '', $this->get($key, $default, $deep)); } public function getDigits($key, $default = '', $deep = false) { return str_replace(array('-', '+'), '', $this->filter($key, $default, $deep, FILTER_SANITIZE_NUMBER_INT)); } public function getInt($key, $default = 0, $deep = false) { return (int) $this->get($key, $default, $deep); } public function filter($key, $default = null, $deep = false, $filter=FILTER_DEFAULT, $options=array()) { $value = $this->get($key, $default, $deep); if (!is_array($options) && $options) { $options = array('flags' => $options); } if (is_array($value) && !isset($options['flags'])) { $options['flags'] = FILTER_REQUIRE_ARRAY; } return filter_var($value, $filter, $options); } public function getIterator() { return new \ArrayIterator($this->parameters); } public function count() { return count($this->parameters); } } <?php namespace Symfony\Component\HttpFoundation; class RedirectResponse extends Response { protected $targetUrl; public function __construct($url, $status = 302, $headers = array()) { if (empty($url)) { throw new \InvalidArgumentException('Cannot redirect to an empty URL.'); } $this->targetUrl = $url; parent::__construct( sprintf('<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <meta http-equiv="refresh" content="1;url=%1$s" /> <title>Redirecting to %1$s</title> </head> <body> Redirecting to <a href="%1$s">%1$s</a>. </body> </html>', htmlspecialchars($url, ENT_QUOTES, 'UTF-8')), $status, array_merge($headers, array('Location' => $url)) ); if (!$this->isRedirect()) { throw new \InvalidArgumentException(sprintf('The HTTP status code is not a redirect ("%s" given).', $status)); } } static public function create($url = '', $status = 302, $headers = array()) { return new static($url, $status, $headers); } public function getTargetUrl() { return $this->targetUrl; } } <?php namespace Symfony\Component\HttpFoundation; use Symfony\Component\HttpFoundation\Session\SessionInterface; class Request { static protected $trustProxy = false; public $attributes; public $request; public $query; public $server; public $files; public $cookies; public $headers; protected $content; protected $languages; protected $charsets; protected $acceptableContentTypes; protected $pathInfo; protected $requestUri; protected $baseUrl; protected $basePath; protected $method; protected $format; protected $session; protected $locale; protected $defaultLocale = 'en'; static protected $formats; public function __construct(array $query = array(), array $request = array(), array $attributes = array(), array $cookies = array(), array $files = array(), array $server = array(), $content = null) { $this->initialize($query, $request, $attributes, $cookies, $files, $server, $content); } public function initialize(array $query = array(), array $request = array(), array $attributes = array(), array $cookies = array(), array $files = array(), array $server = array(), $content = null) { $this->request = new ParameterBag($request); $this->query = new ParameterBag($query); $this->attributes = new ParameterBag($attributes); $this->cookies = new ParameterBag($cookies); $this->files = new FileBag($files); $this->server = new ServerBag($server); $this->headers = new HeaderBag($this->server->getHeaders()); $this->content = $content; $this->languages = null; $this->charsets = null; $this->acceptableContentTypes = null; $this->pathInfo = null; $this->requestUri = null; $this->baseUrl = null; $this->basePath = null; $this->method = null; $this->format = null; } static public function createFromGlobals() { $request = new static($_GET, $_POST, array(), $_COOKIE, $_FILES, $_SERVER); if (0 === strpos($request->server->get('CONTENT_TYPE'), 'application/x-www-form-urlencoded') && in_array(strtoupper($request->server->get('REQUEST_METHOD', 'GET')), array('PUT', 'DELETE', 'PATCH')) ) { parse_str($request->getContent(), $data); $request->request = new ParameterBag($data); } return $request; } static public function create($uri, $method = 'GET', $parameters = array(), $cookies = array(), $files = array(), $server = array(), $content = null) { $defaults = array( 'SERVER_NAME' => 'localhost', 'SERVER_PORT' => 80, 'HTTP_HOST' => 'localhost', 'HTTP_USER_AGENT' => 'Symfony/2.X', 'HTTP_ACCEPT' => 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8', 'HTTP_ACCEPT_LANGUAGE' => 'en-us,en;q=0.5', 'HTTP_ACCEPT_CHARSET' => 'ISO-8859-1,utf-8;q=0.7,*;q=0.7', 'REMOTE_ADDR' => '127.0.0.1', 'SCRIPT_NAME' => '', 'SCRIPT_FILENAME' => '', 'SERVER_PROTOCOL' => 'HTTP/1.1', 'REQUEST_TIME' => time(), ); $components = parse_url($uri); if (isset($components['host'])) { $defaults['SERVER_NAME'] = $components['host']; $defaults['HTTP_HOST'] = $components['host']; } if (isset($components['scheme'])) { if ('https' === $components['scheme']) { $defaults['HTTPS'] = 'on'; $defaults['SERVER_PORT'] = 443; } } if (isset($components['port'])) { $defaults['SERVER_PORT'] = $components['port']; $defaults['HTTP_HOST'] = $defaults['HTTP_HOST'].':'.$components['port']; } if (isset($components['user'])) { $defaults['PHP_AUTH_USER'] = $components['user']; } if (isset($components['pass'])) { $defaults['PHP_AUTH_PW'] = $components['pass']; } if (!isset($components['path'])) { $components['path'] = ''; } switch (strtoupper($method)) { case 'POST': case 'PUT': case 'DELETE': $defaults['CONTENT_TYPE'] = 'application/x-www-form-urlencoded'; case 'PATCH': $request = $parameters; $query = array(); break; default: $request = array(); $query = $parameters; break; } if (isset($components['query'])) { $queryString = html_entity_decode($components['query']); parse_str($queryString, $qs); if (is_array($qs)) { $query = array_replace($qs, $query); } } $queryString = http_build_query($query); $uri = $components['path'].($queryString ? '?'.$queryString : ''); $server = array_replace($defaults, $server, array( 'REQUEST_METHOD' => strtoupper($method), 'PATH_INFO' => '', 'REQUEST_URI' => $uri, 'QUERY_STRING' => $queryString, )); return new static($query, $request, array(), $cookies, $files, $server, $content); } public function duplicate(array $query = null, array $request = null, array $attributes = null, array $cookies = null, array $files = null, array $server = null) { $dup = clone $this; if ($query !== null) { $dup->query = new ParameterBag($query); } if ($request !== null) { $dup->request = new ParameterBag($request); } if ($attributes !== null) { $dup->attributes = new ParameterBag($attributes); } if ($cookies !== null) { $dup->cookies = new ParameterBag($cookies); } if ($files !== null) { $dup->files = new FileBag($files); } if ($server !== null) { $dup->server = new ServerBag($server); $dup->headers = new HeaderBag($dup->server->getHeaders()); } $dup->languages = null; $dup->charsets = null; $dup->acceptableContentTypes = null; $dup->pathInfo = null; $dup->requestUri = null; $dup->baseUrl = null; $dup->basePath = null; $dup->method = null; $dup->format = null; return $dup; } public function __clone() { $this->query = clone $this->query; $this->request = clone $this->request; $this->attributes = clone $this->attributes; $this->cookies = clone $this->cookies; $this->files = clone $this->files; $this->server = clone $this->server; $this->headers = clone $this->headers; } public function __toString() { return sprintf('%s %s %s', $this->getMethod(), $this->getRequestUri(), $this->server->get('SERVER_PROTOCOL'))."\r\n". $this->headers."\r\n". $this->getContent(); } public function overrideGlobals() { $_GET = $this->query->all(); $_POST = $this->request->all(); $_SERVER = $this->server->all(); $_COOKIE = $this->cookies->all(); foreach ($this->headers->all() as $key => $value) { $key = strtoupper(str_replace('-', '_', $key)); if (in_array($key, array('CONTENT_TYPE', 'CONTENT_LENGTH'))) { $_SERVER[$key] = implode(', ', $value); } else { $_SERVER['HTTP_'.$key] = implode(', ', $value); } } $_REQUEST = array_merge($_GET, $_POST); } static public function trustProxyData() { self::$trustProxy = true; } static public function isProxyTrusted() { return self::$trustProxy; } public function get($key, $default = null, $deep = false) { return $this->query->get($key, $this->attributes->get($key, $this->request->get($key, $default, $deep), $deep), $deep); } public function getSession() { return $this->session; } public function hasPreviousSession() { $sessionName = $this->hasSession() ? $this->session->getName() : null; return $this->cookies->has($sessionName) && $this->hasSession(); } public function hasSession() { return null !== $this->session; } public function setSession(SessionInterface $session) { $this->session = $session; } public function getClientIp() { if (self::$trustProxy) { if ($this->server->has('HTTP_CLIENT_IP')) { return $this->server->get('HTTP_CLIENT_IP'); } elseif ($this->server->has('HTTP_X_FORWARDED_FOR')) { $clientIp = explode(',', $this->server->get('HTTP_X_FORWARDED_FOR'), 2); return isset($clientIp[0]) ? trim($clientIp[0]) : ''; } } return $this->server->get('REMOTE_ADDR'); } public function getScriptName() { return $this->server->get('SCRIPT_NAME', $this->server->get('ORIG_SCRIPT_NAME', '')); } public function getPathInfo() { if (null === $this->pathInfo) { $this->pathInfo = $this->preparePathInfo(); } return $this->pathInfo; } public function getBasePath() { if (null === $this->basePath) { $this->basePath = $this->prepareBasePath(); } return $this->basePath; } public function getBaseUrl() { if (null === $this->baseUrl) { $this->baseUrl = $this->prepareBaseUrl(); } return $this->baseUrl; } public function getScheme() { return $this->isSecure() ? 'https' : 'http'; } public function getPort() { if (self::$trustProxy && $this->headers->has('X-Forwarded-Port')) { return $this->headers->get('X-Forwarded-Port'); } return $this->server->get('SERVER_PORT'); } public function getUser() { return $this->server->get('PHP_AUTH_USER'); } public function getPassword() { return $this->server->get('PHP_AUTH_PW'); } public function getHttpHost() { $scheme = $this->getScheme(); $port = $this->getPort(); if (('http' == $scheme && $port == 80) || ('https' == $scheme && $port == 443)) { return $this->getHost(); } return $this->getHost().':'.$port; } public function getRequestUri() { if (null === $this->requestUri) { $this->requestUri = $this->prepareRequestUri(); } return $this->requestUri; } public function getUri() { $qs = $this->getQueryString(); if (null !== $qs) { $qs = '?'.$qs; } $auth = ''; if ($user = $this->getUser()) { $auth = $user; } if ($pass = $this->getPassword()) { $auth .= ":$pass"; } if ('' !== $auth) { $auth .= '@'; } return $this->getScheme().'://'.$auth.$this->getHttpHost().$this->getBaseUrl().$this->getPathInfo().$qs; } public function getUriForPath($path) { return $this->getScheme().'://'.$this->getHttpHost().$this->getBaseUrl().$path; } public function getQueryString() { if (!$qs = $this->server->get('QUERY_STRING')) { return null; } $parts = array(); $order = array(); foreach (explode('&', $qs) as $segment) { if (false === strpos($segment, '=')) { $parts[] = $segment; $order[] = $segment; } else { $tmp = explode('=', rawurldecode($segment), 2); $parts[] = rawurlencode($tmp[0]).'='.rawurlencode($tmp[1]); $order[] = $tmp[0]; } } array_multisort($order, SORT_ASC, $parts); return implode('&', $parts); } public function isSecure() { return ( (strtolower($this->server->get('HTTPS')) == 'on' || $this->server->get('HTTPS') == 1) || (self::$trustProxy && strtolower($this->headers->get('SSL_HTTPS')) == 'on' || $this->headers->get('SSL_HTTPS') == 1) || (self::$trustProxy && strtolower($this->headers->get('X_FORWARDED_PROTO')) == 'https') ); } public function getHost() { if (self::$trustProxy && $host = $this->headers->get('X_FORWARDED_HOST')) { $elements = explode(',', $host); $host = trim($elements[count($elements) - 1]); } else { if (!$host = $this->headers->get('HOST')) { if (!$host = $this->server->get('SERVER_NAME')) { $host = $this->server->get('SERVER_ADDR', ''); } } } $host = preg_replace('/:\d+$/', '', $host); return trim(strtolower($host)); } public function setMethod($method) { $this->method = null; $this->server->set('REQUEST_METHOD', $method); } public function getMethod() { if (null === $this->method) { $this->method = strtoupper($this->server->get('REQUEST_METHOD', 'GET')); if ('POST' === $this->method) { $this->method = strtoupper($this->headers->get('X-HTTP-METHOD-OVERRIDE', $this->request->get('_method', 'POST'))); } } return $this->method; } public function getMimeType($format) { if (null === static::$formats) { static::initializeFormats(); } return isset(static::$formats[$format]) ? static::$formats[$format][0] : null; } public function getFormat($mimeType) { if (false !== $pos = strpos($mimeType, ';')) { $mimeType = substr($mimeType, 0, $pos); } if (null === static::$formats) { static::initializeFormats(); } foreach (static::$formats as $format => $mimeTypes) { if (in_array($mimeType, (array) $mimeTypes)) { return $format; } } return null; } public function setFormat($format, $mimeTypes) { if (null === static::$formats) { static::initializeFormats(); } static::$formats[$format] = is_array($mimeTypes) ? $mimeTypes : array($mimeTypes); } public function getRequestFormat($default = 'html') { if (null === $this->format) { $this->format = $this->get('_format', $default); } return $this->format; } public function setRequestFormat($format) { $this->format = $format; } public function getContentType() { return $this->getFormat($this->server->get('CONTENT_TYPE')); } public function setDefaultLocale($locale) { $this->setPhpDefaultLocale($this->defaultLocale = $locale); } public function setLocale($locale) { $this->setPhpDefaultLocale($this->locale = $locale); } public function getLocale() { return null === $this->locale ? $this->defaultLocale : $this->locale; } public function isMethod($method) { return $this->getMethod() === strtoupper($method); } public function isMethodSafe() { return in_array($this->getMethod(), array('GET', 'HEAD')); } public function getContent($asResource = false) { if (false === $this->content || (true === $asResource && null !== $this->content)) { throw new \LogicException('getContent() can only be called once when using the resource return type.'); } if (true === $asResource) { $this->content = false; return fopen('php://input', 'rb'); } if (null === $this->content) { $this->content = file_get_contents('php://input'); } return $this->content; } public function getETags() { return preg_split('/\s*,\s*/', $this->headers->get('if_none_match'), null, PREG_SPLIT_NO_EMPTY); } public function isNoCache() { return $this->headers->hasCacheControlDirective('no-cache') || 'no-cache' == $this->headers->get('Pragma'); } public function getPreferredLanguage(array $locales = null) { $preferredLanguages = $this->getLanguages(); if (empty($locales)) { return isset($preferredLanguages[0]) ? $preferredLanguages[0] : null; } if (!$preferredLanguages) { return $locales[0]; } $preferredLanguages = array_values(array_intersect($preferredLanguages, $locales)); return isset($preferredLanguages[0]) ? $preferredLanguages[0] : $locales[0]; } public function getLanguages() { if (null !== $this->languages) { return $this->languages; } $languages = $this->splitHttpAcceptHeader($this->headers->get('Accept-Language')); $this->languages = array(); foreach ($languages as $lang => $q) { if (strstr($lang, '-')) { $codes = explode('-', $lang); if ($codes[0] == 'i') { if (count($codes) > 1) { $lang = $codes[1]; } } else { for ($i = 0, $max = count($codes); $i < $max; $i++) { if ($i == 0) { $lang = strtolower($codes[0]); } else { $lang .= '_'.strtoupper($codes[$i]); } } } } $this->languages[] = $lang; } return $this->languages; } public function getCharsets() { if (null !== $this->charsets) { return $this->charsets; } return $this->charsets = array_keys($this->splitHttpAcceptHeader($this->headers->get('Accept-Charset'))); } public function getAcceptableContentTypes() { if (null !== $this->acceptableContentTypes) { return $this->acceptableContentTypes; } return $this->acceptableContentTypes = array_keys($this->splitHttpAcceptHeader($this->headers->get('Accept'))); } public function isXmlHttpRequest() { return 'XMLHttpRequest' == $this->headers->get('X-Requested-With'); } public function splitHttpAcceptHeader($header) { if (!$header) { return array(); } $values = array(); foreach (array_filter(explode(',', $header)) as $value) { if (preg_match('/;\s*(q=.*$)/', $value, $match)) { $q = (float) substr(trim($match[1]), 2); $value = trim(substr($value, 0, -strlen($match[0]))); } else { $q = 1; } if (0 < $q) { $values[trim($value)] = $q; } } arsort($values); reset($values); return $values; } protected function prepareRequestUri() { $requestUri = ''; if ($this->headers->has('X_REWRITE_URL') && false !== stripos(PHP_OS, 'WIN')) { $requestUri = $this->headers->get('X_REWRITE_URL'); } elseif ($this->server->get('IIS_WasUrlRewritten') == '1' && $this->server->get('UNENCODED_URL') != '') { $requestUri = $this->server->get('UNENCODED_URL'); } elseif ($this->server->has('REQUEST_URI')) { $requestUri = $this->server->get('REQUEST_URI'); $schemeAndHttpHost = $this->getScheme().'://'.$this->getHttpHost(); if (strpos($requestUri, $schemeAndHttpHost) === 0) { $requestUri = substr($requestUri, strlen($schemeAndHttpHost)); } } elseif ($this->server->has('ORIG_PATH_INFO')) { $requestUri = $this->server->get('ORIG_PATH_INFO'); if ($this->server->get('QUERY_STRING')) { $requestUri .= '?'.$this->server->get('QUERY_STRING'); } } return $requestUri; } protected function prepareBaseUrl() { $filename = basename($this->server->get('SCRIPT_FILENAME')); if (basename($this->server->get('SCRIPT_NAME')) === $filename) { $baseUrl = $this->server->get('SCRIPT_NAME'); } elseif (basename($this->server->get('PHP_SELF')) === $filename) { $baseUrl = $this->server->get('PHP_SELF'); } elseif (basename($this->server->get('ORIG_SCRIPT_NAME')) === $filename) { $baseUrl = $this->server->get('ORIG_SCRIPT_NAME'); } else { $path = $this->server->get('PHP_SELF', ''); $file = $this->server->get('SCRIPT_FILENAME', ''); $segs = explode('/', trim($file, '/')); $segs = array_reverse($segs); $index = 0; $last = count($segs); $baseUrl = ''; do { $seg = $segs[$index]; $baseUrl = '/'.$seg.$baseUrl; ++$index; } while (($last > $index) && (false !== ($pos = strpos($path, $baseUrl))) && (0 != $pos)); } $requestUri = $this->getRequestUri(); if ($baseUrl && false !== $prefix = $this->getUrlencodedPrefix($requestUri, $baseUrl)) { return $prefix; } if ($baseUrl && false !== $prefix = $this->getUrlencodedPrefix($requestUri, dirname($baseUrl))) { return rtrim($prefix, '/'); } $truncatedRequestUri = $requestUri; if (($pos = strpos($requestUri, '?')) !== false) { $truncatedRequestUri = substr($requestUri, 0, $pos); } $basename = basename($baseUrl); if (empty($basename) || !strpos(rawurldecode($truncatedRequestUri), $basename)) { return ''; } if ((strlen($requestUri) >= strlen($baseUrl)) && ((false !== ($pos = strpos($requestUri, $baseUrl))) && ($pos !== 0))) { $baseUrl = substr($requestUri, 0, $pos + strlen($baseUrl)); } return rtrim($baseUrl, '/'); } protected function prepareBasePath() { $filename = basename($this->server->get('SCRIPT_FILENAME')); $baseUrl = $this->getBaseUrl(); if (empty($baseUrl)) { return ''; } if (basename($baseUrl) === $filename) { $basePath = dirname($baseUrl); } else { $basePath = $baseUrl; } if ('\\' === DIRECTORY_SEPARATOR) { $basePath = str_replace('\\', '/', $basePath); } return rtrim($basePath, '/'); } protected function preparePathInfo() { $baseUrl = $this->getBaseUrl(); if (null === ($requestUri = $this->getRequestUri())) { return '/'; } $pathInfo = '/'; if ($pos = strpos($requestUri, '?')) { $requestUri = substr($requestUri, 0, $pos); } if ((null !== $baseUrl) && (false === ($pathInfo = substr($requestUri, strlen($baseUrl))))) { return '/'; } elseif (null === $baseUrl) { return $requestUri; } return (string) $pathInfo; } static protected function initializeFormats() { static::$formats = array( 'html' => array('text/html', 'application/xhtml+xml'), 'txt' => array('text/plain'), 'js' => array('application/javascript', 'application/x-javascript', 'text/javascript'), 'css' => array('text/css'), 'json' => array('application/json', 'application/x-json'), 'xml' => array('text/xml', 'application/xml', 'application/x-xml'), 'rdf' => array('application/rdf+xml'), 'atom' => array('application/atom+xml'), 'rss' => array('application/rss+xml'), ); } private function setPhpDefaultLocale($locale) { try { if (class_exists('Locale', false)) { \Locale::setDefault($locale); } } catch (\Exception $e) { } } private function getUrlencodedPrefix($string, $prefix) { if (0 !== strpos(rawurldecode($string), $prefix)) { return false; } $len = strlen($prefix); if (preg_match("#^(%[[:xdigit:]]{2}|.){{$len}}#", $string, $match)) { return $match[0]; } return false; } } <?php namespace Symfony\Component\HttpFoundation; class RequestMatcher implements RequestMatcherInterface { private $path; private $host; private $methods; private $ip; private $attributes; public function __construct($path = null, $host = null, $methods = null, $ip = null, array $attributes = array()) { $this->path = $path; $this->host = $host; $this->methods = $methods; $this->ip = $ip; $this->attributes = $attributes; } public function matchHost($regexp) { $this->host = $regexp; } public function matchPath($regexp) { $this->path = $regexp; } public function matchIp($ip) { $this->ip = $ip; } public function matchMethod($method) { $this->methods = array_map('strtoupper', is_array($method) ? $method : array($method)); } public function matchAttribute($key, $regexp) { $this->attributes[$key] = $regexp; } public function matches(Request $request) { if (null !== $this->methods && !in_array($request->getMethod(), $this->methods)) { return false; } foreach ($this->attributes as $key => $pattern) { if (!preg_match('#'.str_replace('#', '\\#', $pattern).'#', $request->attributes->get($key))) { return false; } } if (null !== $this->path) { $path = str_replace('#', '\\#', $this->path); if (!preg_match('#'.$path.'#', rawurldecode($request->getPathInfo()))) { return false; } } if (null !== $this->host && !preg_match('#'.str_replace('#', '\\#', $this->host).'#', $request->getHost())) { return false; } if (null !== $this->ip && !$this->checkIp($request->getClientIp(), $this->ip)) { return false; } return true; } protected function checkIp($requestIp, $ip) { if (false !== strpos($requestIp, ':')) { return $this->checkIp6($requestIp, $ip); } else { return $this->checkIp4($requestIp, $ip); } } protected function checkIp4($requestIp, $ip) { if (false !== strpos($ip, '/')) { list($address, $netmask) = explode('/', $ip, 2); if ($netmask < 1 || $netmask > 32) { return false; } } else { $address = $ip; $netmask = 32; } return 0 === substr_compare(sprintf('%032b', ip2long($requestIp)), sprintf('%032b', ip2long($address)), 0, $netmask); } protected function checkIp6($requestIp, $ip) { if (!defined('AF_INET6')) { throw new \RuntimeException('Unable to check Ipv6. Check that PHP was not compiled with option "disable-ipv6".'); } list($address, $netmask) = explode('/', $ip, 2); $bytesAddr = unpack("n*", inet_pton($address)); $bytesTest = unpack("n*", inet_pton($requestIp)); for ($i = 1, $ceil = ceil($netmask / 16); $i <= $ceil; $i++) { $left = $netmask - 16 * ($i-1); $left = ($left <= 16) ? $left : 16; $mask = ~(0xffff >> $left) & 0xffff; if (($bytesAddr[$i] & $mask) != ($bytesTest[$i] & $mask)) { return false; } } return true; } } <?php namespace Symfony\Component\HttpFoundation; interface RequestMatcherInterface { function matches(Request $request); } <?php interface SessionHandlerInterface { function open($savePath, $sessionName); function close(); function read($sessionId); function write($sessionId, $data); function destroy($sessionId); function gc($lifetime); } <?php namespace Symfony\Component\HttpFoundation; class Response { public $headers; protected $content; protected $version; protected $statusCode; protected $statusText; protected $charset; static public $statusTexts = array( 100 => 'Continue', 101 => 'Switching Protocols', 102 => 'Processing', 200 => 'OK', 201 => 'Created', 202 => 'Accepted', 203 => 'Non-Authoritative Information', 204 => 'No Content', 205 => 'Reset Content', 206 => 'Partial Content', 207 => 'Multi-Status', 208 => 'Already Reported', 226 => 'IM Used', 300 => 'Multiple Choices', 301 => 'Moved Permanently', 302 => 'Found', 303 => 'See Other', 304 => 'Not Modified', 305 => 'Use Proxy', 306 => 'Reserved', 307 => 'Temporary Redirect', 308 => 'Permanent Redirect', 400 => 'Bad Request', 401 => 'Unauthorized', 402 => 'Payment Required', 403 => 'Forbidden', 404 => 'Not Found', 405 => 'Method Not Allowed', 406 => 'Not Acceptable', 407 => 'Proxy Authentication Required', 408 => 'Request Timeout', 409 => 'Conflict', 410 => 'Gone', 411 => 'Length Required', 412 => 'Precondition Failed', 413 => 'Request Entity Too Large', 414 => 'Request-URI Too Long', 415 => 'Unsupported Media Type', 416 => 'Requested Range Not Satisfiable', 417 => 'Expectation Failed', 418 => 'I\'m a teapot', 422 => 'Unprocessable Entity', 423 => 'Locked', 424 => 'Failed Dependency', 425 => 'Reserved for WebDAV advanced collections expired proposal', 426 => 'Upgrade Required', 428 => 'Precondition Required', 429 => 'Too Many Requests', 431 => 'Request Header Fields Too Large', 500 => 'Internal Server Error', 501 => 'Not Implemented', 502 => 'Bad Gateway', 503 => 'Service Unavailable', 504 => 'Gateway Timeout', 505 => 'HTTP Version Not Supported', 506 => 'Variant Also Negotiates (Experimental)', 507 => 'Insufficient Storage', 508 => 'Loop Detected', 510 => 'Not Extended', 511 => 'Network Authentication Required', ); public function __construct($content = '', $status = 200, $headers = array()) { $this->headers = new ResponseHeaderBag($headers); $this->setContent($content); $this->setStatusCode($status); $this->setProtocolVersion('1.0'); if (!$this->headers->has('Date')) { $this->setDate(new \DateTime(null, new \DateTimeZone('UTC'))); } } static public function create($content = '', $status = 200, $headers = array()) { return new static($content, $status, $headers); } public function __toString() { return sprintf('HTTP/%s %s %s', $this->version, $this->statusCode, $this->statusText)."\r\n". $this->headers."\r\n". $this->getContent(); } public function __clone() { $this->headers = clone $this->headers; } public function prepare(Request $request) { $headers = $this->headers; if ($this->isInformational() || in_array($this->statusCode, array(204, 304))) { $this->setContent(''); } if (!$headers->has('Content-Type')) { $format = $request->getRequestFormat(); if (null !== $format && $mimeType = $request->getMimeType($format)) { $headers->set('Content-Type', $mimeType); } } $charset = $this->charset ?: 'UTF-8'; if (!$headers->has('Content-Type')) { $headers->set('Content-Type', 'text/html; charset='.$charset); } elseif (0 === strpos($headers->get('Content-Type'), 'text/') && false === strpos($headers->get('Content-Type'), 'charset')) { $headers->set('Content-Type', $headers->get('Content-Type').'; charset='.$charset); } if ($headers->has('Transfer-Encoding')) { $headers->remove('Content-Length'); } if ('HEAD' === $request->getMethod()) { $length = $headers->get('Content-Length'); $this->setContent(''); if ($length) { $headers->set('Content-Length', $length); } } return $this; } public function sendHeaders() { if (headers_sent()) { return $this; } header(sprintf('HTTP/%s %s %s', $this->version, $this->statusCode, $this->statusText)); foreach ($this->headers->all() as $name => $values) { foreach ($values as $value) { header($name.': '.$value, false); } } foreach ($this->headers->getCookies() as $cookie) { setcookie($cookie->getName(), $cookie->getValue(), $cookie->getExpiresTime(), $cookie->getPath(), $cookie->getDomain(), $cookie->isSecure(), $cookie->isHttpOnly()); } return $this; } public function sendContent() { echo $this->content; return $this; } public function send() { $this->sendHeaders(); $this->sendContent(); if (function_exists('fastcgi_finish_request')) { fastcgi_finish_request(); } return $this; } public function setContent($content) { if (null !== $content && !is_string($content) && !is_numeric($content) && !is_callable(array($content, '__toString'))) { throw new \UnexpectedValueException('The Response content must be a string or object implementing __toString(), "'.gettype($content).'" given.'); } $this->content = (string) $content; return $this; } public function getContent() { return $this->content; } public function setProtocolVersion($version) { $this->version = $version; return $this; } public function getProtocolVersion() { return $this->version; } public function setStatusCode($code, $text = null) { $this->statusCode = (int) $code; if ($this->isInvalid()) { throw new \InvalidArgumentException(sprintf('The HTTP status code "%s" is not valid.', $code)); } $this->statusText = false === $text ? '' : (null === $text ? self::$statusTexts[$this->statusCode] : $text); return $this; } public function getStatusCode() { return $this->statusCode; } public function setCharset($charset) { $this->charset = $charset; return $this; } public function getCharset() { return $this->charset; } public function isCacheable() { if (!in_array($this->statusCode, array(200, 203, 300, 301, 302, 404, 410))) { return false; } if ($this->headers->hasCacheControlDirective('no-store') || $this->headers->getCacheControlDirective('private')) { return false; } return $this->isValidateable() || $this->isFresh(); } public function isFresh() { return $this->getTtl() > 0; } public function isValidateable() { return $this->headers->has('Last-Modified') || $this->headers->has('ETag'); } public function setPrivate() { $this->headers->removeCacheControlDirective('public'); $this->headers->addCacheControlDirective('private'); return $this; } public function setPublic() { $this->headers->addCacheControlDirective('public'); $this->headers->removeCacheControlDirective('private'); return $this; } public function mustRevalidate() { return $this->headers->hasCacheControlDirective('must-revalidate') || $this->headers->has('must-proxy-revalidate'); } public function getDate() { return $this->headers->getDate('Date'); } public function setDate(\DateTime $date) { $date->setTimezone(new \DateTimeZone('UTC')); $this->headers->set('Date', $date->format('D, d M Y H:i:s').' GMT'); return $this; } public function getAge() { if ($age = $this->headers->get('Age')) { return $age; } return max(time() - $this->getDate()->format('U'), 0); } public function expire() { if ($this->isFresh()) { $this->headers->set('Age', $this->getMaxAge()); } return $this; } public function getExpires() { return $this->headers->getDate('Expires'); } public function setExpires(\DateTime $date = null) { if (null === $date) { $this->headers->remove('Expires'); } else { $date = clone $date; $date->setTimezone(new \DateTimeZone('UTC')); $this->headers->set('Expires', $date->format('D, d M Y H:i:s').' GMT'); } return $this; } public function getMaxAge() { if ($age = $this->headers->getCacheControlDirective('s-maxage')) { return $age; } if ($age = $this->headers->getCacheControlDirective('max-age')) { return $age; } if (null !== $this->getExpires()) { return $this->getExpires()->format('U') - $this->getDate()->format('U'); } return null; } public function setMaxAge($value) { $this->headers->addCacheControlDirective('max-age', $value); return $this; } public function setSharedMaxAge($value) { $this->setPublic(); $this->headers->addCacheControlDirective('s-maxage', $value); return $this; } public function getTtl() { if ($maxAge = $this->getMaxAge()) { return $maxAge - $this->getAge(); } return null; } public function setTtl($seconds) { $this->setSharedMaxAge($this->getAge() + $seconds); return $this; } public function setClientTtl($seconds) { $this->setMaxAge($this->getAge() + $seconds); return $this; } public function getLastModified() { return $this->headers->getDate('Last-Modified'); } public function setLastModified(\DateTime $date = null) { if (null === $date) { $this->headers->remove('Last-Modified'); } else { $date = clone $date; $date->setTimezone(new \DateTimeZone('UTC')); $this->headers->set('Last-Modified', $date->format('D, d M Y H:i:s').' GMT'); } return $this; } public function getEtag() { return $this->headers->get('ETag'); } public function setEtag($etag = null, $weak = false) { if (null === $etag) { $this->headers->remove('Etag'); } else { if (0 !== strpos($etag, '"')) { $etag = '"'.$etag.'"'; } $this->headers->set('ETag', (true === $weak ? 'W/' : '').$etag); } return $this; } public function setCache(array $options) { if ($diff = array_diff(array_keys($options), array('etag', 'last_modified', 'max_age', 's_maxage', 'private', 'public'))) { throw new \InvalidArgumentException(sprintf('Response does not support the following options: "%s".', implode('", "', array_values($diff)))); } if (isset($options['etag'])) { $this->setEtag($options['etag']); } if (isset($options['last_modified'])) { $this->setLastModified($options['last_modified']); } if (isset($options['max_age'])) { $this->setMaxAge($options['max_age']); } if (isset($options['s_maxage'])) { $this->setSharedMaxAge($options['s_maxage']); } if (isset($options['public'])) { if ($options['public']) { $this->setPublic(); } else { $this->setPrivate(); } } if (isset($options['private'])) { if ($options['private']) { $this->setPrivate(); } else { $this->setPublic(); } } return $this; } public function setNotModified() { $this->setStatusCode(304); $this->setContent(null); foreach (array('Allow', 'Content-Encoding', 'Content-Language', 'Content-Length', 'Content-MD5', 'Content-Type', 'Last-Modified') as $header) { $this->headers->remove($header); } return $this; } public function hasVary() { return (Boolean) $this->headers->get('Vary'); } public function getVary() { if (!$vary = $this->headers->get('Vary')) { return array(); } return is_array($vary) ? $vary : preg_split('/[\s,]+/', $vary); } public function setVary($headers, $replace = true) { $this->headers->set('Vary', $headers, $replace); return $this; } public function isNotModified(Request $request) { $lastModified = $request->headers->get('If-Modified-Since'); $notModified = false; if ($etags = $request->getEtags()) { $notModified = (in_array($this->getEtag(), $etags) || in_array('*', $etags)) && (!$lastModified || $this->headers->get('Last-Modified') == $lastModified); } elseif ($lastModified) { $notModified = $lastModified == $this->headers->get('Last-Modified'); } if ($notModified) { $this->setNotModified(); } return $notModified; } public function isInvalid() { return $this->statusCode < 100 || $this->statusCode >= 600; } public function isInformational() { return $this->statusCode >= 100 && $this->statusCode < 200; } public function isSuccessful() { return $this->statusCode >= 200 && $this->statusCode < 300; } public function isRedirection() { return $this->statusCode >= 300 && $this->statusCode < 400; } public function isClientError() { return $this->statusCode >= 400 && $this->statusCode < 500; } public function isServerError() { return $this->statusCode >= 500 && $this->statusCode < 600; } public function isOk() { return 200 === $this->statusCode; } public function isForbidden() { return 403 === $this->statusCode; } public function isNotFound() { return 404 === $this->statusCode; } public function isRedirect($location = null) { return in_array($this->statusCode, array(201, 301, 302, 303, 307)) && (null === $location ?: $location == $this->headers->get('Location')); } public function isEmpty() { return in_array($this->statusCode, array(201, 204, 304)); } } <?php namespace Symfony\Component\HttpFoundation; class ResponseHeaderBag extends HeaderBag { const COOKIES_FLAT = 'flat'; const COOKIES_ARRAY = 'array'; const DISPOSITION_ATTACHMENT = 'attachment'; const DISPOSITION_INLINE = 'inline'; protected $computedCacheControl = array(); protected $cookies = array(); public function __construct(array $headers = array()) { parent::__construct($headers); if (!isset($this->headers['cache-control'])) { $this->set('cache-control', ''); } } public function __toString() { $cookies = ''; foreach ($this->getCookies() as $cookie) { $cookies .= 'Set-Cookie: '.$cookie."\r\n"; } return parent::__toString().$cookies; } public function replace(array $headers = array()) { parent::replace($headers); if (!isset($this->headers['cache-control'])) { $this->set('cache-control', ''); } } public function set($key, $values, $replace = true) { parent::set($key, $values, $replace); if (in_array(strtr(strtolower($key), '_', '-'), array('cache-control', 'etag', 'last-modified', 'expires'))) { $computed = $this->computeCacheControlValue(); $this->headers['cache-control'] = array($computed); $this->computedCacheControl = $this->parseCacheControl($computed); } } public function remove($key) { parent::remove($key); if ('cache-control' === strtr(strtolower($key), '_', '-')) { $this->computedCacheControl = array(); } } public function hasCacheControlDirective($key) { return array_key_exists($key, $this->computedCacheControl); } public function getCacheControlDirective($key) { return array_key_exists($key, $this->computedCacheControl) ? $this->computedCacheControl[$key] : null; } public function setCookie(Cookie $cookie) { $this->cookies[$cookie->getDomain()][$cookie->getPath()][$cookie->getName()] = $cookie; } public function removeCookie($name, $path = '/', $domain = null) { if (null === $path) { $path = '/'; } unset($this->cookies[$domain][$path][$name]); if (empty($this->cookies[$domain][$path])) { unset($this->cookies[$domain][$path]); if (empty($this->cookies[$domain])) { unset($this->cookies[$domain]); } } } public function getCookies($format = self::COOKIES_FLAT) { if (!in_array($format, array(self::COOKIES_FLAT, self::COOKIES_ARRAY))) { throw new \InvalidArgumentException(sprintf('Format "%s" invalid (%s).', $format, implode(', ', array(self::COOKIES_FLAT, self::COOKIES_ARRAY)))); } if (self::COOKIES_ARRAY === $format) { return $this->cookies; } $flattenedCookies = array(); foreach ($this->cookies as $path) { foreach ($path as $cookies) { foreach ($cookies as $cookie) { $flattenedCookies[] = $cookie; } } } return $flattenedCookies; } public function clearCookie($name, $path = '/', $domain = null) { $this->setCookie(new Cookie($name, null, 1, $path, $domain)); } public function makeDisposition($disposition, $filename, $filenameFallback = '') { if (!in_array($disposition, array(self::DISPOSITION_ATTACHMENT, self::DISPOSITION_INLINE))) { throw new \InvalidArgumentException(sprintf('The disposition must be either "%s" or "%s".', self::DISPOSITION_ATTACHMENT, self::DISPOSITION_INLINE)); } if (!$filenameFallback) { $filenameFallback = $filename; } if (!preg_match('/^[\x20-\x7e]*$/', $filenameFallback)) { throw new \InvalidArgumentException('The filename fallback must only contain ASCII characters.'); } if (false !== strpos($filenameFallback, '%')) { throw new \InvalidArgumentException('The filename fallback cannot contain the "%" character.'); } if (preg_match('#[/\\\\]#', $filename) || preg_match('#[/\\\\]#', $filenameFallback)) { throw new \InvalidArgumentException('The filename and the fallback cannot contain the "/" and "\\" characters.'); } $output = sprintf('%s; filename="%s"', $disposition, str_replace(array('\\', '"'), array('\\\\', '\\"'), $filenameFallback)); if ($filename != $filenameFallback) { $output .= sprintf("; filename*=utf-8''%s", str_replace(array("'", '(', ')', '*'), array('%27', '%28', '%29', '%2A'), urlencode($filename))); } return $output; } protected function computeCacheControlValue() { if (!$this->cacheControl && !$this->has('ETag') && !$this->has('Last-Modified') && !$this->has('Expires')) { return 'no-cache'; } if (!$this->cacheControl) { return 'private, must-revalidate'; } $header = $this->getCacheControlHeader(); if (isset($this->cacheControl['public']) || isset($this->cacheControl['private'])) { return $header; } if (!isset($this->cacheControl['s-maxage'])) { return $header.', private'; } return $header; } } <?php namespace Symfony\Component\HttpFoundation; class ServerBag extends ParameterBag { public function getHeaders() { $headers = array(); foreach ($this->parameters as $key => $value) { if (0 === strpos($key, 'HTTP_')) { $headers[substr($key, 5)] = $value; } elseif (in_array($key, array('CONTENT_LENGTH', 'CONTENT_MD5', 'CONTENT_TYPE'))) { $headers[$key] = $value; } } if (isset($this->parameters['PHP_AUTH_USER'])) { $pass = isset($this->parameters['PHP_AUTH_PW']) ? $this->parameters['PHP_AUTH_PW'] : ''; $headers['AUTHORIZATION'] = 'Basic '.base64_encode($this->parameters['PHP_AUTH_USER'].':'.$pass); } return $headers; } } <?php namespace Symfony\Component\HttpFoundation\Session\Attribute; class AttributeBag implements AttributeBagInterface, \IteratorAggregate, \Countable { private $name = 'attributes'; private $storageKey; protected $attributes = array(); public function __construct($storageKey = '_sf2_attributes') { $this->storageKey = $storageKey; } public function getName() { return $this->name; } public function setName($name) { $this->name = $name; } public function initialize(array &$attributes) { $this->attributes = &$attributes; } public function getStorageKey() { return $this->storageKey; } public function has($name) { return array_key_exists($name, $this->attributes); } public function get($name, $default = null) { return array_key_exists($name, $this->attributes) ? $this->attributes[$name] : $default; } public function set($name, $value) { $this->attributes[$name] = $value; } public function all() { return $this->attributes; } public function replace(array $attributes) { $this->attributes = array(); foreach ($attributes as $key => $value) { $this->set($key, $value); } } public function remove($name) { $retval = null; if (array_key_exists($name, $this->attributes)) { $retval = $this->attributes[$name]; unset($this->attributes[$name]); } return $retval; } public function clear() { $return = $this->attributes; $this->attributes = array(); return $return; } public function getIterator() { return new \ArrayIterator($this->attributes); } public function count() { return count($this->attributes); } } <?php namespace Symfony\Component\HttpFoundation\Session\Attribute; use Symfony\Component\HttpFoundation\Session\SessionBagInterface; interface AttributeBagInterface extends SessionBagInterface { function has($name); function get($name, $default = null); function set($name, $value); function all(); function replace(array $attributes); function remove($name); } <?php namespace Symfony\Component\HttpFoundation\Session\Attribute; class NamespacedAttributeBag extends AttributeBag { private $namespaceCharacter; public function __construct($storageKey = '_sf2_attributes', $namespaceCharacter = '/') { $this->namespaceCharacter = $namespaceCharacter; parent::__construct($storageKey); } public function has($name) { $attributes = $this->resolveAttributePath($name); $name = $this->resolveKey($name); return array_key_exists($name, $attributes); } public function get($name, $default = null) { $attributes = $this->resolveAttributePath($name); $name = $this->resolveKey($name); return array_key_exists($name, $attributes) ? $attributes[$name] : $default; } public function set($name, $value) { $attributes = & $this->resolveAttributePath($name, true); $name = $this->resolveKey($name); $attributes[$name] = $value; } public function remove($name) { $retval = null; $attributes = & $this->resolveAttributePath($name); $name = $this->resolveKey($name); if (array_key_exists($name, $attributes)) { $retval = $attributes[$name]; unset($attributes[$name]); } return $retval; } protected function &resolveAttributePath($name, $writeContext = false) { $array = & $this->attributes; $name = (strpos($name, $this->namespaceCharacter) === 0) ? substr($name, 1) : $name; if (!$name) { return $array; } $parts = explode($this->namespaceCharacter, $name); if (count($parts) < 2) { if (!$writeContext) { return $array; } $array[$parts[0]] = array(); return $array; } unset($parts[count($parts)-1]); foreach ($parts as $part) { if (!array_key_exists($part, $array)) { if (!$writeContext) { return $array; } $array[$part] = array(); } $array = & $array[$part]; } return $array; } protected function resolveKey($name) { if (strpos($name, $this->namespaceCharacter) !== false) { $name = substr($name, strrpos($name, $this->namespaceCharacter)+1, strlen($name)); } return $name; } } <?php namespace Symfony\Component\HttpFoundation\Session\Flash; class AutoExpireFlashBag implements FlashBagInterface { private $name = 'flashes'; private $flashes = array(); private $storageKey; public function __construct($storageKey = '_sf2_flashes') { $this->storageKey = $storageKey; $this->flashes = array('display' => array(), 'new' => array()); } public function getName() { return $this->name; } public function setName($name) { $this->name = $name; } public function initialize(array &$flashes) { $this->flashes = &$flashes; $this->flashes['display'] = array_key_exists('new', $this->flashes) ? $this->flashes['new'] : array(); $this->flashes['new'] = array(); } public function add($type, $message) { $this->flashes['new'][$type][] = $message; } public function peek($type, array $default = array()) { return $this->has($type) ? $this->flashes['display'][$type] : $default; } public function peekAll() { return array_key_exists('display', $this->flashes) ? (array)$this->flashes['display'] : array(); } public function get($type, array $default = array()) { $return = $default; if (!$this->has($type)) { return $return; } if (isset($this->flashes['display'][$type])) { $return = $this->flashes['display'][$type]; unset($this->flashes['display'][$type]); } return $return; } public function all() { $return = $this->flashes['display']; $this->flashes = array('new' => array(), 'display' => array()); return $return; } public function setAll(array $messages) { $this->flashes['new'] = $messages; } public function set($type, $messages) { $this->flashes['new'][$type] = (array)$messages; } public function has($type) { return array_key_exists($type, $this->flashes['display']) && $this->flashes['display'][$type]; } public function keys() { return array_keys($this->flashes['display']); } public function getStorageKey() { return $this->storageKey; } public function clear() { return $this->all(); } } <?php namespace Symfony\Component\HttpFoundation\Session\Flash; class FlashBag implements FlashBagInterface, \IteratorAggregate, \Countable { private $name = 'flashes'; private $flashes = array(); private $storageKey; public function __construct($storageKey = '_sf2_flashes') { $this->storageKey = $storageKey; } public function getName() { return $this->name; } public function setName($name) { $this->name = $name; } public function initialize(array &$flashes) { $this->flashes = &$flashes; } public function add($type, $message) { $this->flashes[$type][] = $message; } public function peek($type, array $default =array()) { return $this->has($type) ? $this->flashes[$type] : $default; } public function peekAll() { return $this->flashes; } public function get($type, array $default = array()) { if (!$this->has($type)) { return $default; } $return = $this->flashes[$type]; unset($this->flashes[$type]); return $return; } public function all() { $return = $this->peekAll(); $this->flashes = array(); return $return; } public function set($type, $messages) { $this->flashes[$type] = (array) $messages; } public function setAll(array $messages) { $this->flashes = $messages; } public function has($type) { return array_key_exists($type, $this->flashes) && $this->flashes[$type]; } public function keys() { return array_keys($this->flashes); } public function getStorageKey() { return $this->storageKey; } public function clear() { return $this->all(); } public function getIterator() { return new \ArrayIterator($this->all()); } public function count() { return count($this->flashes); } } <?php namespace Symfony\Component\HttpFoundation\Session\Flash; use Symfony\Component\HttpFoundation\Session\SessionBagInterface; interface FlashBagInterface extends SessionBagInterface { function add($type, $message); function set($type, $message); function peek($type, array $default = array()); function peekAll(); function get($type, array $default = array()); function all(); function setAll(array $messages); function has($type); function keys(); } <?php namespace Symfony\Component\HttpFoundation\Session; use Symfony\Component\HttpFoundation\Session\Storage\SessionStorageInterface; use Symfony\Component\HttpFoundation\Session\Attribute\AttributeBag; use Symfony\Component\HttpFoundation\Session\Attribute\AttributeBagInterface; use Symfony\Component\HttpFoundation\Session\Flash\FlashBag; use Symfony\Component\HttpFoundation\Session\Flash\FlashBagInterface; use Symfony\Component\HttpFoundation\Session\SessionBagInterface; use Symfony\Component\HttpFoundation\Session\Storage\NativeSessionStorage; class Session implements SessionInterface, \IteratorAggregate, \Countable { protected $storage; private $flashName; private $attributeName; public function __construct(SessionStorageInterface $storage = null, AttributeBagInterface $attributes = null, FlashBagInterface $flashes = null) { $this->storage = $storage ?: new NativeSessionStorage(); $attributes = $attributes ?: new AttributeBag(); $this->attributeName = $attributes->getName(); $this->registerBag($attributes); $flashes = $flashes ?: new FlashBag(); $this->flashName = $flashes->getName(); $this->registerBag($flashes); } public function start() { return $this->storage->start(); } public function has($name) { return $this->storage->getBag($this->attributeName)->has($name); } public function get($name, $default = null) { return $this->storage->getBag($this->attributeName)->get($name, $default); } public function set($name, $value) { $this->storage->getBag($this->attributeName)->set($name, $value); } public function all() { return $this->storage->getBag($this->attributeName)->all(); } public function replace(array $attributes) { $this->storage->getBag($this->attributeName)->replace($attributes); } public function remove($name) { return $this->storage->getBag($this->attributeName)->remove($name); } public function clear() { $this->storage->getBag($this->attributeName)->clear(); } public function getIterator() { return new \ArrayIterator($this->storage->getBag($this->attributeName)->all()); } public function count() { return count($this->storage->getBag($this->attributeName)->all()); } public function invalidate($lifetime = null) { $this->storage->clear(); return $this->migrate(true, $lifetime); } public function migrate($destroy = false, $lifetime = null) { return $this->storage->regenerate($destroy, $lifetime); } public function save() { $this->storage->save(); } public function getId() { return $this->storage->getId(); } public function setId($id) { $this->storage->setId($id); } public function getName() { return $this->storage->getName(); } public function setName($name) { $this->storage->setName($name); } public function getMetadataBag() { return $this->storage->getMetadataBag(); } public function registerBag(SessionBagInterface $bag) { $this->storage->registerBag($bag); } public function getBag($name) { return $this->storage->getBag($name); } public function getFlashBag() { return $this->getBag($this->flashName); } public function getFlashes() { $all = $this->getBag($this->flashName)->all(); $return = array(); if ($all) { foreach ($all as $name => $array) { if (is_numeric(key($array))) { $return[$name] = reset($array); } else { $return[$name] = $array; } } } return $return; } public function setFlashes($values) { foreach ($values as $name => $value) { $this->getBag($this->flashName)->set($name, $value); } } public function getFlash($name, $default = null) { $return = $this->getBag($this->flashName)->get($name); return empty($return) ? $default : reset($return); } public function setFlash($name, $value) { $this->getBag($this->flashName)->set($name, $value); } public function hasFlash($name) { return $this->getBag($this->flashName)->has($name); } public function removeFlash($name) { $this->getBag($this->flashName)->get($name); } public function clearFlashes() { return $this->getBag($this->flashName)->clear(); } } <?php namespace Symfony\Component\HttpFoundation\Session; interface SessionBagInterface { function getName(); function initialize(array &$array); function getStorageKey(); function clear(); } <?php namespace Symfony\Component\HttpFoundation\Session; interface SessionInterface { function start(); function getId(); function setId($id); function getName(); function setName($name); function invalidate($lifetime = null); function migrate($destroy = false, $lifetime = null); function save(); function has($name); function get($name, $default = null); function set($name, $value); function all(); function replace(array $attributes); function remove($name); function clear(); function registerBag(SessionBagInterface $bag); function getBag($name); function getMetadataBag(); } <?php namespace Symfony\Component\HttpFoundation\Session\Storage\Handler; class MemcachedSessionHandler implements \SessionHandlerInterface { private $memcached; private $memcachedOptions; public function __construct(\Memcached $memcached, array $memcachedOptions = array(), array $options = array()) { $this->memcached = $memcached; if (!isset($memcachedOptions['serverpool'])) { $memcachedOptions['serverpool'][] = array( 'host' => '127.0.0.1', 'port' => 11211, 'weight' => 1); } $memcachedOptions['expiretime'] = isset($memcachedOptions['expiretime']) ? (int)$memcachedOptions['expiretime'] : 86400; $this->memcached->setOption(\Memcached::OPT_PREFIX_KEY, isset($memcachedOptions['prefix']) ? $memcachedOptions['prefix'] : 'sf2s'); $this->memcachedOptions = $memcachedOptions; } public function open($savePath, $sessionName) { return $this->memcached->addServers($this->memcachedOptions['serverpool']); } public function close() { return true; } public function read($sessionId) { return $this->memcached->get($sessionId) ?: ''; } public function write($sessionId, $data) { return $this->memcached->set($sessionId, $data, $this->memcachedOptions['expiretime']); } public function destroy($sessionId) { return $this->memcached->delete($sessionId); } public function gc($lifetime) { return true; } protected function addServer(array $server) { if (array_key_exists('host', $server)) { throw new \InvalidArgumentException('host key must be set'); } $server['port'] = isset($server['port']) ? (int)$server['port'] : 11211; $server['timeout'] = isset($server['timeout']) ? (int)$server['timeout'] : 1; $server['presistent'] = isset($server['presistent']) ? (bool)$server['presistent'] : false; $server['weight'] = isset($server['weight']) ? (bool)$server['weight'] : 1; } } <?php namespace Symfony\Component\HttpFoundation\Session\Storage\Handler; class MemcacheSessionHandler implements \SessionHandlerInterface { private $memcache; private $memcacheOptions; private $prefix; public function __construct(\Memcache $memcache, array $memcacheOptions = array(), array $options = array()) { $this->memcache = $memcache; if (!isset($memcacheOptions['serverpool'])) { $memcacheOptions['serverpool'] = array(array( 'host' => '127.0.0.1', 'port' => 11211, 'timeout' => 1, 'persistent' => false, 'weight' => 1, 'retry_interval' => 15, )); } $memcacheOptions['expiretime'] = isset($memcacheOptions['expiretime']) ? (int)$memcacheOptions['expiretime'] : 86400; $this->prefix = isset($memcacheOptions['prefix']) ? $memcacheOptions['prefix'] : 'sf2s'; $this->memcacheOptions = $memcacheOptions; } protected function addServer(array $server) { if (!array_key_exists('host', $server)) { throw new \InvalidArgumentException('host key must be set'); } $server['port'] = isset($server['port']) ? (int)$server['port'] : 11211; $server['timeout'] = isset($server['timeout']) ? (int)$server['timeout'] : 1; $server['persistent'] = isset($server['persistent']) ? (bool)$server['persistent'] : false; $server['weight'] = isset($server['weight']) ? (int)$server['weight'] : 1; $server['retry_interval'] = isset($server['retry_interval']) ? (int)$server['retry_interval'] : 15; $this->memcache->addserver($server['host'], $server['port'], $server['persistent'],$server['weight'],$server['timeout'],$server['retry_interval']); } public function open($savePath, $sessionName) { foreach ($this->memcacheOptions['serverpool'] as $server) { $this->addServer($server); } return true; } public function close() { return $this->memcache->close(); } public function read($sessionId) { return $this->memcache->get($this->prefix.$sessionId) ?: ''; } public function write($sessionId, $data) { if (!$this->memcache->replace($this->prefix.$sessionId, $data, 0, $this->memcacheOptions['expiretime'])) { return $this->memcache->set($this->prefix.$sessionId, $data, 0, $this->memcacheOptions['expiretime']); } return true; } public function destroy($sessionId) { return $this->memcache->delete($this->prefix.$sessionId); } public function gc($lifetime) { return true; } } <?php namespace Symfony\Component\HttpFoundation\Session\Storage\Handler; class MongoDbSessionHandler implements \SessionHandlerInterface { private $mongo; private $collection; private $options; public function __construct(\Mongo $mongo, array $options) { if (!isset($options['database']) || !isset($options['collection'])) { throw new \InvalidArgumentException('You must provide the "database" and "collection" option for MongoDBSessionHandler'); } $this->mongo = $mongo; $this->options = array_merge(array( 'id_field' => 'sess_id', 'data_field' => 'sess_data', 'time_field' => 'sess_time', ), $options); } public function open($savePath, $sessionName) { return true; } public function close() { return true; } public function destroy($sessionId) { $this->getCollection()->remove( array($this->options['id_field'] => $sessionId), array('justOne' => true) ); return true; } public function gc($lifetime) { $time = new \MongoTimestamp(time() - $lifetime); $this->getCollection()->remove(array( $this->options['time_field'] => array('$lt' => $time), )); } public function write($sessionId, $data) { $data = array( $this->options['id_field'] => $sessionId, $this->options['data_field'] => new \MongoBinData($data), $this->options['time_field'] => new \MongoTimestamp() ); $this->getCollection()->update( array($this->options['id_field'] => $sessionId), array('$set' => $data), array('upsert' => true) ); return true; } public function read($sessionId) { $dbData = $this->getCollection()->findOne(array( $this->options['id_field'] => $sessionId, )); return null === $dbData ? '' : $dbData[$this->options['data_field']]->bin; } private function getCollection() { if (null === $this->collection) { $this->collection = $this->mongo->selectDB($this->options['database'])->selectCollection($this->options['collection']); } return $this->collection; } }<?php namespace Symfony\Component\HttpFoundation\Session\Storage\Handler; class NativeFileSessionHandler extends NativeSessionHandler { public function __construct($savePath = null) { if (null === $savePath) { $savePath = ini_get('session.save_path'); } if ($savePath && !is_dir($savePath)) { mkdir($savePath, 0777, true); } ini_set('session.save_handler', 'files'); ini_set('session.save_path', $savePath); } } <?php namespace Symfony\Component\HttpFoundation\Session\Storage\Handler; class NativeMemcachedSessionHandler extends NativeSessionHandler { public function __construct($savePath = '127.0.0.1:11211', array $options = array()) { if (!extension_loaded('memcached')) { throw new \RuntimeException('PHP does not have "memcached" session module registered'); } if (null === $savePath) { $savePath = ini_get('session.save_path'); } ini_set('session.save_handler', 'memcached'); ini_set('session.save_path', $savePath); $this->setOptions($options); } protected function setOptions(array $options) { $validOptions = array_flip(array( 'memcached.sess_locking', 'memcached.sess_lock_wait', 'memcached.sess_prefix', 'memcached.compression_type', 'memcached.compression_factor', 'memcached.compression_threshold', 'memcached.serializer', )); foreach ($options as $key => $value) { if (isset($validOptions[$key])) { ini_set($key, $value); } } } } <?php namespace Symfony\Component\HttpFoundation\Session\Storage\Handler; class NativeMemcacheSessionHandler extends NativeSessionHandler { public function __construct($savePath = 'tcp://127.0.0.1:11211?persistent=0', array $options = array()) { if (!extension_loaded('memcache')) { throw new \RuntimeException('PHP does not have "memcache" session module registered'); } if (null === $savePath) { $savePath = ini_get('session.save_path'); } ini_set('session.save_handler', 'memcache'); ini_set('session.save_path', $savePath); $this->setOptions($options); } protected function setOptions(array $options) { $validOptions = array_flip(array( 'memcache.allow_failover', 'memcache.max_failover_attempts', 'memcache.chunk_size', 'memcache.default_port', 'memcache.hash_strategy', 'memcache.hash_function', 'memcache.protocol', 'memcache.redundancy', 'memcache.session_redundancy', 'memcache.compress_threshold', 'memcache.lock_timeout', )); foreach ($options as $key => $value) { if (isset($validOptions[$key])) { ini_set($key, $value); } } } } <?php namespace Symfony\Component\HttpFoundation\Session\Storage\Handler; class NativeRedisSessionHandler extends NativeSessionHandler { public function __construct($savePath = 'tcp://127.0.0.1:6379?persistent=0') { if (!extension_loaded('redis')) { throw new \RuntimeException('PHP does not have "redis" session module registered'); } if (null === $savePath) { $savePath = ini_get('session.save_path'); } ini_set('session.save_handler', 'redis'); ini_set('session.save_path', $savePath); } } <?php namespace Symfony\Component\HttpFoundation\Session\Storage\Handler; if (version_compare(phpversion(), '5.4.0', '>=')) { class NativeSessionHandler extends \SessionHandler {} } else { class NativeSessionHandler {} } <?php namespace Symfony\Component\HttpFoundation\Session\Storage\Handler; class NativeSqliteSessionHandler extends NativeSessionHandler { public function __construct($savePath, array $options = array()) { if (!extension_loaded('sqlite')) { throw new \RuntimeException('PHP does not have "sqlite" session module registered'); } if (null === $savePath) { $savePath = ini_get('session.save_path'); } ini_set('session.save_handler', 'sqlite'); ini_set('session.save_path', $savePath); $this->setOptions($options); } protected function setOptions(array $options) { foreach ($options as $key => $value) { if (in_array($key, array('sqlite.assoc_case'))) { ini_set($key, $value); } } } } <?php namespace Symfony\Component\HttpFoundation\Session\Storage\Handler; class NullSessionHandler implements \SessionHandlerInterface { public function open($savePath, $sessionName) { return true; } public function close() { return true; } public function read($sessionId) { return ''; } public function write($sessionId, $data) { return true; } public function destroy($sessionId) { return true; } public function gc($lifetime) { return true; } } <?php namespace Symfony\Component\HttpFoundation\Session\Storage\Handler; class PdoSessionHandler implements \SessionHandlerInterface { private $pdo; private $dbOptions; public function __construct(\PDO $pdo, array $dbOptions = array(), array $options = array()) { if (!array_key_exists('db_table', $dbOptions)) { throw new \InvalidArgumentException('You must provide the "db_table" option for a PdoSessionStorage.'); } $this->pdo = $pdo; $this->dbOptions = array_merge(array( 'db_id_col' => 'sess_id', 'db_data_col' => 'sess_data', 'db_time_col' => 'sess_time', ), $dbOptions); } public function open($path, $name) { return true; } public function close() { return true; } public function destroy($id) { $dbTable = $this->dbOptions['db_table']; $dbIdCol = $this->dbOptions['db_id_col']; $sql = "DELETE FROM $dbTable WHERE $dbIdCol = :id"; try { $stmt = $this->pdo->prepare($sql); $stmt->bindParam(':id', $id, \PDO::PARAM_STR); $stmt->execute(); } catch (\PDOException $e) { throw new \RuntimeException(sprintf('PDOException was thrown when trying to manipulate session data: %s', $e->getMessage()), 0, $e); } return true; } public function gc($lifetime) { $dbTable = $this->dbOptions['db_table']; $dbTimeCol = $this->dbOptions['db_time_col']; $sql = "DELETE FROM $dbTable WHERE $dbTimeCol < (:time - $lifetime)"; try { $stmt = $this->pdo->prepare($sql); $stmt->bindValue(':time', time(), \PDO::PARAM_INT); $stmt->execute(); } catch (\PDOException $e) { throw new \RuntimeException(sprintf('PDOException was thrown when trying to manipulate session data: %s', $e->getMessage()), 0, $e); } return true; } public function read($id) { $dbTable = $this->dbOptions['db_table']; $dbDataCol = $this->dbOptions['db_data_col']; $dbIdCol = $this->dbOptions['db_id_col']; try { $sql = "SELECT $dbDataCol FROM $dbTable WHERE $dbIdCol = :id"; $stmt = $this->pdo->prepare($sql); $stmt->bindParam(':id', $id, \PDO::PARAM_STR); $stmt->execute(); $sessionRows = $stmt->fetchAll(\PDO::FETCH_NUM); if (count($sessionRows) == 1) { return base64_decode($sessionRows[0][0]); } $this->createNewSession($id); return ''; } catch (\PDOException $e) { throw new \RuntimeException(sprintf('PDOException was thrown when trying to read the session data: %s', $e->getMessage()), 0, $e); } } public function write($id, $data) { $dbTable = $this->dbOptions['db_table']; $dbDataCol = $this->dbOptions['db_data_col']; $dbIdCol = $this->dbOptions['db_id_col']; $dbTimeCol = $this->dbOptions['db_time_col']; $sql = ('mysql' === $this->pdo->getAttribute(\PDO::ATTR_DRIVER_NAME)) ? "INSERT INTO $dbTable ($dbIdCol, $dbDataCol, $dbTimeCol) VALUES (:id, :data, :time) " ."ON DUPLICATE KEY UPDATE $dbDataCol = VALUES($dbDataCol), $dbTimeCol = CASE WHEN $dbTimeCol = :time THEN (VALUES($dbTimeCol) + 1) ELSE VALUES($dbTimeCol) END" : "UPDATE $dbTable SET $dbDataCol = :data, $dbTimeCol = :time WHERE $dbIdCol = :id"; try { $encoded = base64_encode($data); $stmt = $this->pdo->prepare($sql); $stmt->bindParam(':id', $id, \PDO::PARAM_STR); $stmt->bindParam(':data', $encoded, \PDO::PARAM_STR); $stmt->bindValue(':time', time(), \PDO::PARAM_INT); $stmt->execute(); if (!$stmt->rowCount()) { $this->createNewSession($id, $data); } } catch (\PDOException $e) { throw new \RuntimeException(sprintf('PDOException was thrown when trying to write the session data: %s', $e->getMessage()), 0, $e); } return true; } private function createNewSession($id, $data = '') { $dbTable = $this->dbOptions['db_table']; $dbDataCol = $this->dbOptions['db_data_col']; $dbIdCol = $this->dbOptions['db_id_col']; $dbTimeCol = $this->dbOptions['db_time_col']; $sql = "INSERT INTO $dbTable ($dbIdCol, $dbDataCol, $dbTimeCol) VALUES (:id, :data, :time)"; $encoded = base64_encode($data); $stmt = $this->pdo->prepare($sql); $stmt->bindParam(':id', $id, \PDO::PARAM_STR); $stmt->bindParam(':data', $encoded, \PDO::PARAM_STR); $stmt->bindValue(':time', time(), \PDO::PARAM_INT); $stmt->execute(); return true; } } <?php namespace Symfony\Component\HttpFoundation\Session\Storage; use Symfony\Component\HttpFoundation\Session\SessionBagInterface; class MetadataBag implements SessionBagInterface { const CREATED = 'c'; const UPDATED = 'u'; const LIFETIME = 'l'; private $name = '__metadata'; private $storageKey; protected $meta = array(); private $lastUsed; public function __construct($storageKey = '_sf2_meta') { $this->storageKey = $storageKey; $this->meta = array(self::CREATED => 0, self::UPDATED => 0, self::LIFETIME => 0); } public function initialize(array &$array) { $this->meta = &$array; if (isset($array[self::CREATED])) { $this->lastUsed = $this->meta[self::UPDATED]; $this->meta[self::UPDATED] = time(); } else { $this->stampCreated(); } } public function getLifetime() { return $this->meta[self::LIFETIME]; } public function stampNew($lifetime = null) { $this->stampCreated($lifetime); } public function getStorageKey() { return $this->storageKey; } public function getCreated() { return $this->meta[self::CREATED]; } public function getLastUsed() { return $this->lastUsed; } public function clear() { } public function getName() { return $this->name; } public function setName($name) { $this->name = $name; } private function stampCreated($lifetime = null) { $timeStamp = time(); $this->meta[self::CREATED] = $this->meta[self::UPDATED] = $this->lastUsed = $timeStamp; $this->meta[self::LIFETIME] = (null === $lifetime) ? ini_get('session.cookie_lifetime') : $lifetime; } } <?php namespace Symfony\Component\HttpFoundation\Session\Storage; use Symfony\Component\HttpFoundation\Session\SessionBagInterface; use Symfony\Component\HttpFoundation\Session\Storage\MetadataBag; class MockArraySessionStorage implements SessionStorageInterface { protected $id = ''; protected $name; protected $started = false; protected $closed = false; protected $data = array(); protected $metadataBag; public function __construct($name = 'MOCKSESSID', MetadataBag $metaBag = null) { $this->name = $name; $this->setMetadataBag($metaBag); } public function setSessionData(array $array) { $this->data = $array; } public function start() { if ($this->started && !$this->closed) { return true; } if (empty($this->id)) { $this->id = $this->generateId(); } $this->loadSession(); return true; } public function regenerate($destroy = false, $lifetime = null) { if (!$this->started) { $this->start(); } $this->metadataBag->stampNew($lifetime); $this->id = $this->generateId(); return true; } public function getId() { return $this->id; } public function setId($id) { if ($this->started) { throw new \LogicException('Cannot set session ID after the session has started.'); } $this->id = $id; } public function getName() { return $this->name; } public function setName($name) { $this->name = $name; } public function save() { $this->closed = false; } public function clear() { foreach ($this->bags as $bag) { $bag->clear(); } $this->data = array(); $this->loadSession(); } public function registerBag(SessionBagInterface $bag) { $this->bags[$bag->getName()] = $bag; } public function getBag($name) { if (!isset($this->bags[$name])) { throw new \InvalidArgumentException(sprintf('The SessionBagInterface %s is not registered.', $name)); } if (!$this->started) { $this->start(); } return $this->bags[$name]; } public function setMetadataBag(MetadataBag $bag = null) { if (null === $bag) { $bag = new MetadataBag(); } $this->metadataBag = $bag; } public function getMetadataBag() { return $this->metadataBag; } protected function generateId() { return sha1(uniqid(mt_rand())); } protected function loadSession() { $bags = array_merge($this->bags, array($this->metadataBag)); foreach ($bags as $bag) { $key = $bag->getStorageKey(); $this->data[$key] = isset($this->data[$key]) ? $this->data[$key] : array(); $bag->initialize($this->data[$key]); } $this->started = true; $this->closed = false; } } <?php namespace Symfony\Component\HttpFoundation\Session\Storage; class MockFileSessionStorage extends MockArraySessionStorage { private $savePath; private $sessionData; public function __construct($savePath = null, $name = 'MOCKSESSID') { if (null === $savePath) { $savePath = sys_get_temp_dir(); } if (!is_dir($savePath)) { mkdir($savePath, 0777, true); } $this->savePath = $savePath; parent::__construct($name); } public function start() { if ($this->started) { return true; } if (!$this->id) { $this->id = $this->generateId(); } $this->read(); $this->started = true; return true; } public function regenerate($destroy = false, $lifetime = null) { if (!$this->started) { $this->start(); } if ($destroy) { $this->destroy(); } return parent::regenerate($destroy, $lifetime); } public function save() { file_put_contents($this->getFilePath(), serialize($this->data)); } private function destroy() { if (is_file($this->getFilePath())) { unlink($this->getFilePath()); } } private function getFilePath() { return $this->savePath.'/'.$this->id.'.mocksess'; } private function read() { $filePath = $this->getFilePath(); $this->data = is_readable($filePath) && is_file($filePath) ? unserialize(file_get_contents($filePath)) : array(); $this->loadSession(); } } <?php namespace Symfony\Component\HttpFoundation\Session\Storage; use Symfony\Component\HttpFoundation\Session\SessionBagInterface; use Symfony\Component\HttpFoundation\Session\Storage\MetadataBag; use Symfony\Component\HttpFoundation\Session\Storage\Proxy\NativeProxy; use Symfony\Component\HttpFoundation\Session\Storage\Proxy\AbstractProxy; use Symfony\Component\HttpFoundation\Session\Storage\Proxy\SessionHandlerProxy; class NativeSessionStorage implements SessionStorageInterface { protected $bags; protected $started = false; protected $closed = false; protected $saveHandler; protected $metadataBag; public function __construct(array $options = array(), $handler = null, MetadataBag $metaBag = null) { ini_set('session.auto_start', 0); ini_set('session.cache_limiter', ''); ini_set('session.use_cookies', 1); if (version_compare(phpversion(), '5.4.0', '>=')) { session_register_shutdown(); } else { register_shutdown_function('session_write_close'); } $this->setMetadataBag($metaBag); $this->setOptions($options); $this->setSaveHandler($handler); } public function getSaveHandler() { return $this->saveHandler; } public function start() { if ($this->started && !$this->closed) { return true; } if (!$this->started && !$this->closed && $this->saveHandler->isActive() && $this->saveHandler->isSessionHandlerInterface()) { $this->loadSession(); return true; } if (ini_get('session.use_cookies') && headers_sent()) { throw new \RuntimeException('Failed to start the session because headers have already been sent.'); } if (!session_start()) { throw new \RuntimeException('Failed to start the session'); } $this->loadSession(); if (!$this->saveHandler->isWrapper() && !$this->saveHandler->isSessionHandlerInterface()) { $this->saveHandler->setActive(false); } return true; } public function getId() { if (!$this->started) { return ''; } return $this->saveHandler->getId(); } public function setId($id) { return $this->saveHandler->setId($id); } public function getName() { return $this->saveHandler->getName(); } public function setName($name) { $this->saveHandler->setName($name); } public function regenerate($destroy = false, $lifetime = null) { if (null !== $lifetime) { ini_set('session.cookie_lifetime', $lifetime); } if ($destroy) { $this->metadataBag->stampNew(); } return session_regenerate_id($destroy); } public function save() { session_write_close(); if (!$this->saveHandler->isWrapper() && !$this->getSaveHandler()->isSessionHandlerInterface()) { $this->saveHandler->setActive(false); } $this->closed = true; } public function clear() { foreach ($this->bags as $bag) { $bag->clear(); } $_SESSION = array(); $this->loadSession(); } public function registerBag(SessionBagInterface $bag) { $this->bags[$bag->getName()] = $bag; } public function getBag($name) { if (!isset($this->bags[$name])) { throw new \InvalidArgumentException(sprintf('The SessionBagInterface %s is not registered.', $name)); } if (ini_get('session.auto_start') && !$this->started) { $this->start(); } elseif ($this->saveHandler->isActive() && !$this->started) { $this->loadSession(); } return $this->bags[$name]; } public function setMetadataBag(MetadataBag $metaBag = null) { if (null === $metaBag) { $metaBag = new MetadataBag(); } $this->metadataBag = $metaBag; } public function getMetadataBag() { return $this->metadataBag; } public function setOptions(array $options) { $validOptions = array_flip(array( 'auto_start', 'cache_limiter', 'cookie_domain', 'cookie_httponly', 'cookie_lifetime', 'cookie_path', 'cookie_secure', 'entropy_file', 'entropy_length', 'gc_divisor', 'gc_maxlifetime', 'gc_probability', 'hash_bits_per_character', 'hash_function', 'name', 'referer_check', 'serialize_handler', 'use_cookies', 'use_only_cookies', 'use_trans_sid', 'upload_progress.enabled', 'upload_progress.cleanup', 'upload_progress.prefix', 'upload_progress.name', 'upload_progress.freq', 'upload_progress.min-freq', 'url_rewriter.tags', )); foreach ($options as $key => $value) { if (isset($validOptions[$key])) { ini_set('session.'.$key, $value); } } } public function setSaveHandler($saveHandler = null) { if (!$saveHandler instanceof AbstractProxy && $saveHandler instanceof \SessionHandlerInterface) { $saveHandler = new SessionHandlerProxy($saveHandler); } elseif (!$saveHandler instanceof AbstractProxy) { $saveHandler = new NativeProxy($saveHandler); } $this->saveHandler = $saveHandler; if ($this->saveHandler instanceof \SessionHandlerInterface) { if (version_compare(phpversion(), '5.4.0', '>=')) { session_set_save_handler($this->saveHandler, false); } else { session_set_save_handler( array($this->saveHandler, 'open'), array($this->saveHandler, 'close'), array($this->saveHandler, 'read'), array($this->saveHandler, 'write'), array($this->saveHandler, 'destroy'), array($this->saveHandler, 'gc') ); } } } protected function loadSession(array &$session = null) { if (null === $session) { $session = &$_SESSION; } $bags = array_merge($this->bags, array($this->metadataBag)); foreach ($bags as $bag) { $key = $bag->getStorageKey(); $session[$key] = isset($session[$key]) ? $session[$key] : array(); $bag->initialize($session[$key]); } $this->started = true; $this->closed = false; } } <?php namespace Symfony\Component\HttpFoundation\Session\Storage\Proxy; abstract class AbstractProxy { protected $wrapper = false; protected $active = false; protected $saveHandlerName; public function getSaveHandlerName() { return $this->saveHandlerName; } public function isSessionHandlerInterface() { return ($this instanceof \SessionHandlerInterface); } public function isWrapper() { return $this->wrapper; } public function isActive() { return $this->active; } public function setActive($flag) { $this->active = (bool) $flag; } public function getId() { return session_id(); } public function setId($id) { if ($this->isActive()) { throw new \LogicException('Cannot change the ID of an active session'); } session_id($id); } public function getName() { return session_name(); } public function setName($name) { if ($this->isActive()) { throw new \LogicException('Cannot change the name of an active session'); } session_name($name); } } <?php namespace Symfony\Component\HttpFoundation\Session\Storage\Proxy; class NativeProxy extends AbstractProxy { public function __construct() { $this->saveHandlerName = ini_get('session.save_handler'); } public function isWrapper() { return false; } } <?php namespace Symfony\Component\HttpFoundation\Session\Storage\Proxy; class SessionHandlerProxy extends AbstractProxy implements \SessionHandlerInterface { protected $handler; public function __construct(\SessionHandlerInterface $handler) { $this->handler = $handler; $this->wrapper = ($handler instanceof \SessionHandler); $this->saveHandlerName = $this->wrapper ? ini_get('session.save_handler') : 'user'; } public function open($savePath, $sessionName) { $return = (bool)$this->handler->open($savePath, $sessionName); if (true === $return) { $this->active = true; } return $return; } public function close() { $this->active = false; return (bool) $this->handler->close(); } public function read($id) { return (string) $this->handler->read($id); } public function write($id, $data) { return (bool) $this->handler->write($id, $data); } public function destroy($id) { return (bool) $this->handler->destroy($id); } public function gc($maxlifetime) { return (bool) $this->handler->gc($maxlifetime); } } <?php namespace Symfony\Component\HttpFoundation\Session\Storage; use Symfony\Component\HttpFoundation\Session\SessionBagInterface; use Symfony\Component\HttpFoundation\Session\Storage\MetadataBag; interface SessionStorageInterface { function start(); function getId(); function setId($id); function getName(); function setName($name); function regenerate($destroy = false, $lifetime = null); function save(); function clear(); function getBag($name); function registerBag(SessionBagInterface $bag); function getMetadataBag(); } <?php namespace Symfony\Component\HttpFoundation; class StreamedResponse extends Response { protected $callback; protected $streamed; public function __construct($callback = null, $status = 200, $headers = array()) { parent::__construct(null, $status, $headers); if (null !== $callback) { $this->setCallback($callback); } $this->streamed = false; } public static function create($callback = null, $status = 200, $headers = array()) { return new static($callback, $status, $headers); } public function setCallback($callback) { if (!is_callable($callback)) { throw new \LogicException('The Response callback must be a valid PHP callable.'); } $this->callback = $callback; } public function prepare(Request $request) { if ('1.0' != $request->server->get('SERVER_PROTOCOL')) { $this->setProtocolVersion('1.1'); } $this->headers->set('Cache-Control', 'no-cache'); return parent::prepare($request); } public function sendContent() { if ($this->streamed) { return; } $this->streamed = true; if (null === $this->callback) { throw new \LogicException('The Response callback must not be null.'); } call_user_func($this->callback); } public function setContent($content) { if (null !== $content) { throw new \LogicException('The content cannot be set on a StreamedResponse instance.'); } } public function getContent() { return false; } } <?php namespace Symfony\Component\HttpKernel\Bundle; use Symfony\Component\DependencyInjection\ContainerAware; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Container; use Symfony\Component\Console\Application; use Symfony\Component\Finder\Finder; abstract class Bundle extends ContainerAware implements BundleInterface { protected $name; protected $reflected; protected $extension; public function boot() { } public function shutdown() { } public function build(ContainerBuilder $container) { } public function getContainerExtension() { if (null === $this->extension) { $basename = preg_replace('/Bundle$/', '', $this->getName()); $class = $this->getNamespace().'\\DependencyInjection\\'.$basename.'Extension'; if (class_exists($class)) { $extension = new $class(); $expectedAlias = Container::underscore($basename); if ($expectedAlias != $extension->getAlias()) { throw new \LogicException(sprintf( 'The extension alias for the default extension of a '. 'bundle must be the underscored version of the '. 'bundle name ("%s" instead of "%s")', $expectedAlias, $extension->getAlias() )); } $this->extension = $extension; } else { $this->extension = false; } } if ($this->extension) { return $this->extension; } } public function getNamespace() { if (null === $this->reflected) { $this->reflected = new \ReflectionObject($this); } return $this->reflected->getNamespaceName(); } public function getPath() { if (null === $this->reflected) { $this->reflected = new \ReflectionObject($this); } return dirname($this->reflected->getFileName()); } public function getParent() { return null; } final public function getName() { if (null !== $this->name) { return $this->name; } $name = get_class($this); $pos = strrpos($name, '\\'); return $this->name = false === $pos ? $name : substr($name, $pos + 1); } public function registerCommands(Application $application) { if (!$dir = realpath($this->getPath().'/Command')) { return; } $finder = new Finder(); $finder->files()->name('*Command.php')->in($dir); $prefix = $this->getNamespace().'\\Command'; foreach ($finder as $file) { $ns = $prefix; if ($relativePath = $file->getRelativePath()) { $ns .= '\\'.strtr($relativePath, '/', '\\'); } $r = new \ReflectionClass($ns.'\\'.$file->getBasename('.php')); if ($r->isSubclassOf('Symfony\\Component\\Console\\Command\\Command') && !$r->isAbstract()) { $application->add($r->newInstance()); } } } } <?php namespace Symfony\Component\HttpKernel\Bundle; use Symfony\Component\DependencyInjection\ContainerBuilder; interface BundleInterface { function boot(); function shutdown(); function build(ContainerBuilder $container); function getContainerExtension(); function getParent(); function getName(); function getNamespace(); function getPath(); } <?php namespace Symfony\Component\HttpKernel\CacheClearer; interface CacheClearerInterface { function clear($cacheDir); } <?php namespace Symfony\Component\HttpKernel\CacheClearer; class ChainCacheClearer implements CacheClearerInterface { protected $clearers; public function __construct(array $clearers = array()) { $this->clearers = $clearers; } public function clear($cacheDir) { foreach ($this->clearers as $clearer) { $clearer->clear($cacheDir); } } public function add(CacheClearerInterface $clearer) { $this->clearers[] = $clearer; } } <?php namespace Symfony\Component\HttpKernel\CacheWarmer; abstract class CacheWarmer implements CacheWarmerInterface { protected function writeCacheFile($file, $content) { $tmpFile = tempnam(dirname($file), basename($file)); if (false !== @file_put_contents($tmpFile, $content) && @rename($tmpFile, $file)) { chmod($file, 0666 & ~umask()); return; } throw new \RuntimeException(sprintf('Failed to write cache file "%s".', $file)); } } <?php namespace Symfony\Component\HttpKernel\CacheWarmer; class CacheWarmerAggregate implements CacheWarmerInterface { protected $warmers; protected $optionalsEnabled; public function __construct(array $warmers = array()) { $this->setWarmers($warmers); $this->optionalsEnabled = false; } public function enableOptionalWarmers() { $this->optionalsEnabled = true; } public function warmUp($cacheDir) { foreach ($this->warmers as $warmer) { if (!$this->optionalsEnabled && $warmer->isOptional()) { continue; } $warmer->warmUp($cacheDir); } } public function isOptional() { return false; } public function setWarmers(array $warmers) { $this->warmers = array(); foreach ($warmers as $warmer) { $this->add($warmer); } } public function add(CacheWarmerInterface $warmer) { $this->warmers[] = $warmer; } } <?php namespace Symfony\Component\HttpKernel\CacheWarmer; interface CacheWarmerInterface extends WarmableInterface { function isOptional(); } <?php namespace Symfony\Component\HttpKernel\CacheWarmer; interface WarmableInterface { function warmUp($cacheDir); } <?php namespace Symfony\Component\HttpKernel; use Symfony\Component\HttpFoundation\File\UploadedFile; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\BrowserKit\Client as BaseClient; use Symfony\Component\BrowserKit\Request as DomRequest; use Symfony\Component\BrowserKit\Response as DomResponse; use Symfony\Component\BrowserKit\Cookie as DomCookie; use Symfony\Component\BrowserKit\History; use Symfony\Component\BrowserKit\CookieJar; use Symfony\Component\HttpKernel\TerminableInterface; class Client extends BaseClient { protected $kernel; public function __construct(HttpKernelInterface $kernel, array $server = array(), History $history = null, CookieJar $cookieJar = null) { $this->kernel = $kernel; parent::__construct($server, $history, $cookieJar); $this->followRedirects = false; } protected function doRequest($request) { $response = $this->kernel->handle($request); if ($this->kernel instanceof TerminableInterface) { $this->kernel->terminate($request, $response); } return $response; } protected function getScript($request) { $kernel = str_replace("'", "\\'", serialize($this->kernel)); $request = str_replace("'", "\\'", serialize($request)); $r = new \ReflectionClass('\\Symfony\\Component\\ClassLoader\\UniversalClassLoader'); $requirePath = str_replace("'", "\\'", $r->getFileName()); $symfonyPath = str_replace("'", "\\'", realpath(__DIR__.'/../../..')); return <<<EOF <?php require_once '$requirePath'; \$loader = new Symfony\Component\ClassLoader\UniversalClassLoader(); \$loader->registerNamespaces(array('Symfony' => '$symfonyPath')); \$loader->register(); \$kernel = unserialize('$kernel'); echo serialize(\$kernel->handle(unserialize('$request'))); EOF; } protected function filterRequest(DomRequest $request) { $httpRequest = Request::create($request->getUri(), $request->getMethod(), $request->getParameters(), $request->getCookies(), $request->getFiles(), $request->getServer(), $request->getContent()); $httpRequest->files->replace($this->filterFiles($httpRequest->files->all())); return $httpRequest; } protected function filterFiles(array $files) { $filtered = array(); foreach ($files as $key => $value) { if (is_array($value)) { $filtered[$key] = $this->filterFiles($value); } elseif ($value instanceof UploadedFile) { if ($value->isValid() && $value->getSize() > UploadedFile::getMaxFilesize()) { $filtered[$key] = new UploadedFile( '', $value->getClientOriginalName(), $value->getClientMimeType(), 0, UPLOAD_ERR_INI_SIZE, true ); } else { $filtered[$key] = new UploadedFile( $value->getPathname(), $value->getClientOriginalName(), $value->getClientMimeType(), $value->getClientSize(), $value->getError(), true ); } } else { $filtered[$key] = $value; } } return $filtered; } protected function filterResponse($response) { $headers = $response->headers->all(); if ($response->headers->getCookies()) { $cookies = array(); foreach ($response->headers->getCookies() as $cookie) { $cookies[] = new DomCookie($cookie->getName(), $cookie->getValue(), $cookie->getExpiresTime(), $cookie->getPath(), $cookie->getDomain(), $cookie->isSecure(), $cookie->isHttpOnly()); } $headers['Set-Cookie'] = $cookies; } return new DomResponse($response->getContent(), $response->getStatusCode(), $headers); } } <?php namespace Symfony\Component\HttpKernel\Config; use Symfony\Component\Config\FileLocator as BaseFileLocator; use Symfony\Component\HttpKernel\KernelInterface; class FileLocator extends BaseFileLocator { private $kernel; private $path; public function __construct(KernelInterface $kernel, $path = null, array $paths = array()) { $this->kernel = $kernel; $this->path = $path; $paths[] = $path; parent::__construct($paths); } public function locate($file, $currentPath = null, $first = true) { if ('@' === $file[0]) { return $this->kernel->locateResource($file, $this->path, $first); } return parent::locate($file, $currentPath, $first); } } <?php namespace Symfony\Component\HttpKernel\Controller; use Symfony\Component\HttpKernel\Log\LoggerInterface; use Symfony\Component\HttpFoundation\Request; class ControllerResolver implements ControllerResolverInterface { private $logger; public function __construct(LoggerInterface $logger = null) { $this->logger = $logger; } 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'); } return false; } if (is_array($controller) || (is_object($controller) && method_exists($controller, '__invoke'))) { return $controller; } if (false === strpos($controller, ':')) { if (method_exists($controller, '__invoke')) { return new $controller; } elseif (function_exists($controller)) { return $controller; } } list($controller, $method) = $this->createController($controller); if (!method_exists($controller, $method)) { throw new \InvalidArgumentException(sprintf('Method "%s::%s" does not exist.', get_class($controller), $method)); } return array($controller, $method); } public function getArguments(Request $request, $controller) { if (is_array($controller)) { $r = new \ReflectionMethod($controller[0], $controller[1]); } elseif (is_object($controller) && !$controller instanceof \Closure) { $r = new \ReflectionObject($controller); $r = $r->getMethod('__invoke'); } else { $r = new \ReflectionFunction($controller); } return $this->doGetArguments($request, $controller, $r->getParameters()); } protected function doGetArguments(Request $request, $controller, array $parameters) { $attributes = $request->attributes->all(); $arguments = array(); foreach ($parameters as $param) { if (array_key_exists($param->getName(), $attributes)) { $arguments[] = $attributes[$param->getName()]; } elseif ($param->getClass() && $param->getClass()->isInstance($request)) { $arguments[] = $request; } elseif ($param->isDefaultValueAvailable()) { $arguments[] = $param->getDefaultValue(); } else { if (is_array($controller)) { $repr = sprintf('%s::%s()', get_class($controller[0]), $controller[1]); } elseif (is_object($controller)) { $repr = get_class($controller); } else { $repr = $controller; } throw new \RuntimeException(sprintf('Controller "%s" requires that you provide a value for the "$%s" argument (because there is no default value or because there is a non optional argument after this one).', $repr, $param->getName())); } } return $arguments; } protected function createController($controller) { if (false === strpos($controller, '::')) { throw new \InvalidArgumentException(sprintf('Unable to find controller "%s".', $controller)); } list($class, $method) = explode('::', $controller, 2); if (!class_exists($class)) { throw new \InvalidArgumentException(sprintf('Class "%s" does not exist.', $class)); } return array(new $class(), $method); } } <?php namespace Symfony\Component\HttpKernel\Controller; use Symfony\Component\HttpFoundation\Request; interface ControllerResolverInterface { function getController(Request $request); function getArguments(Request $request, $controller); } <?php namespace Symfony\Component\HttpKernel\DataCollector; use Symfony\Component\HttpKernel\KernelInterface; use Symfony\Component\HttpKernel\Kernel; use Symfony\Component\HttpKernel\DataCollector\DataCollector; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; class ConfigDataCollector extends DataCollector { private $kernel; public function __construct(KernelInterface $kernel) { $this->kernel = $kernel; } public function collect(Request $request, Response $response, \Exception $exception = null) { $this->data = array( 'token' => $response->headers->get('X-Debug-Token'), 'symfony_version' => Kernel::VERSION, 'name' => $this->kernel->getName(), 'env' => $this->kernel->getEnvironment(), 'debug' => $this->kernel->isDebug(), 'php_version' => PHP_VERSION, 'xdebug_enabled' => extension_loaded('xdebug'), 'eaccel_enabled' => extension_loaded('eaccelerator') && ini_get('eaccelerator.enable'), 'apc_enabled' => extension_loaded('apc') && ini_get('apc.enabled'), 'xcache_enabled' => extension_loaded('xcache') && ini_get('xcache.cacher'), 'bundles' => array(), ); foreach ($this->kernel->getBundles() as $name => $bundle) { $this->data['bundles'][$name] = $bundle->getPath(); } } public function getToken() { return $this->data['token']; } public function getSymfonyVersion() { return $this->data['symfony_version']; } public function getPhpVersion() { return $this->data['php_version']; } public function getAppName() { return $this->data['name']; } public function getEnv() { return $this->data['env']; } public function isDebug() { return $this->data['debug']; } public function hasXDebug() { return $this->data['xdebug_enabled']; } public function hasEAccelerator() { return $this->data['eaccel_enabled']; } public function hasApc() { return $this->data['apc_enabled']; } public function hasXCache() { return $this->data['xcache_enabled']; } public function hasAccelerator() { return $this->hasApc() || $this->hasEAccelerator() || $this->hasXCache(); } public function getBundles() { return $this->data['bundles']; } public function getName() { return 'config'; } } <?php namespace Symfony\Component\HttpKernel\DataCollector; use Symfony\Component\HttpKernel\Profiler\Profiler; abstract class DataCollector implements DataCollectorInterface, \Serializable { protected $data; public function serialize() { return serialize($this->data); } public function unserialize($data) { $this->data = unserialize($data); } } <?php namespace Symfony\Component\HttpKernel\DataCollector; use Symfony\Component\HttpKernel\Profiler\Profiler; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; interface DataCollectorInterface { function collect(Request $request, Response $response, \Exception $exception = null); function getName(); } <?php namespace Symfony\Component\HttpKernel\DataCollector; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\EventDispatcher\Debug\TraceableEventDispatcherInterface; use Symfony\Component\EventDispatcher\EventDispatcherInterface; class EventDataCollector extends DataCollector { private $dispatcher; public function setEventDispatcher(EventDispatcherInterface $dispatcher) { if ($dispatcher instanceof TraceableEventDispatcherInterface) { $this->dispatcher = $dispatcher; } } public function collect(Request $request, Response $response, \Exception $exception = null) { $this->data = array( 'called_listeners' => null !== $this->dispatcher ? $this->dispatcher->getCalledListeners() : array(), 'not_called_listeners' => null !== $this->dispatcher ? $this->dispatcher->getNotCalledListeners() : array(), ); } public function getCalledListeners() { return $this->data['called_listeners']; } public function getNotCalledListeners() { return $this->data['not_called_listeners']; } public function getName() { return 'events'; } } <?php namespace Symfony\Component\HttpKernel\DataCollector; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\Exception\FlattenException; use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface; class ExceptionDataCollector extends DataCollector { public function collect(Request $request, Response $response, \Exception $exception = null) { if (null !== $exception) { $flattenException = FlattenException::create($exception); if ($exception instanceof HttpExceptionInterface) { $flattenException->setStatusCode($exception->getStatusCode()); } $this->data = array( 'exception' => $flattenException, ); } } public function hasException() { return isset($this->data['exception']); } public function getException() { return $this->data['exception']; } public function getMessage() { return $this->data['exception']->getMessage(); } public function getCode() { return $this->data['exception']->getCode(); } public function getStatusCode() { return $this->data['exception']->getStatusCode(); } public function getTrace() { return $this->data['exception']->getTrace(); } public function getName() { return 'exception'; } } <?php namespace Symfony\Component\HttpKernel\DataCollector; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\Log\DebugLoggerInterface; class LoggerDataCollector extends DataCollector { private $logger; public function __construct($logger = null) { if (null !== $logger && $logger instanceof DebugLoggerInterface) { $this->logger = $logger; } } public function collect(Request $request, Response $response, \Exception $exception = null) { if (null !== $this->logger) { $this->data = array( 'error_count' => $this->logger->countErrors(), 'logs' => $this->sanitizeLogs($this->logger->getLogs()), ); } } public function countErrors() { return isset($this->data['error_count']) ? $this->data['error_count'] : 0; } public function getLogs() { return isset($this->data['logs']) ? $this->data['logs'] : array(); } public function getName() { return 'logger'; } private function sanitizeLogs($logs) { foreach ($logs as $i => $log) { $logs[$i]['context'] = $this->sanitizeContext($log['context']); } return $logs; } private function sanitizeContext($context) { if (is_array($context)) { foreach ($context as $key => $value) { $context[$key] = $this->sanitizeContext($value); } return $context; } if (is_resource($context)) { return sprintf('Resource(%s)', get_resource_type($context)); } if (is_object($context)) { return sprintf('Object(%s)', get_class($context)); } return $context; } } <?php namespace Symfony\Component\HttpKernel\DataCollector; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; class MemoryDataCollector extends DataCollector { public function collect(Request $request, Response $response, \Exception $exception = null) { $this->data = array( 'memory' => memory_get_peak_usage(true), ); } public function getMemory() { return $this->data['memory']; } public function getName() { return 'memory'; } } <?php namespace Symfony\Component\HttpKernel\DataCollector; use Symfony\Component\HttpFoundation\Cookie; use Symfony\Component\HttpFoundation\ParameterBag; use Symfony\Component\HttpFoundation\HeaderBag; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpFoundation\ResponseHeaderBag; class RequestDataCollector extends DataCollector { public function collect(Request $request, Response $response, \Exception $exception = null) { $responseHeaders = $response->headers->all(); $cookies = array(); foreach ($response->headers->getCookies() as $cookie) { $cookies[] = $this->getCookieHeader($cookie->getName(), $cookie->getValue(), $cookie->getExpiresTime(), $cookie->getPath(), $cookie->getDomain(), $cookie->isSecure(), $cookie->isHttpOnly()); } if (count($cookies) > 0) { $responseHeaders['Set-Cookie'] = $cookies; } $attributes = array(); foreach ($request->attributes->all() as $key => $value) { if (is_object($value)) { $attributes[$key] = sprintf('Object(%s)', get_class($value)); if (is_callable(array($value, '__toString'))) { $attributes[$key] .= sprintf(' = %s', (string) $value); } } else { $attributes[$key] = $value; } } $content = null; try { $content = $request->getContent(); } catch (\LogicException $e) { $content = false; } $this->data = array( 'format' => $request->getRequestFormat(), 'content' => $content, 'content_type' => $response->headers->get('Content-Type') ? $response->headers->get('Content-Type') : 'text/html', 'status_code' => $response->getStatusCode(), 'request_query' => $request->query->all(), 'request_request' => $request->request->all(), 'request_headers' => $request->headers->all(), 'request_server' => $request->server->all(), 'request_cookies' => $request->cookies->all(), 'request_attributes' => $attributes, 'response_headers' => $responseHeaders, 'session_attributes' => $request->hasSession() ? $request->getSession()->all() : array(), 'flashes' => $request->hasSession() ? $request->getSession()->getFlashBag()->peekAll() : array(), 'path_info' => $request->getPathInfo(), ); } public function getPathInfo() { return $this->data['path_info']; } public function getRequestRequest() { return new ParameterBag($this->data['request_request']); } public function getRequestQuery() { return new ParameterBag($this->data['request_query']); } public function getRequestHeaders() { return new HeaderBag($this->data['request_headers']); } public function getRequestServer() { return new ParameterBag($this->data['request_server']); } public function getRequestCookies() { return new ParameterBag($this->data['request_cookies']); } public function getRequestAttributes() { return new ParameterBag($this->data['request_attributes']); } public function getResponseHeaders() { return new ResponseHeaderBag($this->data['response_headers']); } public function getSessionAttributes() { return $this->data['session_attributes']; } public function getFlashes() { return $this->data['flashes']; } public function getContent() { return $this->data['content']; } public function getContentType() { return $this->data['content_type']; } public function getStatusCode() { return $this->data['status_code']; } public function getFormat() { return $this->data['format']; } public function getName() { return 'request'; } private function getCookieHeader($name, $value, $expires, $path, $domain, $secure, $httponly) { $cookie = sprintf('%s=%s', $name, urlencode($value)); if (0 !== $expires) { if (is_numeric($expires)) { $expires = (int) $expires; } elseif ($expires instanceof \DateTime) { $expires = $expires->getTimestamp(); } else { $expires = strtotime($expires); if (false === $expires || -1 == $expires) { throw new \InvalidArgumentException(sprintf('The "expires" cookie parameter is not valid.', $expires)); } } $cookie .= '; expires='.substr(\DateTime::createFromFormat('U', $expires, new \DateTimeZone('UTC'))->format('D, d-M-Y H:i:s T'), 0, -5); } if ($domain) { $cookie .= '; domain='.$domain; } $cookie .= '; path='.$path; if ($secure) { $cookie .= '; secure'; } if ($httponly) { $cookie .= '; httponly'; } return $cookie; } } <?php namespace Symfony\Component\HttpKernel\DataCollector; use Symfony\Component\HttpKernel\DataCollector\DataCollector; use Symfony\Component\HttpKernel\KernelInterface; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; class TimeDataCollector extends DataCollector { protected $kernel; public function __construct(KernelInterface $kernel = null) { $this->kernel = $kernel; } public function collect(Request $request, Response $response, \Exception $exception = null) { $this->data = array( 'start_time' => (null !== $this->kernel ? $this->kernel->getStartTime() : $_SERVER['REQUEST_TIME']) * 1000, 'events' => array(), ); } public function setEvents(array $events) { foreach ($events as $event) { $event->ensureStopped(); } $this->data['events'] = $events; } public function getEvents() { return $this->data['events']; } public function getTotalTime() { $lastEvent = $this->data['events']['__section__']; return $lastEvent->getOrigin() + $lastEvent->getTotalTime() - $this->data['start_time']; } public function getInitTime() { return $this->data['events']['__section__']->getOrigin() - $this->getStartTime(); } public function getStartTime() { return $this->data['start_time']; } public function getName() { return 'time'; } } <?php namespace Symfony\Component\HttpKernel\Debug; use Symfony\Component\HttpKernel\Debug\Stopwatch; use Symfony\Component\HttpKernel\Log\LoggerInterface; use Symfony\Component\HttpKernel\Profiler\Profile; use Symfony\Component\HttpKernel\Profiler\Profiler; use Symfony\Component\HttpKernel\HttpKernelInterface; use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\EventDispatcher\Event; use Symfony\Component\EventDispatcher\ContainerAwareEventDispatcher; use Symfony\Component\EventDispatcher\Debug\TraceableEventDispatcherInterface; class ContainerAwareTraceableEventDispatcher extends ContainerAwareEventDispatcher implements TraceableEventDispatcherInterface { private $logger; private $called; private $stopwatch; private $priorities; private $profiler; public function __construct(ContainerInterface $container, Stopwatch $stopwatch, LoggerInterface $logger = null) { parent::__construct($container); $this->stopwatch = $stopwatch; $this->logger = $logger; $this->called = array(); } public function dispatch($eventName, Event $event = null) { switch ($eventName) { case 'kernel.request': $this->stopwatch->openSection(); break; case 'kernel.view': case 'kernel.response': try { $this->stopwatch->stop('controller'); } catch (\LogicException $e) { } break; case 'kernel.terminate': $token = $event->getResponse()->headers->get('X-Debug-Token'); $this->stopwatch->openSection($token); break; } $e1 = $this->stopwatch->start($eventName, 'section'); parent::dispatch($eventName, $event); $e1->stop(); switch ($eventName) { case 'kernel.controller': $this->stopwatch->start('controller', 'section'); break; case 'kernel.response': $token = $event->getResponse()->headers->get('X-Debug-Token'); $this->stopwatch->stopSection($token); if (HttpKernelInterface::MASTER_REQUEST === $event->getRequestType()) { $this->updateProfiles($token, true); } break; case 'kernel.terminate': $this->stopwatch->stopSection($token); $this->updateProfiles($token, false); break; } return $event; } public function addListener($eventName, $listener, $priority = 0) { if (!is_callable($listener)) { throw new \RuntimeException(sprintf('The given callback (%s) for event "%s" is not callable.', $this->getListenerAsString($listener), $eventName)); } $this->priorities[$eventName.'_'.$this->getListenerAsString($listener)] = $priority; parent::addListener($eventName, $listener, $priority); } protected function doDispatch($listeners, $eventName, Event $event) { foreach ($listeners as $listener) { $info = $this->getListenerInfo($listener, $eventName); if (null !== $this->logger) { $this->logger->debug(sprintf('Notified event "%s" to listener "%s".', $eventName, $info['pretty'])); } $this->called[$eventName.'.'.$info['pretty']] = $info; $e2 = $this->stopwatch->start(isset($info['class']) ? substr($info['class'], strrpos($info['class'], '\\') + 1) : $info['type'], 'event_listener'); call_user_func($listener, $event); $e2->stop(); if ($event->isPropagationStopped()) { if (null !== $this->logger) { $this->logger->debug(sprintf('Listener "%s" stopped propagation of the event "%s".', $info['pretty'], $eventName)); $skippedListeners = $this->getListeners($eventName); $skipped = false; foreach ($skippedListeners as $skippedListener) { if ($skipped) { $info = $this->getListenerInfo($skippedListener, $eventName); $this->logger->debug(sprintf('Listener "%s" was not called for event "%s".', $info['pretty'], $eventName)); } if ($skippedListener === $listener) { $skipped = true; } } } break; } } } protected function lazyLoad($eventName) { $e = $this->stopwatch->start($eventName.'.loading', 'event_listener_loading'); parent::lazyLoad($eventName); $e->stop(); } public function getCalledListeners() { return $this->called; } public function getNotCalledListeners() { $notCalled = array(); foreach ($this->getListeners() as $name => $listeners) { foreach ($listeners as $listener) { $info = $this->getListenerInfo($listener, $name); if (!isset($this->called[$name.'.'.$info['pretty']])) { $notCalled[$name.'.'.$info['pretty']] = $info; } } } return $notCalled; } private function getListenerInfo($listener, $eventName) { $info = array( 'event' => $eventName, 'priority' => $this->priorities[$eventName.'_'.$this->getListenerAsString($listener)], ); if ($listener instanceof \Closure) { $info += array( 'type' => 'Closure', 'pretty' => 'closure' ); } elseif (is_string($listener)) { try { $r = new \ReflectionFunction($listener); $file = $r->getFileName(); $line = $r->getStartLine(); } catch (\ReflectionException $e) { $file = null; $line = null; } $info += array( 'type' => 'Function', 'function' => $listener, 'file' => $file, 'line' => $line, 'pretty' => $listener, ); } elseif (is_array($listener) || (is_object($listener) && is_callable($listener))) { if (!is_array($listener)) { $listener = array($listener, '__invoke'); } $class = is_object($listener[0]) ? get_class($listener[0]) : $listener[0]; try { $r = new \ReflectionMethod($class, $listener[1]); $file = $r->getFileName(); $line = $r->getStartLine(); } catch (\ReflectionException $e) { $file = null; $line = null; } $info += array( 'type' => 'Method', 'class' => $class, 'method' => $listener[1], 'file' => $file, 'line' => $line, 'pretty' => $class.'::'.$listener[1], ); } return $info; } private function updateProfiles($token, $updateChildren) { if (!$this->getContainer()->has('profiler')) { return; } $this->profiler = $this->getContainer()->get('profiler'); if (!$profile = $this->profiler->loadProfile($token)) { return; } $this->saveStopwatchInfoInProfile($profile, $updateChildren); } private function saveStopwatchInfoInProfile(Profile $profile, $updateChildren) { $profile->getCollector('time')->setEvents($this->stopwatch->getSectionEvents($profile->getToken())); $this->profiler->saveProfile($profile); if ($updateChildren) { foreach ($profile->getChildren() as $child) { $this->saveStopwatchInfoInProfile($child, true); } } } private function getListenerAsString($listener) { if (is_string($listener)) { return '[string] '.$listener; } elseif (is_array($listener)) { return '[array] '.(is_object($listener[0]) ? get_class($listener[0]) : $listener[0]).'::'.$listener[1]; } elseif (is_object($listener)) { return '[object] '.get_class($listener); } return '[?] '.var_export($listener, true); } } <?php namespace Symfony\Component\HttpKernel\Debug; class ErrorHandler { private $levels = array( E_WARNING => 'Warning', E_NOTICE => 'Notice', E_USER_ERROR => 'User Error', E_USER_WARNING => 'User Warning', E_USER_NOTICE => 'User Notice', E_STRICT => 'Runtime Notice', E_RECOVERABLE_ERROR => 'Catchable Fatal Error', E_DEPRECATED => 'Deprecated', E_USER_DEPRECATED => 'User Deprecated', ); private $level; static public function register($level = null) { $handler = new static(); $handler->setLevel($level); set_error_handler(array($handler, 'handle')); return $handler; } public function setLevel($level) { $this->level = null === $level ? error_reporting() : $level; } public function handle($level, $message, $file, $line, $context) { if (0 === $this->level) { return false; } if (error_reporting() & $level && $this->level & $level) { throw new \ErrorException(sprintf('%s: %s in %s line %d', isset($this->levels[$level]) ? $this->levels[$level] : $level, $message, $file, $line)); } return false; } } <?php namespace Symfony\Component\HttpKernel\Debug; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\Exception\FlattenException; if (!defined('ENT_SUBSTITUTE')) { define('ENT_SUBSTITUTE', 8); } class ExceptionHandler { private $debug; private $charset; public function __construct($debug = true, $charset = 'UTF-8') { $this->debug = $debug; $this->charset = $charset; } static public function register($debug = true) { $handler = new static($debug); set_exception_handler(array($handler, 'handle')); return $handler; } public function handle(\Exception $exception) { $this->createResponse($exception)->send(); } public function createResponse($exception) { $content = ''; $title = ''; try { if (!$exception instanceof FlattenException) { $exception = FlattenException::create($exception); } switch ($exception->getStatusCode()) { case 404: $title = 'Sorry, the page you are looking for could not be found.'; break; default: $title = 'Whoops, looks like something went wrong.'; } if ($this->debug) { $content = $this->getContent($exception); } } catch (\Exception $e) { if ($this->debug) { $title = sprintf('Exception thrown when handling an exception (%s: %s)', get_class($exception), $exception->getMessage()); } else { $title = 'Whoops, looks like something went wrong.'; } } return new Response($this->decorate($content, $title), $exception->getStatusCode()); } private function getContent($exception) { $message = nl2br($exception->getMessage()); $class = $this->abbrClass($exception->getClass()); $count = count($exception->getAllPrevious()); $content = ''; foreach ($exception->toArray() as $position => $e) { $ind = $count - $position + 1; $total = $count + 1; $class = $this->abbrClass($e['class']); $message = nl2br($e['message']); $content .= sprintf(<<<EOF <div class="block_exception clear_fix"> <h2><span>%d/%d</span> %s: %s</h2> </div> <div class="block"> <ol class="traces list_exception"> EOF , $ind, $total, $class, $message); foreach ($e['trace'] as $i => $trace) { $content .= ' <li>'; if ($trace['function']) { $content .= sprintf('at %s%s%s(%s)', $this->abbrClass($trace['class']), $trace['type'], $trace['function'], $this->formatArgs($trace['args'])); } if (isset($trace['file']) && isset($trace['line'])) { if ($linkFormat = ini_get('xdebug.file_link_format')) { $link = str_replace(array('%f', '%l'), array($trace['file'], $trace['line']), $linkFormat); $content .= sprintf(' in <a href="%s" title="Go to source">%s line %s</a>', $link, $trace['file'], $trace['line']); } else { $content .= sprintf(' in %s line %s', $trace['file'], $trace['line']); } } $content .= "</li>\n"; } $content .= " </ol>\n</div>\n"; } return $content; } private function decorate($content, $title) { return <<<EOF <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> <meta name="robots" content="noindex,nofollow" /> <title>{$title}</title> <style> /* Copyright (c) 2010, Yahoo! Inc. All rights reserved. Code licensed under the BSD License: http://developer.yahoo.com/yui/license.html */ html{color:#000;background:#FFF;}body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,code,form,fieldset,legend,input,textarea,p,blockquote,th,td{margin:0;padding:0;}table{border-collapse:collapse;border-spacing:0;}fieldset,img{border:0;}address,caption,cite,code,dfn,em,strong,th,var{font-style:normal;font-weight:normal;}li{list-style:none;}caption,th{text-align:left;}h1,h2,h3,h4,h5,h6{font-size:100%;font-weight:normal;}q:before,q:after{content:'';}abbr,acronym{border:0;font-variant:normal;}sup{vertical-align:text-top;}sub{vertical-align:text-bottom;}input,textarea,select{font-family:inherit;font-size:inherit;font-weight:inherit;}input,textarea,select{*font-size:100%;}legend{color:#000;} html { background: #eee; padding: 10px } body { font: 11px Verdana, Arial, sans-serif; color: #333 } img { border: 0; } .clear { clear:both; height:0; font-size:0; line-height:0; } .clear_fix:after { display:block; height:0; clear:both; visibility:hidden; } .clear_fix { display:inline-block; } * html .clear_fix { height:1%; } .clear_fix { display:block; } #content { width:970px; margin:0 auto; } .sf-exceptionreset, .sf-exceptionreset .block { margin: auto } .sf-exceptionreset abbr { border-bottom: 1px dotted #000; cursor: help; } .sf-exceptionreset p { font-size:14px; line-height:20px; color:#868686; padding-bottom:20px } .sf-exceptionreset strong { font-weight:bold; } .sf-exceptionreset a { color:#6c6159; } .sf-exceptionreset a img { border:none; } .sf-exceptionreset a:hover { text-decoration:underline; } .sf-exceptionreset em { font-style:italic; } .sf-exceptionreset h1, .sf-exceptionreset h2 { font: 20px Georgia, "Times New Roman", Times, serif } .sf-exceptionreset h2 span { background-color: #fff; color: #333; padding: 6px; float: left; margin-right: 10px; } .sf-exceptionreset .traces li { font-size:12px; padding: 2px 4px; list-style-type:decimal; margin-left:20px; } .sf-exceptionreset .block { background-color:#FFFFFF; padding:10px 28px; margin-bottom:20px; -webkit-border-bottom-right-radius: 16px; -webkit-border-bottom-left-radius: 16px; -moz-border-radius-bottomright: 16px; -moz-border-radius-bottomleft: 16px; border-bottom-right-radius: 16px; border-bottom-left-radius: 16px; border-bottom:1px solid #ccc; border-right:1px solid #ccc; border-left:1px solid #ccc; } .sf-exceptionreset .block_exception { background-color:#ddd; color: #333; padding:20px; -webkit-border-top-left-radius: 16px; -webkit-border-top-right-radius: 16px; -moz-border-radius-topleft: 16px; -moz-border-radius-topright: 16px; border-top-left-radius: 16px; border-top-right-radius: 16px; border-top:1px solid #ccc; border-right:1px solid #ccc; border-left:1px solid #ccc; } .sf-exceptionreset li a { background:none; color:#868686; text-decoration:none; } .sf-exceptionreset li a:hover { background:none; color:#313131; text-decoration:underline; } .sf-exceptionreset ol { padding: 10px 0; } .sf-exceptionreset h1 { background-color:#FFFFFF; padding: 15px 28px; margin-bottom: 20px; -webkit-border-radius: 10px; -moz-border-radius: 10px; border-radius: 10px; border: 1px solid #ccc; } </style> </head> <body> <div id="content" class="sf-exceptionreset"> <h1>$title</h1> $content </div> </body> </html> EOF; } private function abbrClass($class) { $parts = explode('\\', $class); return sprintf("<abbr title=\"%s\">%s</abbr>", $class, array_pop($parts)); } public function formatArgs(array $args) { $result = array(); foreach ($args as $key => $item) { if ('object' === $item[0]) { $formattedValue = sprintf("<em>object</em>(%s)", $this->abbrClass($item[1])); } elseif ('array' === $item[0]) { $formattedValue = sprintf("<em>array</em>(%s)", is_array($item[1]) ? $this->formatArgs($item[1]) : $item[1]); } elseif ('string' === $item[0]) { $formattedValue = sprintf("'%s'", htmlspecialchars($item[1], ENT_QUOTES | ENT_SUBSTITUTE, $this->charset)); } elseif ('null' === $item[0]) { $formattedValue = '<em>null</em>'; } elseif ('boolean' === $item[0]) { $formattedValue = '<em>'.strtolower(var_export($item[1], true)).'</em>'; } elseif ('resource' === $item[0]) { $formattedValue = '<em>resource</em>'; } else { $formattedValue = str_replace("\n", '', var_export(htmlspecialchars((string) $item[1], ENT_QUOTES | ENT_SUBSTITUTE, $this->charset), true)); } $result[] = is_int($key) ? $formattedValue : sprintf("'%s' => %s", $key, $formattedValue); } return implode(', ', $result); } } <?php namespace Symfony\Component\HttpKernel\Debug; class Stopwatch { private $sections; private $activeSections; public function __construct() { $this->sections = $this->activeSections = array('__root__' => new Section('__root__')); } public function openSection($id = null) { $current = end($this->activeSections); if (null !== $id && null === $current->get($id)) { throw new \LogicException(sprintf('The section "%s" has been started at an other level and can not be opened.', $id)); } $this->start('__section__.child', 'section'); $this->activeSections[] = $current->open($id); $this->start('__section__'); } public function stopSection($id) { $this->stop('__section__'); if (1 == count($this->activeSections)) { throw new \LogicException('There is no started section to stop.'); } $this->sections[$id] = array_pop($this->activeSections)->setId($id); $this->stop('__section__.child'); } public function start($name, $category = null) { return end($this->activeSections)->startEvent($name, $category); } public function stop($name) { return end($this->activeSections)->stopEvent($name); } public function lap($name) { return end($this->activeSections)->stopEvent($name)->start(); } public function getSectionEvents($id) { return isset($this->sections[$id]) ? $this->sections[$id]->getEvents() : array(); } } class Section { private $events = array(); private $origin; private $id; private $children = array(); public function __construct($origin = null) { $this->origin = is_numeric($origin) ? $origin : null; } public function get($id) { foreach ($this->children as $child) { if ($id === $child->getId()) { return $child; } } return null; } public function open($id) { if (null === $session = $this->get($id)) { $session = $this->children[] = new self(microtime(true) * 1000); } return $session; } public function getId() { return $this->id; } public function setId($id) { $this->id = $id; return $this; } public function startEvent($name, $category) { if (!isset($this->events[$name])) { $this->events[$name] = new StopwatchEvent($this->origin ?: microtime(true) * 1000, $category); } return $this->events[$name]->start(); } public function stopEvent($name) { if (!isset($this->events[$name])) { throw new \LogicException(sprintf('Event "%s" is not started.', $name)); } return $this->events[$name]->stop(); } public function lap($name) { return $this->stop($name)->start(); } public function getEvents() { return $this->events; } } <?php namespace Symfony\Component\HttpKernel\Debug; class StopwatchEvent { private $periods; private $origin; private $category; private $started; public function __construct($origin, $category = null) { $this->origin = $this->formatTime($origin); $this->category = is_string($category) ? $category : 'default'; $this->started = array(); $this->periods = array(); } public function getCategory() { return $this->category; } public function getOrigin() { return $this->origin; } public function start() { $this->started[] = $this->getNow(); return $this; } public function stop() { if (!count($this->started)) { throw new \LogicException('stop() called but start() has not been called before.'); } $this->periods[] = array(array_pop($this->started), $this->getNow()); return $this; } public function lap() { return $this->stop()->start(); } public function ensureStopped() { while (count($this->started)) { $this->stop(); } } public function getPeriods() { return $this->periods; } public function getStartTime() { return isset($this->periods[0]) ? $this->periods[0][0] : 0; } public function getEndTime() { return ($count = count($this->periods)) ? $this->periods[$count - 1][1] : 0; } public function getTotalTime() { $total = 0; foreach ($this->periods as $period) { $total += $period[1] - $period[0]; } return $this->formatTime($total); } protected function getNow() { return $this->formatTime(microtime(true) * 1000 - $this->origin); } private function formatTime($time) { if (!is_numeric($time)) { throw new \InvalidArgumentException('The time must be a numerical value'); } return round($time, 1); } } <?php namespace Symfony\Component\HttpKernel\DependencyInjection; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; use Symfony\Component\HttpKernel\DependencyInjection\Extension; use Symfony\Component\HttpKernel\Kernel; class AddClassesToCachePass implements CompilerPassInterface { private $kernel; public function __construct(Kernel $kernel) { $this->kernel = $kernel; } public function process(ContainerBuilder $container) { $classes = array(); foreach ($container->getExtensions() as $extension) { if ($extension instanceof Extension) { $classes = array_merge($classes, $extension->getClassesToCompile()); } } $this->kernel->setClassCache(array_unique($container->getParameterBag()->resolveValue($classes))); } } <?php namespace Symfony\Component\HttpKernel\DependencyInjection; use Symfony\Component\DependencyInjection\ContainerBuilder; abstract class ConfigurableExtension extends Extension { public final function load(array $configs, ContainerBuilder $container) { $this->loadInternal($this->processConfiguration($this->getConfiguration(array(), $container), $configs), $container); } abstract protected function loadInternal(array $mergedConfig, ContainerBuilder $container); } <?php namespace Symfony\Component\HttpKernel\DependencyInjection; use Symfony\Component\Config\Definition\Processor; use Symfony\Component\Config\Definition\ConfigurationInterface; use Symfony\Component\DependencyInjection\Extension\ExtensionInterface; use Symfony\Component\DependencyInjection\Extension\ConfigurationExtensionInterface; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Container; abstract class Extension implements ExtensionInterface, ConfigurationExtensionInterface { private $classes = array(); public function getClassesToCompile() { return $this->classes; } public function addClassesToCompile(array $classes) { $this->classes = array_merge($this->classes, $classes); } public function getXsdValidationBasePath() { return false; } public function getNamespace() { return 'http://example.org/schema/dic/'.$this->getAlias(); } public function getAlias() { $className = get_class($this); if (substr($className, -9) != 'Extension') { throw new \BadMethodCallException('This extension does not follow the naming convention; you must overwrite the getAlias() method.'); } $classBaseName = substr(strrchr($className, '\\'), 1, -9); return Container::underscore($classBaseName); } protected final function processConfiguration(ConfigurationInterface $configuration, array $configs) { $processor = new Processor(); return $processor->processConfiguration($configuration, $configs); } public function getConfiguration(array $config, ContainerBuilder $container) { $reflected = new \ReflectionClass($this); $namespace = $reflected->getNamespaceName(); $class = $namespace . '\\Configuration'; if (class_exists($class)) { if (!method_exists($class, '__construct')) { $configuration = new $class(); return $configuration; } } return null; } } <?php namespace Symfony\Component\HttpKernel\DependencyInjection; use Symfony\Component\DependencyInjection\Compiler\MergeExtensionConfigurationPass as BaseMergeExtensionConfigurationPass; use Symfony\Component\DependencyInjection\ContainerBuilder; class MergeExtensionConfigurationPass extends BaseMergeExtensionConfigurationPass { private $extensions; public function __construct(array $extensions) { $this->extensions = $extensions; } public function process(ContainerBuilder $container) { foreach ($this->extensions as $extension) { if (!count($container->getExtensionConfig($extension))) { $container->loadFromExtension($extension, array()); } } parent::process($container); } } <?php namespace Symfony\Component\HttpKernel\Event; use Symfony\Component\HttpKernel\HttpKernelInterface; use Symfony\Component\HttpFoundation\Request; class FilterControllerEvent extends KernelEvent { private $controller; public function __construct(HttpKernelInterface $kernel, $controller, Request $request, $requestType) { parent::__construct($kernel, $request, $requestType); $this->setController($controller); } public function getController() { return $this->controller; } public function setController($controller) { if (!is_callable($controller)) { throw new \LogicException(sprintf('The controller must be a callable (%s given).', $this->varToString($controller))); } $this->controller = $controller; } private function varToString($var) { if (is_object($var)) { return sprintf('Object(%s)', get_class($var)); } if (is_array($var)) { $a = array(); foreach ($var as $k => $v) { $a[] = sprintf('%s => %s', $k, $this->varToString($v)); } return sprintf("Array(%s)", implode(', ', $a)); } if (is_resource($var)) { return sprintf('Resource(%s)', get_resource_type($var)); } if (null === $var) { return 'null'; } if (false === $var) { return 'false'; } if (true === $var) { return 'true'; } return (string) $var; } } <?php namespace Symfony\Component\HttpKernel\Event; use Symfony\Component\HttpKernel\HttpKernelInterface; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; class FilterResponseEvent extends KernelEvent { private $response; public function __construct(HttpKernelInterface $kernel, Request $request, $requestType, Response $response) { parent::__construct($kernel, $request, $requestType); $this->setResponse($response); } public function getResponse() { return $this->response; } public function setResponse(Response $response) { $this->response = $response; } } <?php namespace Symfony\Component\HttpKernel\Event; use Symfony\Component\HttpFoundation\Response; class GetResponseEvent extends KernelEvent { private $response; public function getResponse() { return $this->response; } public function setResponse(Response $response) { $this->response = $response; $this->stopPropagation(); } public function hasResponse() { return null !== $this->response; } } <?php namespace Symfony\Component\HttpKernel\Event; use Symfony\Component\HttpKernel\HttpKernelInterface; use Symfony\Component\HttpFoundation\Request; class GetResponseForControllerResultEvent extends GetResponseEvent { private $controllerResult; public function __construct(HttpKernelInterface $kernel, Request $request, $requestType, $controllerResult) { parent::__construct($kernel, $request, $requestType); $this->controllerResult = $controllerResult; } public function getControllerResult() { return $this->controllerResult; } } <?php namespace Symfony\Component\HttpKernel\Event; use Symfony\Component\HttpKernel\HttpKernelInterface; use Symfony\Component\HttpFoundation\Request; class GetResponseForExceptionEvent extends GetResponseEvent { private $exception; public function __construct(HttpKernelInterface $kernel, Request $request, $requestType, \Exception $e) { parent::__construct($kernel, $request, $requestType); $this->setException($e); } public function getException() { return $this->exception; } public function setException(\Exception $exception) { $this->exception = $exception; } } <?php namespace Symfony\Component\HttpKernel\Event; use Symfony\Component\HttpKernel\HttpKernelInterface; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\EventDispatcher\Event; class KernelEvent extends Event { private $kernel; private $request; private $requestType; public function __construct(HttpKernelInterface $kernel, Request $request, $requestType) { $this->kernel = $kernel; $this->request = $request; $this->requestType = $requestType; } public function getKernel() { return $this->kernel; } public function getRequest() { return $this->request; } public function getRequestType() { return $this->requestType; } } <?php namespace Symfony\Component\HttpKernel\Event; use Symfony\Component\HttpKernel\HttpKernelInterface; use Symfony\Component\EventDispatcher\Event; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; class PostResponseEvent extends Event { private $kernel; private $request; private $response; public function __construct(HttpKernelInterface $kernel, Request $request, Response $response) { $this->kernel = $kernel; $this->request = $request; $this->response = $response; } public function getKernel() { return $this->kernel; } public function getRequest() { return $this->request; } public function getResponse() { return $this->response; } } <?php namespace Symfony\Component\HttpKernel\EventListener; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\HttpKernelInterface; use Symfony\Component\HttpKernel\Event\FilterResponseEvent; use Symfony\Component\HttpKernel\KernelEvents; use Symfony\Component\HttpKernel\HttpCache\Esi; use Symfony\Component\EventDispatcher\EventSubscriberInterface; class EsiListener implements EventSubscriberInterface { private $esi; public function __construct(Esi $esi = null) { $this->esi = $esi; } public function onKernelResponse(FilterResponseEvent $event) { if (HttpKernelInterface::MASTER_REQUEST !== $event->getRequestType() || null === $this->esi) { return; } $this->esi->addSurrogateControl($event->getResponse()); } static public function getSubscribedEvents() { return array( KernelEvents::RESPONSE => 'onKernelResponse', ); } } <?php namespace Symfony\Component\HttpKernel\EventListener; use Symfony\Component\HttpKernel\Log\LoggerInterface; use Symfony\Component\HttpKernel\Log\DebugLoggerInterface; use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent; use Symfony\Component\HttpKernel\KernelEvents; use Symfony\Component\HttpKernel\HttpKernelInterface; use Symfony\Component\HttpKernel\Exception\FlattenException; use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface; use Symfony\Component\EventDispatcher\EventSubscriberInterface; class ExceptionListener implements EventSubscriberInterface { private $controller; private $logger; public function __construct($controller, LoggerInterface $logger = null) { $this->controller = $controller; $this->logger = $logger; } public function onKernelException(GetResponseForExceptionEvent $event) { static $handling; if (true === $handling) { return false; } $handling = true; $exception = $event->getException(); $request = $event->getRequest(); if (null !== $this->logger) { $message = sprintf('%s: %s (uncaught exception) at %s line %s', get_class($exception), $exception->getMessage(), $exception->getFile(), $exception->getLine()); if (!$exception instanceof HttpExceptionInterface || $exception->getStatusCode() >= 500) { $this->logger->crit($message); } else { $this->logger->err($message); } } else { error_log(sprintf('Uncaught PHP Exception %s: "%s" at %s line %s', get_class($exception), $exception->getMessage(), $exception->getFile(), $exception->getLine())); } $logger = $this->logger instanceof DebugLoggerInterface ? $this->logger : null; $flattenException = FlattenException::create($exception); if ($exception instanceof HttpExceptionInterface) { $flattenException->setStatusCode($exception->getStatusCode()); $flattenException->setHeaders($exception->getHeaders()); } $attributes = array( '_controller' => $this->controller, 'exception' => $flattenException, 'logger' => $logger, 'format' => $request->getRequestFormat(), ); $request = $request->duplicate(null, null, $attributes); $request->setMethod('GET'); try { $response = $event->getKernel()->handle($request, HttpKernelInterface::SUB_REQUEST, true); } catch (\Exception $e) { $message = sprintf('Exception thrown when handling an exception (%s: %s)', get_class($e), $e->getMessage()); if (null !== $this->logger) { if (!$exception instanceof HttpExceptionInterface || $exception->getStatusCode() >= 500) { $this->logger->crit($message); } else { $this->logger->err($message); } } else { error_log($message); } $handling = false; throw $exception; } $event->setResponse($response); $handling = false; } static public function getSubscribedEvents() { return array( KernelEvents::EXCEPTION => array('onKernelException', -128), ); } } <?php namespace Symfony\Component\HttpKernel\EventListener; use Symfony\Component\HttpKernel\Event\GetResponseEvent; use Symfony\Component\HttpKernel\KernelEvents; use Symfony\Component\Routing\RouterInterface; use Symfony\Component\EventDispatcher\EventSubscriberInterface; class LocaleListener implements EventSubscriberInterface { private $router; private $defaultLocale; public function __construct($defaultLocale = 'en', RouterInterface $router = null) { $this->defaultLocale = $defaultLocale; $this->router = $router; } public function onKernelRequest(GetResponseEvent $event) { $request = $event->getRequest(); if ($request->hasPreviousSession()) { $request->setDefaultLocale($request->getSession()->get('_locale', $this->defaultLocale)); } else { $request->setDefaultLocale($this->defaultLocale); } if ($locale = $request->attributes->get('_locale')) { $request->setLocale($locale); if ($request->hasPreviousSession()) { $request->getSession()->set('_locale', $request->getLocale()); } } if (null !== $this->router) { $this->router->getContext()->setParameter('_locale', $request->getLocale()); } } static public function getSubscribedEvents() { return array( KernelEvents::REQUEST => array(array('onKernelRequest', 16)), ); } } <?php namespace Symfony\Component\HttpKernel\EventListener; use Symfony\Component\HttpKernel\HttpKernelInterface; use Symfony\Component\HttpKernel\Event\GetResponseEvent; use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent; use Symfony\Component\HttpKernel\Event\FilterResponseEvent; use Symfony\Component\HttpKernel\KernelEvents; use Symfony\Component\HttpKernel\Profiler\Profile; use Symfony\Component\HttpKernel\Profiler\Profiler; use Symfony\Component\HttpFoundation\RequestMatcherInterface; use Symfony\Component\EventDispatcher\EventSubscriberInterface; class ProfilerListener implements EventSubscriberInterface { protected $profiler; protected $matcher; protected $onlyException; protected $onlyMasterRequests; protected $exception; protected $children; protected $requests; protected $profiles; public function __construct(Profiler $profiler, RequestMatcherInterface $matcher = null, $onlyException = false, $onlyMasterRequests = false) { $this->profiler = $profiler; $this->matcher = $matcher; $this->onlyException = (Boolean) $onlyException; $this->onlyMasterRequests = (Boolean) $onlyMasterRequests; $this->children = new \SplObjectStorage(); $this->profiles = array(); } public function onKernelException(GetResponseForExceptionEvent $event) { if ($this->onlyMasterRequests && HttpKernelInterface::MASTER_REQUEST !== $event->getRequestType()) { return; } $this->exception = $event->getException(); } public function onKernelRequest(GetResponseEvent $event) { $this->requests[] = $event->getRequest(); } public function onKernelResponse(FilterResponseEvent $event) { $master = HttpKernelInterface::MASTER_REQUEST === $event->getRequestType(); if ($this->onlyMasterRequests && !$master) { return; } if ($this->onlyException && null === $this->exception) { return; } $request = $event->getRequest(); $exception = $this->exception; $this->exception = null; if (null !== $this->matcher && !$this->matcher->matches($request)) { return; } if (!$profile = $this->profiler->collect($request, $event->getResponse(), $exception)) { return; } $this->profiles[] = $profile; if (null !== $exception) { foreach ($this->profiles as $profile) { $this->profiler->saveProfile($profile); } return; } if (!$master) { array_pop($this->requests); $parent = end($this->requests); $profiles = isset($this->children[$parent]) ? $this->children[$parent] : array(); $profiles[] = $profile; $this->children[$parent] = $profiles; } if (isset($this->children[$request])) { foreach ($this->children[$request] as $child) { $profile->addChild($child); } $this->children[$request] = array(); } if ($master) { $this->saveProfiles($profile); } } static public function getSubscribedEvents() { return array( KernelEvents::REQUEST => array('onKernelRequest', 1024), KernelEvents::RESPONSE => array('onKernelResponse', -100), KernelEvents::EXCEPTION => 'onKernelException', ); } private function saveProfiles(Profile $profile) { $this->profiler->saveProfile($profile); foreach ($profile->getChildren() as $profile) { $this->saveProfiles($profile); } } } <?php namespace Symfony\Component\HttpKernel\EventListener; use Symfony\Component\HttpKernel\Event\FilterResponseEvent; use Symfony\Component\HttpKernel\HttpKernelInterface; use Symfony\Component\HttpKernel\KernelEvents; use Symfony\Component\EventDispatcher\EventSubscriberInterface; class ResponseListener implements EventSubscriberInterface { private $charset; public function __construct($charset) { $this->charset = $charset; } public function onKernelResponse(FilterResponseEvent $event) { if (HttpKernelInterface::MASTER_REQUEST !== $event->getRequestType()) { return; } $response = $event->getResponse(); if (null === $response->getCharset()) { $response->setCharset($this->charset); } $response->prepare($event->getRequest()); } static public function getSubscribedEvents() { return array( KernelEvents::RESPONSE => 'onKernelResponse', ); } } <?php namespace Symfony\Component\HttpKernel\EventListener; use Symfony\Component\HttpKernel\Log\LoggerInterface; use Symfony\Component\HttpKernel\HttpKernelInterface; use Symfony\Component\HttpKernel\Event\GetResponseEvent; use Symfony\Component\HttpKernel\KernelEvents; use Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException; use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; use Symfony\Component\Routing\Exception\MethodNotAllowedException; use Symfony\Component\Routing\Exception\ResourceNotFoundException; use Symfony\Component\Routing\Matcher\UrlMatcherInterface; use Symfony\Component\EventDispatcher\EventSubscriberInterface; class RouterListener implements EventSubscriberInterface { private $urlMatcher; private $logger; public function __construct(UrlMatcherInterface $urlMatcher, LoggerInterface $logger = null) { $this->urlMatcher = $urlMatcher; $this->logger = $logger; } public function onKernelRequest(GetResponseEvent $event) { $request = $event->getRequest(); if (HttpKernelInterface::MASTER_REQUEST === $event->getRequestType()) { $this->urlMatcher->getContext()->fromRequest($request); } if ($request->attributes->has('_controller')) { return; } try { $parameters = $this->urlMatcher->match($request->getPathInfo()); if (null !== $this->logger) { $this->logger->info(sprintf('Matched route "%s" (parameters: %s)', $parameters['_route'], $this->parametersToString($parameters))); } $request->attributes->add($parameters); unset($parameters['_route']); unset($parameters['_controller']); $request->attributes->set('_route_params', $parameters); } catch (ResourceNotFoundException $e) { $message = sprintf('No route found for "%s %s"', $request->getMethod(), $request->getPathInfo()); throw new NotFoundHttpException($message, $e); } catch (MethodNotAllowedException $e) { $message = sprintf('No route found for "%s %s": Method Not Allowed (Allow: %s)', $request->getMethod(), $request->getPathInfo(), strtoupper(implode(', ', $e->getAllowedMethods()))); throw new MethodNotAllowedHttpException($e->getAllowedMethods(), $message, $e); } } private function parametersToString(array $parameters) { $pieces = array(); foreach ($parameters as $key => $val) { $pieces[] = sprintf('"%s": "%s"', $key, (is_string($val) ? $val : json_encode($val))); } return implode(', ', $pieces); } static public function getSubscribedEvents() { return array( KernelEvents::REQUEST => array(array('onKernelRequest', 32)), ); } } <?php namespace Symfony\Component\HttpKernel\EventListener; use Symfony\Component\HttpFoundation\StreamedResponse; use Symfony\Component\HttpKernel\Event\FilterResponseEvent; use Symfony\Component\HttpKernel\HttpKernelInterface; use Symfony\Component\HttpKernel\KernelEvents; use Symfony\Component\EventDispatcher\EventSubscriberInterface; class StreamedResponseListener implements EventSubscriberInterface { public function onKernelResponse(FilterResponseEvent $event) { if (HttpKernelInterface::MASTER_REQUEST !== $event->getRequestType()) { return; } $response = $event->getResponse(); if ($response instanceof StreamedResponse) { $response->send(); } } static public function getSubscribedEvents() { return array( KernelEvents::RESPONSE => array('onKernelResponse', -1024), ); } } <?php namespace Symfony\Component\HttpKernel\Exception; class AccessDeniedHttpException extends HttpException { public function __construct($message = null, \Exception $previous = null, $code = 0) { parent::__construct(403, $message, $previous, array(), $code); } } <?php namespace Symfony\Component\HttpKernel\Exception; class FlattenException { private $message; private $code; private $previous; private $trace; private $class; private $statusCode; private $headers; private $file; private $line; static public function create(\Exception $exception, $statusCode = null, array $headers = array()) { $e = new static(); $e->setMessage($exception->getMessage()); $e->setCode($exception->getCode()); if (null === $statusCode) { $statusCode = $exception instanceof HttpExceptionInterface ? $exception->getStatusCode() : 500; } $e->setStatusCode($statusCode); $e->setHeaders($headers); $e->setTrace($exception->getTrace(), $exception->getFile(), $exception->getLine()); $e->setClass(get_class($exception)); $e->setFile($exception->getFile()); $e->setLine($exception->getLine()); if ($exception->getPrevious()) { $e->setPrevious(static::create($exception->getPrevious())); } return $e; } public function toArray() { $exceptions = array(); foreach (array_merge(array($this), $this->getAllPrevious()) as $exception) { $exceptions[] = array( 'message' => $exception->getMessage(), 'class' => $exception->getClass(), 'trace' => $exception->getTrace(), ); } return $exceptions; } public function getStatusCode() { return $this->statusCode; } public function setStatusCode($code) { $this->statusCode = $code; } public function getHeaders() { return $this->headers; } public function setHeaders(array $headers) { $this->headers = $headers; } public function getClass() { return $this->class; } public function setClass($class) { $this->class = $class; } public function getFile() { return $this->file; } public function setFile($file) { $this->file = $file; } public function getLine() { return $this->line; } public function setLine($line) { $this->line = $line; } public function getMessage() { return $this->message; } public function setMessage($message) { $this->message = $message; } public function getCode() { return $this->code; } public function setCode($code) { $this->code = $code; } public function getPrevious() { return $this->previous; } public function setPrevious(FlattenException $previous) { $this->previous = $previous; } public function getAllPrevious() { $exceptions = array(); $e = $this; while ($e = $e->getPrevious()) { $exceptions[] = $e; } return $exceptions; } public function getTrace() { return $this->trace; } public function setTrace($trace, $file, $line) { $this->trace = array(); $this->trace[] = array( 'namespace' => '', 'short_class' => '', 'class' => '', 'type' => '', 'function' => '', 'file' => $file, 'line' => $line, 'args' => array(), ); foreach ($trace as $entry) { $class = ''; $namespace = ''; if (isset($entry['class'])) { $parts = explode('\\', $entry['class']); $class = array_pop($parts); $namespace = implode('\\', $parts); } $this->trace[] = array( 'namespace' => $namespace, 'short_class' => $class, 'class' => isset($entry['class']) ? $entry['class'] : '', 'type' => isset($entry['type']) ? $entry['type'] : '', 'function' => $entry['function'], 'file' => isset($entry['file']) ? $entry['file'] : null, 'line' => isset($entry['line']) ? $entry['line'] : null, 'args' => isset($entry['args']) ? $this->flattenArgs($entry['args']) : array(), ); } } private function flattenArgs($args, $level = 0) { $result = array(); foreach ($args as $key => $value) { if (is_object($value)) { $result[$key] = array('object', get_class($value)); } elseif (is_array($value)) { if ($level > 10) { $result[$key] = array('array', '*DEEP NESTED ARRAY*'); } else { $result[$key] = array('array', $this->flattenArgs($value, ++$level)); } } elseif (null === $value) { $result[$key] = array('null', null); } elseif (is_bool($value)) { $result[$key] = array('boolean', $value); } elseif (is_resource($value)) { $result[$key] = array('resource', get_resource_type($value)); } else { $result[$key] = array('string', (string) $value); } } return $result; } } <?php namespace Symfony\Component\HttpKernel\Exception; class HttpException extends \RuntimeException implements HttpExceptionInterface { private $statusCode; private $headers; public function __construct($statusCode, $message = null, \Exception $previous = null, array $headers = array(), $code = 0) { $this->statusCode = $statusCode; $this->headers = $headers; parent::__construct($message, $code, $previous); } public function getStatusCode() { return $this->statusCode; } public function getHeaders() { return $this->headers; } } <?php namespace Symfony\Component\HttpKernel\Exception; interface HttpExceptionInterface { function getStatusCode(); function getHeaders(); } <?php namespace Symfony\Component\HttpKernel\Exception; class MethodNotAllowedHttpException extends HttpException { public function __construct(array $allow, $message = null, \Exception $previous = null, $code = 0) { $headers = array('Allow' => strtoupper(implode(', ', $allow))); parent::__construct(405, $message, $previous, $headers, $code); } } <?php namespace Symfony\Component\HttpKernel\Exception; class NotFoundHttpException extends HttpException { public function __construct($message = null, \Exception $previous = null, $code = 0) { parent::__construct(404, $message, $previous, array(), $code); } } <?php namespace Symfony\Component\HttpKernel\HttpCache; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\HttpKernelInterface; class Esi { private $contentTypes; public function __construct(array $contentTypes = array('text/html', 'text/xml', 'application/xml')) { $this->contentTypes = $contentTypes; } public function createCacheStrategy() { return new EsiResponseCacheStrategy(); } public function hasSurrogateEsiCapability(Request $request) { if (null === $value = $request->headers->get('Surrogate-Capability')) { return false; } return false !== strpos($value, 'ESI/1.0'); } public function addSurrogateEsiCapability(Request $request) { $current = $request->headers->get('Surrogate-Capability'); $new = 'symfony2="ESI/1.0"'; $request->headers->set('Surrogate-Capability', $current ? $current.', '.$new : $new); } public function addSurrogateControl(Response $response) { if (false !== strpos($response->getContent(), '<esi:include')) { $response->headers->set('Surrogate-Control', 'content="ESI/1.0"'); } } public function needsEsiParsing(Response $response) { if (!$control = $response->headers->get('Surrogate-Control')) { return false; } return (Boolean) preg_match('#content="[^"]*ESI/1.0[^"]*"#', $control); } public function renderIncludeTag($uri, $alt = null, $ignoreErrors = true, $comment = '') { $html = sprintf('<esi:include src="%s"%s%s />', $uri, $ignoreErrors ? ' onerror="continue"' : '', $alt ? sprintf(' alt="%s"', $alt) : '' ); if (!empty($comment)) { return sprintf("<esi:comment text=\"%s\" />\n%s", $comment, $html); } return $html; } public function process(Request $request, Response $response) { $this->request = $request; $type = $response->headers->get('Content-Type'); if (empty($type)) { $type = 'text/html'; } $parts = explode(';', $type); if (!in_array($parts[0], $this->contentTypes)) { return $response; } $content = $response->getContent(); $content = str_replace(array('<?', '<%'), array('<?php echo "<?"; ?>', '<?php echo "<%"; ?>'), $content); $content = preg_replace_callback('#<esi\:include\s+(.*?)\s*(?:/|</esi\:include)>#', array($this, 'handleEsiIncludeTag'), $content); $content = preg_replace('#<esi\:comment[^>]*(?:/|</esi\:comment)>#', '', $content); $content = preg_replace('#<esi\:remove>.*?</esi\:remove>#', '', $content); $response->setContent($content); $response->headers->set('X-Body-Eval', 'ESI'); if ($response->headers->has('Surrogate-Control')) { $value = $response->headers->get('Surrogate-Control'); if ('content="ESI/1.0"' == $value) { $response->headers->remove('Surrogate-Control'); } elseif (preg_match('#,\s*content="ESI/1.0"#', $value)) { $response->headers->set('Surrogate-Control', preg_replace('#,\s*content="ESI/1.0"#', '', $value)); } elseif (preg_match('#content="ESI/1.0",\s*#', $value)) { $response->headers->set('Surrogate-Control', preg_replace('#content="ESI/1.0",\s*#', '', $value)); } } } public function handle(HttpCache $cache, $uri, $alt, $ignoreErrors) { $subRequest = Request::create($uri, 'get', array(), $cache->getRequest()->cookies->all(), array(), $cache->getRequest()->server->all()); try { $response = $cache->handle($subRequest, HttpKernelInterface::SUB_REQUEST, true); if (!$response->isSuccessful()) { throw new \RuntimeException(sprintf('Error when rendering "%s" (Status code is %s).', $subRequest->getUri(), $response->getStatusCode())); } return $response->getContent(); } catch (\Exception $e) { if ($alt) { return $this->handle($cache, $alt, '', $ignoreErrors); } if (!$ignoreErrors) { throw $e; } } } private function handleEsiIncludeTag($attributes) { $options = array(); preg_match_all('/(src|onerror|alt)="([^"]*?)"/', $attributes[1], $matches, PREG_SET_ORDER); foreach ($matches as $set) { $options[$set[1]] = $set[2]; } if (!isset($options['src'])) { throw new \RuntimeException('Unable to process an ESI tag without a "src" attribute.'); } return sprintf('<?php echo $this->esi->handle($this, \'%s\', \'%s\', %s) ?>'."\n", $options['src'], isset($options['alt']) ? $options['alt'] : null, isset($options['onerror']) && 'continue' == $options['onerror'] ? 'true' : 'false' ); } } <?php namespace Symfony\Component\HttpKernel\HttpCache; use Symfony\Component\HttpFoundation\Response; class EsiResponseCacheStrategy implements EsiResponseCacheStrategyInterface { private $cacheable = true; private $ttls = array(); private $maxAges = array(); public function add(Response $response) { if ($response->isValidateable()) { $this->cacheable = false; } else { $this->ttls[] = $response->getTtl(); $this->maxAges[] = $response->getMaxAge(); } } public function update(Response $response) { if (1 === count($this->ttls)) { return; } if (!$this->cacheable) { $response->headers->set('Cache-Control', 'no-cache, must-revalidate'); return; } if (null !== $maxAge = min($this->maxAges)) { $response->setSharedMaxAge($maxAge); $response->headers->set('Age', $maxAge - min($this->ttls)); } $response->setMaxAge(0); } } <?php namespace Symfony\Component\HttpKernel\HttpCache; use Symfony\Component\HttpFoundation\Response; interface EsiResponseCacheStrategyInterface { function add(Response $response); function update(Response $response); } <?php namespace Symfony\Component\HttpKernel\HttpCache; use Symfony\Component\HttpKernel\HttpKernelInterface; use Symfony\Component\HttpKernel\TerminableInterface; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; class HttpCache implements HttpKernelInterface, TerminableInterface { private $kernel; private $store; private $request; private $esi; private $esiCacheStrategy; private $traces; public function __construct(HttpKernelInterface $kernel, StoreInterface $store, Esi $esi = null, array $options = array()) { $this->store = $store; $this->kernel = $kernel; register_shutdown_function(array($this->store, 'cleanup')); $this->options = array_merge(array( 'debug' => false, 'default_ttl' => 0, 'private_headers' => array('Authorization', 'Cookie'), 'allow_reload' => false, 'allow_revalidate' => false, 'stale_while_revalidate' => 2, 'stale_if_error' => 60, ), $options); $this->esi = $esi; $this->traces = array(); } public function getStore() { return $this->store; } public function getTraces() { return $this->traces; } public function getLog() { $log = array(); foreach ($this->traces as $request => $traces) { $log[] = sprintf('%s: %s', $request, implode(', ', $traces)); } return implode('; ', $log); } public function getRequest() { return $this->request; } public function getKernel() { return $this->kernel; } public function getEsi() { return $this->esi; } public function handle(Request $request, $type = HttpKernelInterface::MASTER_REQUEST, $catch = true) { if (HttpKernelInterface::MASTER_REQUEST === $type) { $this->traces = array(); $this->request = $request; if (null !== $this->esi) { $this->esiCacheStrategy = $this->esi->createCacheStrategy(); } } $path = $request->getPathInfo(); if ($qs = $request->getQueryString()) { $path .= '?'.$qs; } $this->traces[$request->getMethod().' '.$path] = array(); if (!$request->isMethodSafe()) { $response = $this->invalidate($request, $catch); } elseif ($request->headers->has('expect')) { $response = $this->pass($request, $catch); } else { $response = $this->lookup($request, $catch); } $response->isNotModified($request); $this->restoreResponseBody($request, $response); $response->setDate(new \DateTime(null, new \DateTimeZone('UTC'))); if (HttpKernelInterface::MASTER_REQUEST === $type && $this->options['debug']) { $response->headers->set('X-Symfony-Cache', $this->getLog()); } if (null !== $this->esi) { $this->esiCacheStrategy->add($response); if (HttpKernelInterface::MASTER_REQUEST === $type) { $this->esiCacheStrategy->update($response); } } $response->prepare($request); return $response; } public function terminate(Request $request, Response $response) { if ($this->getKernel() instanceof TerminableInterface) { $this->getKernel()->terminate($request, $response); } } protected function pass(Request $request, $catch = false) { $this->record($request, 'pass'); return $this->forward($request, $catch); } protected function invalidate(Request $request, $catch = false) { $response = $this->pass($request, $catch); if ($response->isSuccessful() || $response->isRedirect()) { try { $this->store->invalidate($request, $catch); $this->record($request, 'invalidate'); } catch (\Exception $e) { $this->record($request, 'invalidate-failed'); if ($this->options['debug']) { throw $e; } } } return $response; } protected function lookup(Request $request, $catch = false) { if ($this->options['allow_reload'] && $request->isNoCache()) { $this->record($request, 'reload'); return $this->fetch($request); } try { $entry = $this->store->lookup($request); } catch (\Exception $e) { $this->record($request, 'lookup-failed'); if ($this->options['debug']) { throw $e; } return $this->pass($request, $catch); } if (null === $entry) { $this->record($request, 'miss'); return $this->fetch($request, $catch); } if (!$this->isFreshEnough($request, $entry)) { $this->record($request, 'stale'); return $this->validate($request, $entry, $catch); } $this->record($request, 'fresh'); $entry->headers->set('Age', $entry->getAge()); return $entry; } protected function validate(Request $request, Response $entry, $catch = false) { $subRequest = clone $request; $subRequest->setMethod('GET'); $subRequest->headers->set('if_modified_since', $entry->headers->get('Last-Modified')); $cachedEtags = $entry->getEtag() ? array($entry->getEtag()) : array(); $requestEtags = $request->getEtags(); if ($etags = array_unique(array_merge($cachedEtags, $requestEtags))) { $subRequest->headers->set('if_none_match', implode(', ', $etags)); } $response = $this->forward($subRequest, $catch, $entry); if (304 == $response->getStatusCode()) { $this->record($request, 'valid'); $etag = $response->getEtag(); if ($etag && in_array($etag, $requestEtags) && !in_array($etag, $cachedEtags)) { return $response; } $entry = clone $entry; $entry->headers->remove('Date'); foreach (array('Date', 'Expires', 'Cache-Control', 'ETag', 'Last-Modified') as $name) { if ($response->headers->has($name)) { $entry->headers->set($name, $response->headers->get($name)); } } $response = $entry; } else { $this->record($request, 'invalid'); } if ($response->isCacheable()) { $this->store($request, $response); } return $response; } protected function fetch(Request $request, $catch = false) { $subRequest = clone $request; $subRequest->setMethod('GET'); $subRequest->headers->remove('if_modified_since'); $subRequest->headers->remove('if_none_match'); $response = $this->forward($subRequest, $catch); if ($this->isPrivateRequest($request) && !$response->headers->hasCacheControlDirective('public')) { $response->setPrivate(true); } elseif ($this->options['default_ttl'] > 0 && null === $response->getTtl() && !$response->headers->getCacheControlDirective('must-revalidate')) { $response->setTtl($this->options['default_ttl']); } if ($response->isCacheable()) { $this->store($request, $response); } return $response; } protected function forward(Request $request, $catch = false, Response $entry = null) { if ($this->esi) { $this->esi->addSurrogateEsiCapability($request); } $response = $this->kernel->handle($request, HttpKernelInterface::MASTER_REQUEST, $catch); if (null !== $entry && in_array($response->getStatusCode(), array(500, 502, 503, 504))) { if (null === $age = $entry->headers->getCacheControlDirective('stale-if-error')) { $age = $this->options['stale_if_error']; } if (abs($entry->getTtl()) < $age) { $this->record($request, 'stale-if-error'); return $entry; } } $this->processResponseBody($request, $response); return $response; } protected function isFreshEnough(Request $request, Response $entry) { if (!$entry->isFresh()) { return $this->lock($request, $entry); } if ($this->options['allow_revalidate'] && null !== $maxAge = $request->headers->getCacheControlDirective('max-age')) { return $maxAge > 0 && $maxAge >= $entry->getAge(); } return true; } protected function lock(Request $request, Response $entry) { $lock = $this->store->lock($request, $entry); if (true !== $lock) { if (null === $age = $entry->headers->getCacheControlDirective('stale-while-revalidate')) { $age = $this->options['stale_while_revalidate']; } if (abs($entry->getTtl()) < $age) { $this->record($request, 'stale-while-revalidate'); return true; } $wait = 0; while (is_file($lock) && $wait < 5000000) { usleep(50000); $wait += 50000; } if ($wait < 2000000) { $new = $this->lookup($request); $entry->headers = $new->headers; $entry->setContent($new->getContent()); $entry->setStatusCode($new->getStatusCode()); $entry->setProtocolVersion($new->getProtocolVersion()); foreach ($new->headers->getCookies() as $cookie) { $entry->headers->setCookie($cookie); } } else { $entry->setStatusCode(503); $entry->setContent('503 Service Unavailable'); $entry->headers->set('Retry-After', 10); } return true; } return false; } protected function store(Request $request, Response $response) { try { $this->store->write($request, $response); $this->record($request, 'store'); $response->headers->set('Age', $response->getAge()); } catch (\Exception $e) { $this->record($request, 'store-failed'); if ($this->options['debug']) { throw $e; } } $this->store->unlock($request); } private function restoreResponseBody(Request $request, Response $response) { if ('HEAD' === $request->getMethod() || 304 === $response->getStatusCode()) { $response->setContent(''); $response->headers->remove('X-Body-Eval'); $response->headers->remove('X-Body-File'); return; } if ($response->headers->has('X-Body-Eval')) { ob_start(); if ($response->headers->has('X-Body-File')) { include $response->headers->get('X-Body-File'); } else { eval('; ?>'.$response->getContent().'<?php ;'); } $response->setContent(ob_get_clean()); $response->headers->remove('X-Body-Eval'); if (!$response->headers->has('Transfer-Encoding')) { $response->headers->set('Content-Length', strlen($response->getContent())); } } elseif ($response->headers->has('X-Body-File')) { $response->setContent(file_get_contents($response->headers->get('X-Body-File'))); } else { return; } $response->headers->remove('X-Body-File'); } protected function processResponseBody(Request $request, Response $response) { if (null !== $this->esi && $this->esi->needsEsiParsing($response)) { $this->esi->process($request, $response); } } private function isPrivateRequest(Request $request) { foreach ($this->options['private_headers'] as $key) { $key = strtolower(str_replace('HTTP_', '', $key)); if ('cookie' === $key) { if (count($request->cookies->all())) { return true; } } elseif ($request->headers->has($key)) { return true; } } return false; } private function record(Request $request, $event) { $path = $request->getPathInfo(); if ($qs = $request->getQueryString()) { $path .= '?'.$qs; } $this->traces[$request->getMethod().' '.$path][] = $event; } } <?php namespace Symfony\Component\HttpKernel\HttpCache; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; class Store implements StoreInterface { private $root; private $keyCache; private $locks; public function __construct($root) { $this->root = $root; if (!is_dir($this->root)) { mkdir($this->root, 0777, true); } $this->keyCache = new \SplObjectStorage(); $this->locks = array(); } public function cleanup() { foreach ($this->locks as $lock) { @unlink($lock); } $error = error_get_last(); if (1 === $error['type'] && false === headers_sent()) { header('HTTP/1.0 503 Service Unavailable'); header('Retry-After: 10'); echo '503 Service Unavailable'; } } public function lock(Request $request) { if (false !== $lock = @fopen($path = $this->getPath($this->getCacheKey($request).'.lck'), 'x')) { fclose($lock); $this->locks[] = $path; return true; } return $path; } public function unlock(Request $request) { return @unlink($this->getPath($this->getCacheKey($request).'.lck')); } public function lookup(Request $request) { $key = $this->getCacheKey($request); if (!$entries = $this->getMetadata($key)) { return null; } $match = null; foreach ($entries as $entry) { if ($this->requestsMatch(isset($entry[1]['vary'][0]) ? $entry[1]['vary'][0] : '', $request->headers->all(), $entry[0])) { $match = $entry; break; } } if (null === $match) { return null; } list($req, $headers) = $match; if (is_file($body = $this->getPath($headers['x-content-digest'][0]))) { return $this->restoreResponse($headers, $body); } return null; } public function write(Request $request, Response $response) { $key = $this->getCacheKey($request); $storedEnv = $this->persistRequest($request); if (!$response->headers->has('X-Content-Digest')) { $digest = 'en'.sha1($response->getContent()); if (false === $this->save($digest, $response->getContent())) { throw new \RuntimeException('Unable to store the entity.'); } $response->headers->set('X-Content-Digest', $digest); if (!$response->headers->has('Transfer-Encoding')) { $response->headers->set('Content-Length', strlen($response->getContent())); } } $entries = array(); $vary = $response->headers->get('vary'); foreach ($this->getMetadata($key) as $entry) { if (!isset($entry[1]['vary'][0])) { $entry[1]['vary'] = array(''); } if ($vary != $entry[1]['vary'][0] || !$this->requestsMatch($vary, $entry[0], $storedEnv)) { $entries[] = $entry; } } $headers = $this->persistResponse($response); unset($headers['age']); array_unshift($entries, array($storedEnv, $headers)); if (false === $this->save($key, serialize($entries))) { throw new \RuntimeException('Unable to store the metadata.'); } return $key; } public function invalidate(Request $request) { $modified = false; $key = $this->getCacheKey($request); $entries = array(); foreach ($this->getMetadata($key) as $entry) { $response = $this->restoreResponse($entry[1]); if ($response->isFresh()) { $response->expire(); $modified = true; $entries[] = array($entry[0], $this->persistResponse($response)); } else { $entries[] = $entry; } } if ($modified) { if (false === $this->save($key, serialize($entries))) { throw new \RuntimeException('Unable to store the metadata.'); } } foreach (array('Location', 'Content-Location') as $header) { if ($uri = $request->headers->get($header)) { $subRequest = Request::create($uri, 'get', array(), array(), array(), $request->server->all()); $this->invalidate($subRequest); } } } private function requestsMatch($vary, $env1, $env2) { if (empty($vary)) { return true; } foreach (preg_split('/[\s,]+/', $vary) as $header) { $key = strtr(strtolower($header), '_', '-'); $v1 = isset($env1[$key]) ? $env1[$key] : null; $v2 = isset($env2[$key]) ? $env2[$key] : null; if ($v1 !== $v2) { return false; } } return true; } private function getMetadata($key) { if (false === $entries = $this->load($key)) { return array(); } return unserialize($entries); } public function purge($url) { if (is_file($path = $this->getPath($this->getCacheKey(Request::create($url))))) { unlink($path); return true; } return false; } private function load($key) { $path = $this->getPath($key); return is_file($path) ? file_get_contents($path) : false; } private function save($key, $data) { $path = $this->getPath($key); if (!is_dir(dirname($path)) && false === @mkdir(dirname($path), 0777, true)) { return false; } $tmpFile = tempnam(dirname($path), basename($path)); if (false === $fp = @fopen($tmpFile, 'wb')) { return false; } @fwrite($fp, $data); @fclose($fp); if ($data != file_get_contents($tmpFile)) { return false; } if (false === @rename($tmpFile, $path)) { return false; } chmod($path, 0666 & ~umask()); } public function getPath($key) { return $this->root.DIRECTORY_SEPARATOR.substr($key, 0, 2).DIRECTORY_SEPARATOR.substr($key, 2, 2).DIRECTORY_SEPARATOR.substr($key, 4, 2).DIRECTORY_SEPARATOR.substr($key, 6); } private function getCacheKey(Request $request) { if (isset($this->keyCache[$request])) { return $this->keyCache[$request]; } return $this->keyCache[$request] = 'md'.sha1($request->getUri()); } private function persistRequest(Request $request) { return $request->headers->all(); } private function persistResponse(Response $response) { $headers = $response->headers->all(); $headers['X-Status'] = array($response->getStatusCode()); return $headers; } private function restoreResponse($headers, $body = null) { $status = $headers['X-Status'][0]; unset($headers['X-Status']); if (null !== $body) { $headers['X-Body-File'] = array($body); } return new Response($body, $status, $headers); } } <?php namespace Symfony\Component\HttpKernel\HttpCache; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; interface StoreInterface { function lookup(Request $request); function write(Request $request, Response $response); function invalidate(Request $request); function lock(Request $request); function unlock(Request $request); function purge($url); function cleanup(); } <?php namespace Symfony\Component\HttpKernel; use Symfony\Component\HttpKernel\Controller\ControllerResolverInterface; use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; use Symfony\Component\HttpKernel\Event\FilterControllerEvent; use Symfony\Component\HttpKernel\Event\FilterResponseEvent; use Symfony\Component\HttpKernel\Event\GetResponseEvent; use Symfony\Component\HttpKernel\Event\GetResponseForControllerResultEvent; use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent; use Symfony\Component\HttpKernel\Event\PostResponseEvent; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\EventDispatcher\EventDispatcherInterface; class HttpKernel implements HttpKernelInterface, TerminableInterface { protected $dispatcher; protected $resolver; public function __construct(EventDispatcherInterface $dispatcher, ControllerResolverInterface $resolver) { $this->dispatcher = $dispatcher; $this->resolver = $resolver; } public function handle(Request $request, $type = HttpKernelInterface::MASTER_REQUEST, $catch = true) { try { return $this->handleRaw($request, $type); } catch (\Exception $e) { if (false === $catch) { throw $e; } return $this->handleException($e, $request, $type); } } public function terminate(Request $request, Response $response) { $this->dispatcher->dispatch(KernelEvents::TERMINATE, new PostResponseEvent($this, $request, $response)); } private function handleRaw(Request $request, $type = self::MASTER_REQUEST) { $event = new GetResponseEvent($this, $request, $type); $this->dispatcher->dispatch(KernelEvents::REQUEST, $event); if ($event->hasResponse()) { return $this->filterResponse($event->getResponse(), $request, $type); } if (false === $controller = $this->resolver->getController($request)) { throw new NotFoundHttpException(sprintf('Unable to find the controller for path "%s". Maybe you forgot to add the matching route in your routing configuration?', $request->getPathInfo())); } $event = new FilterControllerEvent($this, $controller, $request, $type); $this->dispatcher->dispatch(KernelEvents::CONTROLLER, $event); $controller = $event->getController(); $arguments = $this->resolver->getArguments($request, $controller); $response = call_user_func_array($controller, $arguments); if (!$response instanceof Response) { $event = new GetResponseForControllerResultEvent($this, $request, $type, $response); $this->dispatcher->dispatch(KernelEvents::VIEW, $event); if ($event->hasResponse()) { $response = $event->getResponse(); } if (!$response instanceof Response) { $msg = sprintf('The controller must return a response (%s given).', $this->varToString($response)); if (null === $response) { $msg .= ' Did you forget to add a return statement somewhere in your controller?'; } throw new \LogicException($msg); } } return $this->filterResponse($response, $request, $type); } private function filterResponse(Response $response, Request $request, $type) { $event = new FilterResponseEvent($this, $request, $type, $response); $this->dispatcher->dispatch(KernelEvents::RESPONSE, $event); return $event->getResponse(); } private function handleException(\Exception $e, $request, $type) { $event = new GetResponseForExceptionEvent($this, $request, $type, $e); $this->dispatcher->dispatch(KernelEvents::EXCEPTION, $event); if (!$event->hasResponse()) { throw $e; } try { return $this->filterResponse($event->getResponse(), $request, $type); } catch (\Exception $e) { return $event->getResponse(); } } private function varToString($var) { if (is_object($var)) { return sprintf('Object(%s)', get_class($var)); } if (is_array($var)) { $a = array(); foreach ($var as $k => $v) { $a[] = sprintf('%s => %s', $k, $this->varToString($v)); } return sprintf("Array(%s)", implode(', ', $a)); } if (is_resource($var)) { return sprintf('Resource(%s)', get_resource_type($var)); } if (null === $var) { return 'null'; } if (false === $var) { return 'false'; } if (true === $var) { return 'true'; } return (string) $var; } } <?php namespace Symfony\Component\HttpKernel; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; interface HttpKernelInterface { const MASTER_REQUEST = 1; const SUB_REQUEST = 2; function handle(Request $request, $type = self::MASTER_REQUEST, $catch = true); } <?php namespace Symfony\Component\HttpKernel; use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Dumper\PhpDumper; use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag; use Symfony\Component\DependencyInjection\Loader\XmlFileLoader; use Symfony\Component\DependencyInjection\Loader\YamlFileLoader; use Symfony\Component\DependencyInjection\Loader\IniFileLoader; use Symfony\Component\DependencyInjection\Loader\PhpFileLoader; use Symfony\Component\DependencyInjection\Loader\ClosureLoader; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\HttpKernelInterface; use Symfony\Component\HttpKernel\Bundle\BundleInterface; use Symfony\Component\HttpKernel\Config\FileLocator; use Symfony\Component\HttpKernel\DependencyInjection\MergeExtensionConfigurationPass; use Symfony\Component\HttpKernel\DependencyInjection\AddClassesToCachePass; use Symfony\Component\HttpKernel\Debug\ErrorHandler; use Symfony\Component\HttpKernel\Debug\ExceptionHandler; use Symfony\Component\Config\Loader\LoaderResolver; use Symfony\Component\Config\Loader\DelegatingLoader; use Symfony\Component\Config\ConfigCache; use Symfony\Component\ClassLoader\ClassCollectionLoader; use Symfony\Component\ClassLoader\DebugClassLoader; abstract class Kernel implements KernelInterface, TerminableInterface { protected $bundles; protected $bundleMap; protected $container; protected $rootDir; protected $environment; protected $debug; protected $booted; protected $name; protected $startTime; protected $classes; protected $errorReportingLevel; const VERSION = '2.1.0-DEV'; public function __construct($environment, $debug) { $this->environment = $environment; $this->debug = (Boolean) $debug; $this->booted = false; $this->rootDir = $this->getRootDir(); $this->name = preg_replace('/[^a-zA-Z0-9_]+/', '', basename($this->rootDir)); $this->classes = array(); if ($this->debug) { $this->startTime = microtime(true); } $this->init(); } public function init() { if ($this->debug) { ini_set('display_errors', 1); error_reporting(-1); DebugClassLoader::enable(); ErrorHandler::register($this->errorReportingLevel); if ('cli' !== php_sapi_name()) { ExceptionHandler::register(); } } else { ini_set('display_errors', 0); } } public function __clone() { if ($this->debug) { $this->startTime = microtime(true); } $this->booted = false; $this->container = null; } public function boot() { if (true === $this->booted) { return; } $this->initializeBundles(); $this->initializeContainer(); foreach ($this->getBundles() as $bundle) { $bundle->setContainer($this->container); $bundle->boot(); } $this->booted = true; } public function terminate(Request $request, Response $response) { if (false === $this->booted) { return; } if ($this->getHttpKernel() instanceof TerminableInterface) { $this->getHttpKernel()->terminate($request, $response); } } public function shutdown() { if (false === $this->booted) { return; } $this->booted = false; foreach ($this->getBundles() as $bundle) { $bundle->shutdown(); $bundle->setContainer(null); } $this->container = null; } public function handle(Request $request, $type = HttpKernelInterface::MASTER_REQUEST, $catch = true) { if (false === $this->booted) { $this->boot(); } return $this->getHttpKernel()->handle($request, $type, $catch); } protected function getHttpKernel() { return $this->container->get('http_kernel'); } public function getBundles() { return $this->bundles; } public function isClassInActiveBundle($class) { foreach ($this->getBundles() as $bundle) { if (0 === strpos($class, $bundle->getNamespace())) { return true; } } return false; } public function getBundle($name, $first = true) { if (!isset($this->bundleMap[$name])) { throw new \InvalidArgumentException(sprintf('Bundle "%s" does not exist or it is not enabled. Maybe you forgot to add it in the registerBundles() function of your %s.php file?', $name, get_class($this))); } if (true === $first) { return $this->bundleMap[$name][0]; } return $this->bundleMap[$name]; } public function locateResource($name, $dir = null, $first = true) { if ('@' !== $name[0]) { throw new \InvalidArgumentException(sprintf('A resource name must start with @ ("%s" given).', $name)); } if (false !== strpos($name, '..')) { throw new \RuntimeException(sprintf('File name "%s" contains invalid characters (..).', $name)); } $bundleName = substr($name, 1); $path = ''; if (false !== strpos($bundleName, '/')) { list($bundleName, $path) = explode('/', $bundleName, 2); } $isResource = 0 === strpos($path, 'Resources') && null !== $dir; $overridePath = substr($path, 9); $resourceBundle = null; $bundles = $this->getBundle($bundleName, false); $files = array(); foreach ($bundles as $bundle) { if ($isResource && file_exists($file = $dir.'/'.$bundle->getName().$overridePath)) { if (null !== $resourceBundle) { throw new \RuntimeException(sprintf('"%s" resource is hidden by a resource from the "%s" derived bundle. Create a "%s" file to override the bundle resource.', $file, $resourceBundle, $dir.'/'.$bundles[0]->getName().$overridePath )); } if ($first) { return $file; } $files[] = $file; } if (file_exists($file = $bundle->getPath().'/'.$path)) { if ($first && !$isResource) { return $file; } $files[] = $file; $resourceBundle = $bundle->getName(); } } if (count($files) > 0) { return $first && $isResource ? $files[0] : $files; } throw new \InvalidArgumentException(sprintf('Unable to find file "%s".', $name)); } public function getName() { return $this->name; } public function getEnvironment() { return $this->environment; } public function isDebug() { return $this->debug; } public function getRootDir() { if (null === $this->rootDir) { $r = new \ReflectionObject($this); $this->rootDir = dirname($r->getFileName()); } return $this->rootDir; } public function getContainer() { return $this->container; } public function loadClassCache($name = 'classes', $extension = '.php') { if (!$this->booted && is_file($this->getCacheDir().'/classes.map')) { ClassCollectionLoader::load(include($this->getCacheDir().'/classes.map'), $this->getCacheDir(), $name, $this->debug, false, $extension); } } public function setClassCache(array $classes) { file_put_contents($this->getCacheDir().'/classes.map', sprintf('<?php return %s;', var_export($classes, true))); } public function getStartTime() { return $this->debug ? $this->startTime : -INF; } public function getCacheDir() { return $this->rootDir.'/cache/'.$this->environment; } public function getLogDir() { return $this->rootDir.'/logs'; } protected function initializeBundles() { $this->bundles = array(); $topMostBundles = array(); $directChildren = array(); foreach ($this->registerBundles() as $bundle) { $name = $bundle->getName(); if (isset($this->bundles[$name])) { throw new \LogicException(sprintf('Trying to register two bundles with the same name "%s"', $name)); } $this->bundles[$name] = $bundle; if ($parentName = $bundle->getParent()) { if (isset($directChildren[$parentName])) { throw new \LogicException(sprintf('Bundle "%s" is directly extended by two bundles "%s" and "%s".', $parentName, $name, $directChildren[$parentName])); } if ($parentName == $name) { throw new \LogicException(sprintf('Bundle "%s" can not extend itself.', $name)); } $directChildren[$parentName] = $name; } else { $topMostBundles[$name] = $bundle; } } if (count($diff = array_values(array_diff(array_keys($directChildren), array_keys($this->bundles))))) { throw new \LogicException(sprintf('Bundle "%s" extends bundle "%s", which is not registered.', $directChildren[$diff[0]], $diff[0])); } $this->bundleMap = array(); foreach ($topMostBundles as $name => $bundle) { $bundleMap = array($bundle); $hierarchy = array($name); while (isset($directChildren[$name])) { $name = $directChildren[$name]; array_unshift($bundleMap, $this->bundles[$name]); $hierarchy[] = $name; } foreach ($hierarchy as $bundle) { $this->bundleMap[$bundle] = $bundleMap; array_pop($bundleMap); } } } protected function getContainerClass() { return $this->name.ucfirst($this->environment).($this->debug ? 'Debug' : '').'ProjectContainer'; } protected function getContainerBaseClass() { return 'Container'; } protected function initializeContainer() { $class = $this->getContainerClass(); $cache = new ConfigCache($this->getCacheDir().'/'.$class.'.php', $this->debug); $fresh = true; if (!$cache->isFresh()) { $container = $this->buildContainer(); $this->dumpContainer($cache, $container, $class, $this->getContainerBaseClass()); $fresh = false; } require_once $cache; $this->container = new $class(); $this->container->set('kernel', $this); if (!$fresh && $this->container->has('cache_warmer')) { $this->container->get('cache_warmer')->warmUp($this->container->getParameter('kernel.cache_dir')); } } protected function getKernelParameters() { $bundles = array(); foreach ($this->bundles as $name => $bundle) { $bundles[$name] = get_class($bundle); } return array_merge( array( 'kernel.root_dir' => $this->rootDir, 'kernel.environment' => $this->environment, 'kernel.debug' => $this->debug, 'kernel.name' => $this->name, 'kernel.cache_dir' => $this->getCacheDir(), 'kernel.logs_dir' => $this->getLogDir(), 'kernel.bundles' => $bundles, 'kernel.charset' => 'UTF-8', 'kernel.container_class' => $this->getContainerClass(), ), $this->getEnvParameters() ); } protected function getEnvParameters() { $parameters = array(); foreach ($_SERVER as $key => $value) { if (0 === strpos($key, 'SYMFONY__')) { $parameters[strtolower(str_replace('__', '.', substr($key, 9)))] = $value; } } return $parameters; } protected function buildContainer() { foreach (array('cache' => $this->getCacheDir(), 'logs' => $this->getLogDir()) as $name => $dir) { if (!is_dir($dir)) { if (false === @mkdir($dir, 0777, true)) { throw new \RuntimeException(sprintf("Unable to create the %s directory (%s)\n", $name, $dir)); } } elseif (!is_writable($dir)) { throw new \RuntimeException(sprintf("Unable to write in the %s directory (%s)\n", $name, $dir)); } } $container = $this->getContainerBuilder(); $extensions = array(); foreach ($this->bundles as $bundle) { if ($extension = $bundle->getContainerExtension()) { $container->registerExtension($extension); $extensions[] = $extension->getAlias(); } if ($this->debug) { $container->addObjectResource($bundle); } } foreach ($this->bundles as $bundle) { $bundle->build($container); } $container->addObjectResource($this); $container->getCompilerPassConfig()->setMergePass(new MergeExtensionConfigurationPass($extensions)); if (null !== $cont = $this->registerContainerConfiguration($this->getContainerLoader($container))) { $container->merge($cont); } $container->addCompilerPass(new AddClassesToCachePass($this)); $container->compile(); return $container; } protected function getContainerBuilder() { return new ContainerBuilder(new ParameterBag($this->getKernelParameters())); } protected function dumpContainer(ConfigCache $cache, ContainerBuilder $container, $class, $baseClass) { $dumper = new PhpDumper($container); $content = $dumper->dump(array('class' => $class, 'base_class' => $baseClass)); if (!$this->debug) { $content = self::stripComments($content); } $cache->write($content, $container->getResources()); } protected function getContainerLoader(ContainerInterface $container) { $locator = new FileLocator($this); $resolver = new LoaderResolver(array( new XmlFileLoader($container, $locator), new YamlFileLoader($container, $locator), new IniFileLoader($container, $locator), new PhpFileLoader($container, $locator), new ClosureLoader($container), )); return new DelegatingLoader($resolver); } static public function stripComments($source) { if (!function_exists('token_get_all')) { return $source; } $output = ''; foreach (token_get_all($source) as $token) { if (is_string($token)) { $output .= $token; } elseif (!in_array($token[0], array(T_COMMENT, T_DOC_COMMENT))) { $output .= $token[1]; } } $output = preg_replace(array('/\s+$/Sm', '/\n+/S'), "\n", $output); return $output; } public function serialize() { return serialize(array($this->environment, $this->debug)); } public function unserialize($data) { list($environment, $debug) = unserialize($data); $this->__construct($environment, $debug); } } <?php namespace Symfony\Component\HttpKernel; final class KernelEvents { const REQUEST = 'kernel.request'; const EXCEPTION = 'kernel.exception'; const VIEW = 'kernel.view'; const CONTROLLER = 'kernel.controller'; const RESPONSE = 'kernel.response'; const TERMINATE = 'kernel.terminate'; } <?php namespace Symfony\Component\HttpKernel; use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\HttpKernel\HttpKernelInterface; use Symfony\Component\HttpKernel\Bundle\BundleInterface; use Symfony\Component\Config\Loader\LoaderInterface; interface KernelInterface extends HttpKernelInterface, \Serializable { function registerBundles(); function registerContainerConfiguration(LoaderInterface $loader); function boot(); function shutdown(); function getBundles(); function isClassInActiveBundle($class); function getBundle($name, $first = true); function locateResource($name, $dir = null, $first = true); function getName(); function getEnvironment(); function isDebug(); function getRootDir(); function getContainer(); function getStartTime(); function getCacheDir(); function getLogDir(); } <?php namespace Symfony\Component\HttpKernel\Log; interface DebugLoggerInterface { function getLogs(); function countErrors(); } <?php namespace Symfony\Component\HttpKernel\Log; interface LoggerInterface { function emerg($message, array $context = array()); function alert($message, array $context = array()); function crit($message, array $context = array()); function err($message, array $context = array()); function warn($message, array $context = array()); function notice($message, array $context = array()); function info($message, array $context = array()); function debug($message, array $context = array()); } <?php namespace Symfony\Component\HttpKernel\Log; use Symfony\Component\HttpKernel\Log\LoggerInterface; class NullLogger implements LoggerInterface { public function emerg($message, array $context = array()) { } public function alert($message, array $context = array()) { } public function crit($message, array $context = array()) { } public function err($message, array $context = array()) { } public function warn($message, array $context = array()) { } public function notice($message, array $context = array()) { } public function info($message, array $context = array()) { } public function debug($message, array $context = array()) { } } <?php namespace Symfony\Component\HttpKernel\Profiler; abstract class BaseMemcacheProfilerStorage implements ProfilerStorageInterface { const TOKEN_PREFIX = 'sf_profiler_'; protected $dsn; protected $lifetime; public function __construct($dsn, $username = '', $password = '', $lifetime = 86400) { $this->dsn = $dsn; $this->lifetime = (int) $lifetime; } public function find($ip, $url, $limit, $method) { $indexName = $this->getIndexName(); $indexContent = $this->getValue($indexName); if (!$indexContent) { return array(); } $profileList = explode("\n", $indexContent); $result = array(); foreach ($profileList as $item) { if ($limit === 0) { break; } if ($item=='') { continue; } list($itemToken, $itemIp, $itemMethod, $itemUrl, $itemTime, $itemParent) = explode("\t", $item, 6); if ($ip && false === strpos($itemIp, $ip) || $url && false === strpos($itemUrl, $url) || $method && false === strpos($itemMethod, $method)) { continue; } $result[$itemToken] = array( 'token' => $itemToken, 'ip' => $itemIp, 'method' => $itemMethod, 'url' => $itemUrl, 'time' => $itemTime, 'parent' => $itemParent, ); --$limit; } usort($result, function($a, $b) { if ($a['time'] === $b['time']) { return 0; } return $a['time'] > $b['time'] ? -1 : 1; }); return $result; } public function purge() { $this->flush(); } public function read($token) { if (empty($token)) { return false; } $profile = $this->getValue($this->getItemName($token)); if (false !== $profile) { $profile = $this->createProfileFromData($token, $profile); } return $profile; } public function write(Profile $profile) { $data = array( 'token' => $profile->getToken(), 'parent' => $profile->getParentToken(), 'children' => array_map(function ($p) { return $p->getToken(); }, $profile->getChildren()), 'data' => $profile->getCollectors(), 'ip' => $profile->getIp(), 'method' => $profile->getMethod(), 'url' => $profile->getUrl(), 'time' => $profile->getTime(), ); if ($this->setValue($this->getItemName($profile->getToken()), $data, $this->lifetime)) { $indexName = $this->getIndexName(); $indexRow = implode("\t", array( $profile->getToken(), $profile->getIp(), $profile->getMethod(), $profile->getUrl(), $profile->getTime(), $profile->getParentToken(), ))."\n"; return $this->appendValue($indexName, $indexRow, $this->lifetime); } return false; } abstract protected function getValue($key); abstract protected function setValue($key, $value, $expiration = 0); abstract protected function flush(); abstract protected function appendValue($key, $value, $expiration = 0); private function createProfileFromData($token, $data, $parent = null) { $profile = new Profile($token); $profile->setIp($data['ip']); $profile->setMethod($data['method']); $profile->setUrl($data['url']); $profile->setTime($data['time']); $profile->setCollectors($data['data']); if (!$parent && $data['parent']) { $parent = $this->read($data['parent']); } if ($parent) { $profile->setParent($parent); } foreach ($data['children'] as $token) { if (!$token) { continue; } if (!$childProfileData = $this->getValue($this->getItemName($token))) { continue; } $profile->addChild($this->createProfileFromData($token, $childProfileData, $profile)); } return $profile; } private function getItemName($token) { $name = self::TOKEN_PREFIX . $token; if ($this->isItemNameValid($name)) { return $name; } return false; } private function getIndexName() { $name = self::TOKEN_PREFIX . 'index'; if ($this->isItemNameValid($name)) { return $name; } return false; } private function isItemNameValid($name) { $length = strlen($name); if ($length > 250) { throw new \RuntimeException(sprintf('The memcache item key "%s" is too long (%s bytes). Allowed maximum size is 250 bytes.', $name, $length)); } return true; } } <?php namespace Symfony\Component\HttpKernel\Profiler; class FileProfilerStorage implements ProfilerStorageInterface { private $folder; public function __construct($dsn) { if (0 !== strpos($dsn, 'file:')) { throw new \RuntimeException(sprintf('Please check your configuration. You are trying to use FileStorage with an invalid dsn "%s". The expected format is "file:/path/to/the/storage/folder".', $this->dsn)); } $this->folder = substr($dsn, 5); if (!is_dir($this->folder)) { mkdir($this->folder); } } public function find($ip, $url, $limit, $method) { $file = $this->getIndexFilename(); if (!file_exists($file)) { return array(); } $file = fopen($file, 'r'); fseek($file, 0, SEEK_END); $result = array(); while ($limit > 0) { $line = $this->readLineFromFile($file); if (false === $line) { break; } if ($line === '') { continue; } list($csvToken, $csvIp, $csvMethod, $csvUrl, $csvTime, $csvParent) = str_getcsv($line); if ($ip && false === strpos($csvIp, $ip) || $url && false === strpos($csvUrl, $url) || $method && false === strpos($csvMethod, $method)) { continue; } $result[$csvToken] = array( 'token' => $csvToken, 'ip' => $csvIp, 'method' => $csvMethod, 'url' => $csvUrl, 'time' => $csvTime, 'parent' => $csvParent, ); --$limit; } fclose($file); return array_values($result); } public function purge() { $flags = \FilesystemIterator::SKIP_DOTS; $iterator = new \RecursiveDirectoryIterator($this->folder, $flags); $iterator = new \RecursiveIteratorIterator($iterator, \RecursiveIteratorIterator::CHILD_FIRST); foreach ($iterator as $file) { if (is_file($file)) { unlink($file); } else { rmdir($file); } } } public function read($token) { if (!$token || !file_exists($file = $this->getFilename($token))) { return null; } return $this->createProfileFromData($token, unserialize(file_get_contents($file))); } public function write(Profile $profile) { $file = $this->getFilename($profile->getToken()); $dir = dirname($file); if (!is_dir($dir)) { mkdir($dir, 0777, true); } $data = array( 'token' => $profile->getToken(), 'parent' => $profile->getParentToken(), 'children' => array_map(function ($p) { return $p->getToken(); }, $profile->getChildren()), 'data' => $profile->getCollectors(), 'ip' => $profile->getIp(), 'method' => $profile->getMethod(), 'url' => $profile->getUrl(), 'time' => $profile->getTime(), ); if (false === file_put_contents($file, serialize($data))) { return false; } if (false === $file = fopen($this->getIndexFilename(), 'a')) { return false; } fputcsv($file, array( $profile->getToken(), $profile->getIp(), $profile->getMethod(), $profile->getUrl(), $profile->getTime(), $profile->getParentToken(), )); fclose($file); return true; } protected function getFilename($token) { $folderA = substr($token, -2, 2); $folderB = substr($token, -4, 2); return $this->folder.'/'.$folderA.'/'.$folderB.'/'.$token; } protected function getIndexFilename() { return $this->folder.'/index.csv'; } protected function readLineFromFile($file) { if (ftell($file) === 0) { return false; } fseek($file, -1, SEEK_CUR); $str = ''; while (true) { $char = fgetc($file); if ($char === "\n") { fseek($file, -1, SEEK_CUR); break; } $str = $char.$str; if (ftell($file) === 1) { fseek($file, -1, SEEK_CUR); break; } fseek($file, -2, SEEK_CUR); } return $str === '' ? $this->readLineFromFile($file) : $str; } protected function createProfileFromData($token, $data, $parent = null) { $profile = new Profile($token); $profile->setIp($data['ip']); $profile->setMethod($data['method']); $profile->setUrl($data['url']); $profile->setTime($data['time']); $profile->setCollectors($data['data']); if (!$parent && $data['parent']) { $parent = $this->read($data['parent']); } if ($parent) { $profile->setParent($parent); } foreach ($data['children'] as $token) { if (!$token || !file_exists($file = $this->getFilename($token))) { continue; } $profile->addChild($this->createProfileFromData($token, unserialize(file_get_contents($file)), $profile)); } return $profile; } } <?php namespace Symfony\Component\HttpKernel\Profiler; use Memcached; class MemcachedProfilerStorage extends BaseMemcacheProfilerStorage { private $memcached; protected function getMemcached() { if (null === $this->memcached) { if (!preg_match('#^memcached://(?(?=\[.*\])\[(.*)\]|(.*)):(.*)$#', $this->dsn, $matches)) { throw new \RuntimeException(sprintf('Please check your configuration. You are trying to use Memcached with an invalid dsn "%s". The expected format is "memcached://[host]:port".', $this->dsn)); } $host = $matches[1] ?: $matches[2]; $port = $matches[3]; $memcached = new Memcached; $memcached->setOption(Memcached::OPT_COMPRESSION, false); $memcached->addServer($host, $port); $this->memcached = $memcached; } return $this->memcached; } protected function getValue($key) { return $this->getMemcached()->get($key); } protected function setValue($key, $value, $expiration = 0) { return $this->getMemcached()->set($key, $value, time() + $expiration); } protected function flush() { return $this->getMemcached()->flush(); } protected function appendValue($key, $value, $expiration = 0) { $memcached = $this->getMemcached(); if (!$result = $memcached->append($key, $value)) { return $memcached->set($key, $value, $expiration); } return $result; } } <?php namespace Symfony\Component\HttpKernel\Profiler; use Memcache; class MemcacheProfilerStorage extends BaseMemcacheProfilerStorage { private $memcache; protected function getMemcache() { if (null === $this->memcache) { if (!preg_match('#^memcache://(?(?=\[.*\])\[(.*)\]|(.*)):(.*)$#', $this->dsn, $matches)) { throw new \RuntimeException(sprintf('Please check your configuration. You are trying to use Memcache with an invalid dsn "%s". The expected format is "memcache://[host]:port".', $this->dsn)); } $host = $matches[1] ?: $matches[2]; $port = $matches[3]; $memcache = new Memcache; $memcache->addServer($host, $port); $this->memcache = $memcache; } return $this->memcache; } protected function getValue($key) { return $this->getMemcache()->get($key); } protected function setValue($key, $value, $expiration = 0) { return $this->getMemcache()->set($key, $value, false, time() + $expiration); } protected function flush() { return $this->getMemcache()->flush(); } protected function appendValue($key, $value, $expiration = 0) { $memcache = $this->getMemcache(); if (method_exists($memcache, 'append')) { if (!$result = $memcache->append($key, $value, false, $expiration)) { return $memcache->set($key, $value, false, $expiration); } return $result; } $content = $memcache->get($key); return $memcache->set($key, $content . $value, false, $expiration); } } <?php namespace Symfony\Component\HttpKernel\Profiler; class MongoDbProfilerStorage implements ProfilerStorageInterface { protected $dsn; protected $lifetime; private $mongo; public function __construct($dsn, $username = '', $password = '', $lifetime = 86400) { $this->dsn = $dsn; $this->lifetime = (int) $lifetime; } public function find($ip, $url, $limit, $method) { $cursor = $this->getMongo()->find($this->buildQuery($ip, $url, $method), array('_id', 'parent', 'ip', 'method', 'url', 'time'))->sort(array('time' => -1))->limit($limit); $tokens = array(); foreach ($cursor as $profile) { $tokens[] = $this->getData($profile); } return $tokens; } public function purge() { $this->getMongo()->remove(array()); } public function read($token) { $profile = $this->getMongo()->findOne(array('_id' => $token, 'data' => array('$exists' => true))); if (null !== $profile) { $profile = $this->createProfileFromData($this->getData($profile)); } return $profile; } public function write(Profile $profile) { $this->cleanup(); $record = array( '_id' => $profile->getToken(), 'parent' => $profile->getParentToken(), 'data' => serialize($profile->getCollectors()), 'ip' => $profile->getIp(), 'method' => $profile->getMethod(), 'url' => $profile->getUrl(), 'time' => $profile->getTime() ); return $this->getMongo()->update(array('_id' => $profile->getToken()), array_filter($record, function ($v) { return !empty($v); }), array('upsert' => true)); } protected function getMongo() { if ($this->mongo === null) { if (preg_match('#^(mongodb://.*)/(.*)/(.*)$#', $this->dsn, $matches)) { $mongo = new \Mongo($matches[1]); $database = $matches[2]; $collection = $matches[3]; $this->mongo = $mongo->selectCollection($database, $collection); } else { throw new \RuntimeException(sprintf('Please check your configuration. You are trying to use MongoDB with an invalid dsn "%s". The expected format is "mongodb://user:pass@location/database/collection"', $this->dsn)); } } return $this->mongo; } protected function createProfileFromData(array $data) { $profile = $this->getProfile($data); if ($data['parent']) { $parent = $this->getMongo()->findOne(array('_id' => $data['parent'], 'data' => array('$exists' => true))); if ($parent) { $profile->setParent($this->getProfile($this->getData($parent))); } } $profile->setChildren($this->readChildren($data['token'])); return $profile; } protected function readChildren($token) { $profiles = array(); $cursor = $this->getMongo()->find(array('parent' => $token, 'data' => array('$exists' => true))); foreach ($cursor as $d) { $profiles[] = $this->getProfile($this->getData($d)); } return $profiles; } protected function cleanup() { $this->getMongo()->remove(array('time' => array('$lt' => time() - $this->lifetime))); } private function buildQuery($ip, $url, $method) { $query = array(); if (!empty($ip)) { $query['ip'] = $ip; } if (!empty($url)) { $query['url'] = $url; } if (!empty($method)) { $query['method'] = $method; } return $query; } private function getData(array $data) { return array( 'token' => $data['_id'], 'parent' => isset($data['parent']) ? $data['parent'] : null, 'ip' => isset($data['ip']) ? $data['ip'] : null, 'method' => isset($data['method']) ? $data['method'] : null, 'url' => isset($data['url']) ? $data['url'] : null, 'time' => isset($data['time']) ? $data['time'] : null, 'data' => isset($data['data']) ? $data['data'] : null, ); } private function getProfile(array $data) { $profile = new Profile($data['token']); $profile->setIp($data['ip']); $profile->setMethod($data['method']); $profile->setUrl($data['url']); $profile->setTime($data['time']); $profile->setCollectors(unserialize($data['data'])); return $profile; } } <?php namespace Symfony\Component\HttpKernel\Profiler; class MysqlProfilerStorage extends PdoProfilerStorage { protected function initDb() { if (null === $this->db) { if (0 !== strpos($this->dsn, 'mysql')) { throw new \RuntimeException(sprintf('Please check your configuration. You are trying to use Mysql with an invalid dsn "%s". The expected format is "mysql:dbname=database_name;host=host_name".', $this->dsn)); } if (!class_exists('PDO') || !in_array('mysql', \PDO::getAvailableDrivers(), true)) { throw new \RuntimeException('You need to enable PDO_Mysql extension for the profiler to run properly.'); } $db = new \PDO($this->dsn, $this->username, $this->password); $db->exec('CREATE TABLE IF NOT EXISTS sf_profiler_data (token VARCHAR(255) PRIMARY KEY, data LONGTEXT, ip VARCHAR(64), method VARCHAR(6), url VARCHAR(255), time INTEGER UNSIGNED, parent VARCHAR(255), created_at INTEGER UNSIGNED, KEY (created_at), KEY (ip), KEY (method), KEY (url), KEY (parent))'); $this->db = $db; } return $this->db; } protected function buildCriteria($ip, $url, $limit, $method) { $criteria = array(); $args = array(); if ($ip = preg_replace('/[^\d\.]/', '', $ip)) { $criteria[] = 'ip LIKE :ip'; $args[':ip'] = '%'.$ip.'%'; } if ($url) { $criteria[] = 'url LIKE :url'; $args[':url'] = '%'.addcslashes($url, '%_\\').'%'; } if ($method) { $criteria[] = 'method = :method'; $args[':method'] = $method; } return array($criteria, $args); } } <?php namespace Symfony\Component\HttpKernel\Profiler; abstract class PdoProfilerStorage implements ProfilerStorageInterface { protected $dsn; protected $username; protected $password; protected $lifetime; protected $db; public function __construct($dsn, $username = '', $password = '', $lifetime = 86400) { $this->dsn = $dsn; $this->username = $username; $this->password = $password; $this->lifetime = (int) $lifetime; } public function find($ip, $url, $limit, $method) { list($criteria, $args) = $this->buildCriteria($ip, $url, $limit, $method); $criteria = $criteria ? 'WHERE '.implode(' AND ', $criteria) : ''; $db = $this->initDb(); $tokens = $this->fetch($db, 'SELECT token, ip, method, url, time, parent FROM sf_profiler_data '.$criteria.' ORDER BY time DESC LIMIT '.((integer) $limit), $args); $this->close($db); return $tokens; } public function read($token) { $db = $this->initDb(); $args = array(':token' => $token); $data = $this->fetch($db, 'SELECT data, parent, ip, method, url, time FROM sf_profiler_data WHERE token = :token LIMIT 1', $args); $this->close($db); if (isset($data[0]['data'])) { return $this->createProfileFromData($token, $data[0]); } return null; } public function write(Profile $profile) { $db = $this->initDb(); $args = array( ':token' => $profile->getToken(), ':parent' => $profile->getParentToken(), ':data' => base64_encode(serialize($profile->getCollectors())), ':ip' => $profile->getIp(), ':method' => $profile->getMethod(), ':url' => $profile->getUrl(), ':time' => $profile->getTime(), ':created_at' => time(), ); try { if ($this->read($profile->getToken())) { $this->exec($db, 'UPDATE sf_profiler_data SET parent = :parent, data = :data, ip = :ip, method = :method, url = :url, time = :time, created_at = :created_at WHERE token = :token', $args); } else { $this->exec($db, 'INSERT INTO sf_profiler_data (token, parent, data, ip, method, url, time, created_at) VALUES (:token, :parent, :data, :ip, :method, :url, :time, :created_at)', $args); } $this->cleanup(); $status = true; } catch (\Exception $e) { $status = false; } $this->close($db); return $status; } public function purge() { $db = $this->initDb(); $this->exec($db, 'DELETE FROM sf_profiler_data'); $this->close($db); } abstract protected function buildCriteria($ip, $url, $limit, $method); abstract protected function initDb(); protected function cleanup() { $db = $this->initDb(); $this->exec($db, 'DELETE FROM sf_profiler_data WHERE created_at < :time', array(':time' => time() - $this->lifetime)); $this->close($db); } protected function exec($db, $query, array $args = array()) { $stmt = $this->prepareStatement($db, $query); foreach ($args as $arg => $val) { $stmt->bindValue($arg, $val, is_int($val) ? \PDO::PARAM_INT : \PDO::PARAM_STR); } $success = $stmt->execute(); if (!$success) { throw new \RuntimeException(sprintf('Error executing query "%s"', $query)); } } protected function prepareStatement($db, $query) { try { $stmt = $db->prepare($query); } catch (\Exception $e) { $stmt = false; } if (false === $stmt) { throw new \RuntimeException('The database cannot successfully prepare the statement'); } return $stmt; } protected function fetch($db, $query, array $args = array()) { $stmt = $this->prepareStatement($db, $query); foreach ($args as $arg => $val) { $stmt->bindValue($arg, $val, is_int($val) ? \PDO::PARAM_INT : \PDO::PARAM_STR); } $stmt->execute(); $return = $stmt->fetchAll(\PDO::FETCH_ASSOC); return $return; } protected function close($db) { } protected function createProfileFromData($token, $data, $parent = null) { $profile = new Profile($token); $profile->setIp($data['ip']); $profile->setMethod($data['method']); $profile->setUrl($data['url']); $profile->setTime($data['time']); $profile->setCollectors(unserialize(base64_decode($data['data']))); if (!$parent && !empty($data['parent'])) { $parent = $this->read($data['parent']); } if ($parent) { $profile->setParent($parent); } $profile->setChildren($this->readChildren($token, $profile)); return $profile; } protected function readChildren($token, $parent) { $db = $this->initDb(); $data = $this->fetch($db, 'SELECT token, data, ip, method, url, time FROM sf_profiler_data WHERE parent = :token', array(':token' => $token)); $this->close($db); if (!$data) { return array(); } $profiles = array(); foreach ($data as $d) { $profiles[] = $this->createProfileFromData($d['token'], $d, $parent); } return $profiles; } } <?php namespace Symfony\Component\HttpKernel\Profiler; use Symfony\Component\HttpKernel\DataCollector\DataCollectorInterface; class Profile { private $token; private $collectors; private $ip; private $method; private $url; private $time; private $parent; private $children; public function __construct($token) { $this->token = $token; $this->collectors = array(); $this->children = array(); } public function setToken($token) { $this->token = $token; } public function getToken() { return $this->token; } public function setParent(Profile $parent) { $this->parent = $parent; } public function getParent() { return $this->parent; } public function getParentToken() { return $this->parent ? $this->parent->getToken() : null; } public function getIp() { return $this->ip; } public function setIp($ip) { $this->ip = $ip; } public function getMethod() { return $this->method; } public function setMethod($method) { $this->method = $method; } public function getUrl() { return $this->url; } public function setUrl($url) { $this->url = $url; } public function getTime() { return $this->time; } public function setTime($time) { $this->time = $time; } public function getChildren() { return $this->children; } public function setChildren(array $children) { $this->children = array(); foreach ($children as $child) { $this->addChild($child); } } public function addChild(Profile $child) { $this->children[] = $child; $child->setParent($this); } public function getCollector($name) { if (!isset($this->collectors[$name])) { throw new \InvalidArgumentException(sprintf('Collector "%s" does not exist.', $name)); } return $this->collectors[$name]; } public function getCollectors() { return $this->collectors; } public function setCollectors(array $collectors) { $this->collectors = array(); foreach ($collectors as $collector) { $this->addCollector($collector); } } public function addCollector(DataCollectorInterface $collector) { $this->collectors[$collector->getName()] = $collector; } public function hasCollector($name) { return isset($this->collectors[$name]); } public function __sleep() { return array('token', 'parent', 'children', 'collectors', 'ip', 'method', 'url', 'time'); } } <?php namespace Symfony\Component\HttpKernel\Profiler; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\Profiler\ProfilerStorageInterface; use Symfony\Component\HttpKernel\DataCollector\DataCollectorInterface; use Symfony\Component\HttpKernel\Log\LoggerInterface; class Profiler { private $storage; private $collectors; private $logger; private $enabled; public function __construct(ProfilerStorageInterface $storage, LoggerInterface $logger = null) { $this->storage = $storage; $this->logger = $logger; $this->collectors = array(); $this->enabled = true; } public function disable() { $this->enabled = false; } public function loadProfileFromResponse(Response $response) { if (!$token = $response->headers->get('X-Debug-Token')) { return false; } return $this->loadProfile($token); } public function loadProfile($token) { return $this->storage->read($token); } public function saveProfile(Profile $profile) { if (!($ret = $this->storage->write($profile)) && null !== $this->logger) { $this->logger->warn('Unable to store the profiler information.'); } return $ret; } public function purge() { $this->storage->purge(); } public function export(Profile $profile) { return base64_encode(serialize($profile)); } public function import($data) { $profile = unserialize(base64_decode($data)); if ($this->storage->read($profile->getToken())) { return false; } $this->saveProfile($profile); return $profile; } public function find($ip, $url, $limit, $method) { return $this->storage->find($ip, $url, $limit, $method); } public function collect(Request $request, Response $response, \Exception $exception = null) { if (false === $this->enabled) { return; } $profile = new Profile(uniqid()); $profile->setTime(time()); $profile->setUrl($request->getUri()); $profile->setIp($request->server->get('REMOTE_ADDR')); $profile->setMethod($request->getMethod()); $response->headers->set('X-Debug-Token', $profile->getToken()); foreach ($this->collectors as $collector) { $collector->collect($request, $response, $exception); $profile->addCollector(unserialize(serialize($collector))); } return $profile; } public function all() { return $this->collectors; } public function set(array $collectors = array()) { $this->collectors = array(); foreach ($collectors as $collector) { $this->add($collector); } } public function add(DataCollectorInterface $collector) { $this->collectors[$collector->getName()] = $collector; } public function has($name) { return isset($this->collectors[$name]); } public function get($name) { if (!isset($this->collectors[$name])) { throw new \InvalidArgumentException(sprintf('Collector "%s" does not exist.', $name)); } return $this->collectors[$name]; } } <?php namespace Symfony\Component\HttpKernel\Profiler; interface ProfilerStorageInterface { function find($ip, $url, $limit, $method); function read($token); function write(Profile $profile); function purge(); } <?php namespace Symfony\Component\HttpKernel\Profiler; use Redis; class RedisProfilerStorage implements ProfilerStorageInterface { const TOKEN_PREFIX = 'sf_profiler_'; protected $dsn; protected $lifetime; private $redis; public function __construct($dsn, $username = '', $password = '', $lifetime = 86400) { $this->dsn = $dsn; $this->lifetime = (int) $lifetime; } public function find($ip, $url, $limit, $method) { $indexName = $this->getIndexName(); if (!$indexContent = $this->getValue($indexName, Redis::SERIALIZER_NONE)) { return array(); } $profileList = explode("\n", $indexContent); $result = array(); foreach ($profileList as $item) { if ($limit === 0) { break; } if ($item == '') { continue; } list($itemToken, $itemIp, $itemMethod, $itemUrl, $itemTime, $itemParent) = explode("\t", $item, 6); if ($ip && false === strpos($itemIp, $ip) || $url && false === strpos($itemUrl, $url) || $method && false === strpos($itemMethod, $method)) { continue; } $result[$itemToken] = array( 'token' => $itemToken, 'ip' => $itemIp, 'method' => $itemMethod, 'url' => $itemUrl, 'time' => $itemTime, 'parent' => $itemParent, ); --$limit; } usort($result, function($a, $b) { if ($a['time'] === $b['time']) { return 0; } return $a['time'] > $b['time'] ? -1 : 1; }); return $result; } public function purge() { $indexName = $this->getIndexName(); $indexContent = $this->getValue($indexName, Redis::SERIALIZER_NONE); if (!$indexContent) { return false; } $profileList = explode("\n", $indexContent); $result = array(); foreach ($profileList as $item) { if ($item == '') { continue; } if (false !== $pos = strpos($item, "\t")) { $result[] = $this->getItemName(substr($item, 0, $pos)); } } $result[] = $indexName; return $this->delete($result); } public function read($token) { if (empty($token)) { return false; } $profile = $this->getValue($this->getItemName($token), Redis::SERIALIZER_PHP); if (false !== $profile) { $profile = $this->createProfileFromData($token, $profile); } return $profile; } public function write(Profile $profile) { $data = array( 'token' => $profile->getToken(), 'parent' => $profile->getParentToken(), 'children' => array_map(function ($p) { return $p->getToken(); }, $profile->getChildren()), 'data' => $profile->getCollectors(), 'ip' => $profile->getIp(), 'method' => $profile->getMethod(), 'url' => $profile->getUrl(), 'time' => $profile->getTime(), ); if ($this->setValue($this->getItemName($profile->getToken()), $data, $this->lifetime, Redis::SERIALIZER_PHP)) { $indexName = $this->getIndexName(); $indexRow = implode("\t", array( $profile->getToken(), $profile->getIp(), $profile->getMethod(), $profile->getUrl(), $profile->getTime(), $profile->getParentToken(), ))."\n"; return $this->appendValue($indexName, $indexRow, $this->lifetime); } return false; } 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)); } $host = $matches[1] ?: $matches[2]; $port = $matches[3]; if (!extension_loaded('redis')) { throw new \RuntimeException('RedisProfilerStorage requires that the redis extension is loaded.'); } $redis = new Redis; $redis->connect($host, $port); $redis->setOption(Redis::OPT_PREFIX, self::TOKEN_PREFIX); $this->redis = $redis; } return $this->redis; } private function createProfileFromData($token, $data, $parent = null) { $profile = new Profile($token); $profile->setIp($data['ip']); $profile->setMethod($data['method']); $profile->setUrl($data['url']); $profile->setTime($data['time']); $profile->setCollectors($data['data']); if (!$parent && $data['parent']) { $parent = $this->read($data['parent']); } if ($parent) { $profile->setParent($parent); } foreach ($data['children'] as $token) { if (!$token) { continue; } if (!$childProfileData = $this->getValue($this->getItemName($token), Redis::SERIALIZER_PHP)) { continue; } $profile->addChild($this->createProfileFromData($token, $childProfileData, $profile)); } return $profile; } private function getItemName($token) { $name = $token; if ($this->isItemNameValid($name)) { return $name; } return false; } private function getIndexName() { $name = 'index'; if ($this->isItemNameValid($name)) { return $name; } return false; } private function isItemNameValid($name) { $length = strlen($name); if ($length > 2147483648) { throw new \RuntimeException(sprintf('The Redis item key "%s" is too long (%s bytes). Allowed maximum size is 2^31 bytes.', $name, $length)); } return true; } private function getValue($key, $serializer = Redis::SERIALIZER_NONE) { $redis = $this->getRedis(); $redis->setOption(Redis::OPT_SERIALIZER, $serializer); return $redis->get($key); } private function setValue($key, $value, $expiration = 0, $serializer = Redis::SERIALIZER_NONE) { $redis = $this->getRedis(); $redis->setOption(Redis::OPT_SERIALIZER, $serializer); return $redis->setex($key, $expiration, $value); } private function appendValue($key, $value, $expiration = 0) { $redis = $this->getRedis(); $redis->setOption(Redis::OPT_SERIALIZER, Redis::SERIALIZER_NONE); if ($redis->exists($key)) { $redis->append($key, $value); return $redis->setTimeout($key, $expiration); } return $redis->setex($key, $expiration, $value); } private function delete(array $keys) { return (bool) $this->getRedis()->delete($keys); } } <?php namespace Symfony\Component\HttpKernel\Profiler; class SqliteProfilerStorage extends PdoProfilerStorage { protected function initDb() { if (null === $this->db || $this->db instanceof \SQLite3) { if (0 !== strpos($this->dsn, 'sqlite')) { throw new \RuntimeException(sprintf('Please check your configuration. You are trying to use Sqlite with an invalid dsn "%s". The expected format is "sqlite:/path/to/the/db/file".', $this->dsn)); } if (class_exists('SQLite3')) { $db = new \SQLite3(substr($this->dsn, 7, strlen($this->dsn)), \SQLITE3_OPEN_READWRITE | \SQLITE3_OPEN_CREATE); if (method_exists($db, 'busyTimeout')) { $db->busyTimeout(1000); } } elseif (class_exists('PDO') && in_array('sqlite', \PDO::getAvailableDrivers(), true)) { $db = new \PDO($this->dsn); } else { throw new \RuntimeException('You need to enable either the SQLite3 or PDO_SQLite extension for the profiler to run properly.'); } $db->exec('PRAGMA temp_store=MEMORY; PRAGMA journal_mode=MEMORY;'); $db->exec('CREATE TABLE IF NOT EXISTS sf_profiler_data (token STRING, data STRING, ip STRING, method STRING, url STRING, time INTEGER, parent STRING, created_at INTEGER)'); $db->exec('CREATE INDEX IF NOT EXISTS data_created_at ON sf_profiler_data (created_at)'); $db->exec('CREATE INDEX IF NOT EXISTS data_ip ON sf_profiler_data (ip)'); $db->exec('CREATE INDEX IF NOT EXISTS data_method ON sf_profiler_data (method)'); $db->exec('CREATE INDEX IF NOT EXISTS data_url ON sf_profiler_data (url)'); $db->exec('CREATE INDEX IF NOT EXISTS data_parent ON sf_profiler_data (parent)'); $db->exec('CREATE UNIQUE INDEX IF NOT EXISTS data_token ON sf_profiler_data (token)'); $this->db = $db; } return $this->db; } protected function exec($db, $query, array $args = array()) { if ($db instanceof \SQLite3) { $stmt = $this->prepareStatement($db, $query); foreach ($args as $arg => $val) { $stmt->bindValue($arg, $val, is_int($val) ? \SQLITE3_INTEGER : \SQLITE3_TEXT); } $res = $stmt->execute(); if (false === $res) { throw new \RuntimeException(sprintf('Error executing SQLite query "%s"', $query)); } $res->finalize(); } else { parent::exec($db, $query, $args); } } protected function fetch($db, $query, array $args = array()) { $return = array(); if ($db instanceof \SQLite3) { $stmt = $this->prepareStatement($db, $query, true); foreach ($args as $arg => $val) { $stmt->bindValue($arg, $val, is_int($val) ? \SQLITE3_INTEGER : \SQLITE3_TEXT); } $res = $stmt->execute(); while ($row = $res->fetchArray(\SQLITE3_ASSOC)) { $return[] = $row; } $res->finalize(); $stmt->close(); } else { $return = parent::fetch($db, $query, $args); } return $return; } protected function buildCriteria($ip, $url, $limit, $method) { $criteria = array(); $args = array(); if ($ip = preg_replace('/[^\d\.]/', '', $ip)) { $criteria[] = 'ip LIKE :ip'; $args[':ip'] = '%'.$ip.'%'; } if ($url) { $criteria[] = 'url LIKE :url ESCAPE "\"'; $args[':url'] = '%'.addcslashes($url, '%_\\').'%'; } if ($method) { $criteria[] = 'method = :method'; $args[':method'] = $method; } return array($criteria, $args); } protected function close($db) { if ($db instanceof \SQLite3) { $db->close(); } } } <?php namespace Symfony\Component\HttpKernel; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; interface TerminableInterface { function terminate(Request $request, Response $response); } <?php namespace Symfony\Component\Routing\Annotation; class Route { private $pattern; private $name; private $requirements; private $options; private $defaults; public function __construct(array $data) { $this->requirements = array(); $this->options = array(); $this->defaults = array(); if (isset($data['value'])) { $data['pattern'] = $data['value']; unset($data['value']); } foreach ($data as $key => $value) { $method = 'set'.$key; if (!method_exists($this, $method)) { throw new \BadMethodCallException(sprintf("Unknown property '%s' on annotation '%s'.", $key, get_class($this))); } $this->$method($value); } } public function setPattern($pattern) { $this->pattern = $pattern; } public function getPattern() { return $this->pattern; } public function setName($name) { $this->name = $name; } public function getName() { return $this->name; } public function setRequirements($requirements) { $this->requirements = $requirements; } public function getRequirements() { return $this->requirements; } public function setOptions($options) { $this->options = $options; } public function getOptions() { return $this->options; } public function setDefaults($defaults) { $this->defaults = $defaults; } public function getDefaults() { return $this->defaults; } } <?php namespace Symfony\Component\Routing; class CompiledRoute { private $route; private $variables; private $tokens; private $staticPrefix; private $regex; public function __construct(Route $route, $staticPrefix, $regex, array $tokens, array $variables) { $this->route = $route; $this->staticPrefix = $staticPrefix; $this->regex = $regex; $this->tokens = $tokens; $this->variables = $variables; } public function getRoute() { return $this->route; } public function getStaticPrefix() { return $this->staticPrefix; } public function getRegex() { return $this->regex; } public function getTokens() { return $this->tokens; } public function getVariables() { return $this->variables; } public function getPattern() { return $this->route->getPattern(); } public function getOptions() { return $this->route->getOptions(); } public function getDefaults() { return $this->route->getDefaults(); } public function getRequirements() { return $this->route->getRequirements(); } } <?php namespace Symfony\Component\Routing\Exception; interface ExceptionInterface { } <?php namespace Symfony\Component\Routing\Exception; class InvalidParameterException extends \InvalidArgumentException implements ExceptionInterface { } <?php namespace Symfony\Component\Routing\Exception; class MethodNotAllowedException extends \RuntimeException implements ExceptionInterface { protected $allowedMethods; public function __construct(array $allowedMethods, $message = null, $code = 0, \Exception $previous = null) { $this->allowedMethods = array_map('strtoupper', $allowedMethods); parent::__construct($message, $code, $previous); } public function getAllowedMethods() { return $this->allowedMethods; } } <?php namespace Symfony\Component\Routing\Exception; class MissingMandatoryParametersException extends \InvalidArgumentException implements ExceptionInterface { } <?php namespace Symfony\Component\Routing\Exception; class ResourceNotFoundException extends \RuntimeException implements ExceptionInterface { } <?php namespace Symfony\Component\Routing\Exception; class RouteNotFoundException extends \InvalidArgumentException implements ExceptionInterface { } <?php namespace Symfony\Component\Routing\Generator\Dumper; use Symfony\Component\Routing\RouteCollection; abstract class GeneratorDumper implements GeneratorDumperInterface { private $routes; public function __construct(RouteCollection $routes) { $this->routes = $routes; } public function getRoutes() { return $this->routes; } } <?php namespace Symfony\Component\Routing\Generator\Dumper; use Symfony\Component\Routing\RouteCollection; interface GeneratorDumperInterface { function dump(array $options = array()); function getRoutes(); } <?php namespace Symfony\Component\Routing\Generator\Dumper; use Symfony\Component\Routing\Route; class PhpGeneratorDumper extends GeneratorDumper { public function dump(array $options = array()) { $options = array_merge(array( 'class' => 'ProjectUrlGenerator', 'base_class' => 'Symfony\\Component\\Routing\\Generator\\UrlGenerator', ), $options); return <<<EOF <?php use Symfony\Component\Routing\RequestContext; use Symfony\Component\Routing\Exception\RouteNotFoundException; /** * {$options['class']} * * This class has been auto-generated * by the Symfony Routing Component. */ class {$options['class']} extends {$options['base_class']} { static private \$declaredRoutes = {$this->generateDeclaredRoutes()}; /** * Constructor. */ public function __construct(RequestContext \$context) { \$this->context = \$context; } {$this->generateGenerateMethod()} } EOF; } private function generateDeclaredRoutes() { $routes = "array(\n"; foreach ($this->getRoutes()->all() as $name => $route) { $compiledRoute = $route->compile(); $properties = array(); $properties[] = $compiledRoute->getVariables(); $properties[] = $compiledRoute->getDefaults(); $properties[] = $compiledRoute->getRequirements(); $properties[] = $compiledRoute->getTokens(); $routes .= sprintf(" '%s' => %s,\n", $name, str_replace("\n", '', var_export($properties, true))); } $routes .= ' )'; return $routes; } private function generateGenerateMethod() { return <<<EOF public function generate(\$name, \$parameters = array(), \$absolute = false) { if (!isset(self::\$declaredRoutes[\$name])) { throw new RouteNotFoundException(sprintf('Route "%s" does not exist.', \$name)); } list(\$variables, \$defaults, \$requirements, \$tokens) = self::\$declaredRoutes[\$name]; return \$this->doGenerate(\$variables, \$defaults, \$requirements, \$tokens, \$parameters, \$name, \$absolute); } EOF; } } <?php namespace Symfony\Component\Routing\Generator; use Symfony\Component\Routing\Route; use Symfony\Component\Routing\RouteCollection; use Symfony\Component\Routing\RequestContext; use Symfony\Component\Routing\Exception\InvalidParameterException; use Symfony\Component\Routing\Exception\RouteNotFoundException; use Symfony\Component\Routing\Exception\MissingMandatoryParametersException; class UrlGenerator implements UrlGeneratorInterface { protected $context; protected $decodedChars = array( '%2F' => '/', ); protected $routes; public function __construct(RouteCollection $routes, RequestContext $context) { $this->routes = $routes; $this->context = $context; } public function setContext(RequestContext $context) { $this->context = $context; } public function getContext() { return $this->context; } public function generate($name, $parameters = array(), $absolute = false) { if (null === $route = $this->routes->get($name)) { throw new RouteNotFoundException(sprintf('Route "%s" does not exist.', $name)); } $compiledRoute = $route->compile(); return $this->doGenerate($compiledRoute->getVariables(), $route->getDefaults(), $route->getRequirements(), $compiledRoute->getTokens(), $parameters, $name, $absolute); } protected function doGenerate($variables, $defaults, $requirements, $tokens, $parameters, $name, $absolute) { $variables = array_flip($variables); $originParameters = $parameters; $parameters = array_replace($this->context->getParameters(), $parameters); $tparams = array_replace($defaults, $parameters); if ($diff = array_diff_key($variables, $tparams)) { throw new MissingMandatoryParametersException(sprintf('The "%s" route has some missing mandatory parameters ("%s").', $name, implode('", "', array_keys($diff)))); } $url = ''; $optional = true; foreach ($tokens as $token) { if ('variable' === $token[0]) { if (false === $optional || !array_key_exists($token[3], $defaults) || (isset($parameters[$token[3]]) && (string) $parameters[$token[3]] != (string) $defaults[$token[3]])) { if (!$isEmpty = in_array($tparams[$token[3]], array(null, '', false), true)) { if ($tparams[$token[3]] && !preg_match('#^'.$token[2].'$#', $tparams[$token[3]])) { throw new InvalidParameterException(sprintf('Parameter "%s" for route "%s" must match "%s" ("%s" given).', $token[3], $name, $token[2], $tparams[$token[3]])); } } if (!$isEmpty || !$optional) { $url = $token[1].strtr(rawurlencode($tparams[$token[3]]), $this->decodedChars).$url; } $optional = false; } } elseif ('text' === $token[0]) { $url = $token[1].$url; $optional = false; } } if (!$url) { $url = '/'; } $extra = array_diff_key($originParameters, $variables, $defaults); if ($extra && $query = http_build_query($extra, '', '&')) { $url .= '?'.$query; } $url = $this->context->getBaseUrl().$url; if ($this->context->getHost()) { $scheme = $this->context->getScheme(); if (isset($requirements['_scheme']) && ($req = strtolower($requirements['_scheme'])) && $scheme != $req) { $absolute = true; $scheme = $req; } if ($absolute) { $port = ''; if ('http' === $scheme && 80 != $this->context->getHttpPort()) { $port = ':'.$this->context->getHttpPort(); } elseif ('https' === $scheme && 443 != $this->context->getHttpsPort()) { $port = ':'.$this->context->getHttpsPort(); } $url = $scheme.'://'.$this->context->getHost().$port.$url; } } return $url; } } <?php namespace Symfony\Component\Routing\Generator; use Symfony\Component\Routing\RequestContextAwareInterface; use Symfony\Component\Routing\Exception\RouteNotFoundException; interface UrlGeneratorInterface extends RequestContextAwareInterface { function generate($name, $parameters = array(), $absolute = false); } <?php namespace Symfony\Component\Routing\Loader; use Doctrine\Common\Annotations\Reader; use Symfony\Component\Routing\Annotation\Route as RouteAnnotation; use Symfony\Component\Config\Resource\FileResource; use Symfony\Component\Routing\Route; use Symfony\Component\Routing\RouteCollection; use Symfony\Component\Config\Loader\LoaderInterface; use Symfony\Component\Config\Loader\LoaderResolverInterface; abstract class AnnotationClassLoader implements LoaderInterface { protected $reader; protected $routeAnnotationClass = 'Symfony\\Component\\Routing\\Annotation\\Route'; protected $defaultRouteIndex; public function __construct(Reader $reader) { $this->reader = $reader; } public function setRouteAnnotationClass($class) { $this->routeAnnotationClass = $class; } public function load($class, $type = null) { if (!class_exists($class)) { throw new \InvalidArgumentException(sprintf('Class "%s" does not exist.', $class)); } $globals = array( 'pattern' => '', 'requirements' => array(), 'options' => array(), 'defaults' => array(), ); $class = new \ReflectionClass($class); if ($class->isAbstract()) { throw new \InvalidArgumentException(sprintf('Annotations from class "%s" cannot be read as it is abstract.', $class)); } if ($annot = $this->reader->getClassAnnotation($class, $this->routeAnnotationClass)) { if (null !== $annot->getPattern()) { $globals['pattern'] = $annot->getPattern(); } if (null !== $annot->getRequirements()) { $globals['requirements'] = $annot->getRequirements(); } if (null !== $annot->getOptions()) { $globals['options'] = $annot->getOptions(); } if (null !== $annot->getDefaults()) { $globals['defaults'] = $annot->getDefaults(); } } $collection = new RouteCollection(); $collection->addResource(new FileResource($class->getFileName())); foreach ($class->getMethods() as $method) { $this->defaultRouteIndex = 0; foreach ($this->reader->getMethodAnnotations($method) as $annot) { if ($annot instanceof $this->routeAnnotationClass) { $this->addRoute($collection, $annot, $globals, $class, $method); } } } return $collection; } protected function addRoute(RouteCollection $collection, $annot, $globals, \ReflectionClass $class, \ReflectionMethod $method) { $name = $annot->getName(); if (null === $name) { $name = $this->getDefaultRouteName($class, $method); } $defaults = array_merge($globals['defaults'], $annot->getDefaults()); $requirements = array_merge($globals['requirements'], $annot->getRequirements()); $options = array_merge($globals['options'], $annot->getOptions()); $route = new Route($globals['pattern'].$annot->getPattern(), $defaults, $requirements, $options); $this->configureRoute($route, $class, $method, $annot); $collection->add($name, $route); } public function supports($resource, $type = null) { return is_string($resource) && preg_match('/^(?:\\\\?[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)+$/', $resource) && (!$type || 'annotation' === $type); } public function setResolver(LoaderResolverInterface $resolver) { } public function getResolver() { } protected function getDefaultRouteName(\ReflectionClass $class, \ReflectionMethod $method) { $name = strtolower(str_replace('\\', '_', $class->getName()).'_'.$method->getName()); if ($this->defaultRouteIndex > 0) { $name .= '_'.$this->defaultRouteIndex; } $this->defaultRouteIndex++; return $name; } abstract protected function configureRoute(Route $route, \ReflectionClass $class, \ReflectionMethod $method, $annot); } <?php namespace Symfony\Component\Routing\Loader; use Symfony\Component\Routing\RouteCollection; use Symfony\Component\Config\Resource\DirectoryResource; class AnnotationDirectoryLoader extends AnnotationFileLoader { public function load($path, $type = null) { $dir = $this->locator->locate($path); $collection = new RouteCollection(); $collection->addResource(new DirectoryResource($dir, '/\.php$/')); $files = iterator_to_array(new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($dir), \RecursiveIteratorIterator::LEAVES_ONLY)); usort($files, function (\SplFileInfo $a, \SplFileInfo $b) { return (string) $a > (string) $b ? 1 : -1; }); foreach ($files as $file) { if (!$file->isFile() || '.php' !== substr($file->getFilename(), -4)) { continue; } if ($class = $this->findClass($file)) { $refl = new \ReflectionClass($class); if ($refl->isAbstract()) { continue; } $collection->addCollection($this->loader->load($class, $type)); } } return $collection; } public function supports($resource, $type = null) { try { $path = $this->locator->locate($resource); } catch (\Exception $e) { return false; } return is_string($resource) && is_dir($path) && (!$type || 'annotation' === $type); } } <?php namespace Symfony\Component\Routing\Loader; use Symfony\Component\Routing\RouteCollection; use Symfony\Component\Config\Resource\FileResource; use Symfony\Component\Config\Loader\FileLoader; use Symfony\Component\Config\FileLocator; class AnnotationFileLoader extends FileLoader { protected $loader; public function __construct(FileLocator $locator, AnnotationClassLoader $loader, $paths = array()) { if (!function_exists('token_get_all')) { throw new \RuntimeException('The Tokenizer extension is required for the routing annotation loaders.'); } parent::__construct($locator, $paths); $this->loader = $loader; } public function load($file, $type = null) { $path = $this->locator->locate($file); $collection = new RouteCollection(); if ($class = $this->findClass($path)) { $collection->addResource(new FileResource($path)); $collection->addCollection($this->loader->load($class, $type)); } return $collection; } public function supports($resource, $type = null) { return is_string($resource) && 'php' === pathinfo($resource, PATHINFO_EXTENSION) && (!$type || 'annotation' === $type); } protected function findClass($file) { $class = false; $namespace = false; $tokens = token_get_all(file_get_contents($file)); for ($i = 0, $count = count($tokens); $i < $count; $i++) { $token = $tokens[$i]; if (!is_array($token)) { continue; } if (true === $class && T_STRING === $token[0]) { return $namespace.'\\'.$token[1]; } if (true === $namespace && T_STRING === $token[0]) { $namespace = ''; do { $namespace .= $token[1]; $token = $tokens[++$i]; } while ($i < $count && is_array($token) && in_array($token[0], array(T_NS_SEPARATOR, T_STRING))); } if (T_CLASS === $token[0]) { $class = true; } if (T_NAMESPACE === $token[0]) { $namespace = true; } } return false; } } <?php namespace Symfony\Component\Routing\Loader; use Symfony\Component\Config\Loader\Loader; class ClosureLoader extends Loader { public function load($closure, $type = null) { return call_user_func($closure); } public function supports($resource, $type = null) { return $resource instanceof \Closure && (!$type || 'closure' === $type); } } <?php namespace Symfony\Component\Routing\Loader; use Symfony\Component\Config\Resource\FileResource; use Symfony\Component\Config\Loader\FileLoader; class PhpFileLoader extends FileLoader { public function load($file, $type = null) { $loader = $this; $path = $this->locator->locate($file); $this->setCurrentDir(dirname($path)); $collection = include $path; $collection->addResource(new FileResource($path)); return $collection; } public function supports($resource, $type = null) { return is_string($resource) && 'php' === pathinfo($resource, PATHINFO_EXTENSION) && (!$type || 'php' === $type); } } <?php namespace Symfony\Component\Routing\Loader; use Symfony\Component\Routing\RouteCollection; use Symfony\Component\Routing\Route; use Symfony\Component\Config\Resource\FileResource; use Symfony\Component\Config\Loader\FileLoader; class XmlFileLoader extends FileLoader { public function load($file, $type = null) { $path = $this->locator->locate($file); $xml = $this->loadFile($path); $collection = new RouteCollection(); $collection->addResource(new FileResource($path)); foreach ($xml->documentElement->childNodes as $node) { if (!$node instanceof \DOMElement) { continue; } $this->parseNode($collection, $node, $path, $file); } return $collection; } protected function parseNode(RouteCollection $collection, \DOMElement $node, $path, $file) { switch ($node->tagName) { case 'route': $this->parseRoute($collection, $node, $path); break; case 'import': $resource = (string) $node->getAttribute('resource'); $type = (string) $node->getAttribute('type'); $prefix = (string) $node->getAttribute('prefix'); $defaults = array(); $requirements = array(); $options = array(); foreach ($node->childNodes as $n) { if (!$n instanceof \DOMElement) { continue; } switch ($n->tagName) { case 'default': $defaults[(string) $n->getAttribute('key')] = trim((string) $n->nodeValue); break; case 'requirement': $requirements[(string) $n->getAttribute('key')] = trim((string) $n->nodeValue); break; case 'option': $options[(string) $n->getAttribute('key')] = trim((string) $n->nodeValue); break; default: throw new \InvalidArgumentException(sprintf('Unable to parse tag "%s"', $n->tagName)); } } $this->setCurrentDir(dirname($path)); $collection->addCollection($this->import($resource, ('' !== $type ? $type : null), false, $file), $prefix, $defaults, $requirements, $options); break; default: throw new \InvalidArgumentException(sprintf('Unable to parse tag "%s"', $node->tagName)); } } public function supports($resource, $type = null) { return is_string($resource) && 'xml' === pathinfo($resource, PATHINFO_EXTENSION) && (!$type || 'xml' === $type); } protected function parseRoute(RouteCollection $collection, \DOMElement $definition, $file) { $defaults = array(); $requirements = array(); $options = array(); foreach ($definition->childNodes as $node) { if (!$node instanceof \DOMElement) { continue; } switch ($node->tagName) { case 'default': $defaults[(string) $node->getAttribute('key')] = trim((string) $node->nodeValue); break; case 'option': $options[(string) $node->getAttribute('key')] = trim((string) $node->nodeValue); break; case 'requirement': $requirements[(string) $node->getAttribute('key')] = trim((string) $node->nodeValue); break; default: throw new \InvalidArgumentException(sprintf('Unable to parse tag "%s"', $node->tagName)); } } $route = new Route((string) $definition->getAttribute('pattern'), $defaults, $requirements, $options); $collection->add((string) $definition->getAttribute('id'), $route); } protected function loadFile($file) { $dom = new \DOMDocument(); libxml_use_internal_errors(true); if (!$dom->load($file, defined('LIBXML_COMPACT') ? LIBXML_COMPACT : 0)) { throw new \InvalidArgumentException(implode("\n", $this->getXmlErrors())); } $dom->validateOnParse = true; $dom->normalizeDocument(); libxml_use_internal_errors(false); $this->validate($dom); return $dom; } protected function validate(\DOMDocument $dom) { $location = __DIR__.'/schema/routing/routing-1.0.xsd'; $current = libxml_use_internal_errors(true); if (!$dom->schemaValidate($location)) { throw new \InvalidArgumentException(implode("\n", $this->getXmlErrors())); } libxml_use_internal_errors($current); } private function getXmlErrors() { $errors = array(); foreach (libxml_get_errors() as $error) { $errors[] = sprintf('[%s %s] %s (in %s - line %d, column %d)', LIBXML_ERR_WARNING == $error->level ? 'WARNING' : 'ERROR', $error->code, trim($error->message), $error->file ? $error->file : 'n/a', $error->line, $error->column ); } libxml_clear_errors(); return $errors; } } <?php namespace Symfony\Component\Routing\Loader; use Symfony\Component\Routing\RouteCollection; use Symfony\Component\Routing\Route; use Symfony\Component\Config\Resource\FileResource; use Symfony\Component\Yaml\Yaml; use Symfony\Component\Config\Loader\FileLoader; class YamlFileLoader extends FileLoader { private static $availableKeys = array( 'type', 'resource', 'prefix', 'pattern', 'options', 'defaults', 'requirements' ); public function load($file, $type = null) { $path = $this->locator->locate($file); $config = Yaml::parse($path); $collection = new RouteCollection(); $collection->addResource(new FileResource($path)); if (null === $config) { $config = array(); } if (!is_array($config)) { throw new \InvalidArgumentException(sprintf('The file "%s" must contain a YAML array.', $file)); } foreach ($config as $name => $config) { $config = $this->normalizeRouteConfig($config); if (isset($config['resource'])) { $type = isset($config['type']) ? $config['type'] : null; $prefix = isset($config['prefix']) ? $config['prefix'] : null; $defaults = isset($config['defaults']) ? $config['defaults'] : array(); $requirements = isset($config['requirements']) ? $config['requirements'] : array(); $options = isset($config['options']) ? $config['options'] : array(); $this->setCurrentDir(dirname($path)); $collection->addCollection($this->import($config['resource'], $type, false, $file), $prefix, $defaults, $requirements, $options); } else { $this->parseRoute($collection, $name, $config, $path); } } return $collection; } public function supports($resource, $type = null) { return is_string($resource) && 'yml' === pathinfo($resource, PATHINFO_EXTENSION) && (!$type || 'yaml' === $type); } protected function parseRoute(RouteCollection $collection, $name, $config, $file) { $defaults = isset($config['defaults']) ? $config['defaults'] : array(); $requirements = isset($config['requirements']) ? $config['requirements'] : array(); $options = isset($config['options']) ? $config['options'] : array(); if (!isset($config['pattern'])) { throw new \InvalidArgumentException(sprintf('You must define a "pattern" for the "%s" route.', $name)); } $route = new Route($config['pattern'], $defaults, $requirements, $options); $collection->add($name, $route); } private function normalizeRouteConfig(array $config) { foreach ($config as $key => $value) { if (!in_array($key, self::$availableKeys)) { throw new \InvalidArgumentException(sprintf( 'Yaml routing loader does not support given key: "%s". Expected one of the (%s).', $key, implode(', ', self::$availableKeys) )); } } return $config; } } <?php namespace Symfony\Component\Routing\Matcher; use Symfony\Component\Routing\Exception\MethodNotAllowedException; class ApacheUrlMatcher extends UrlMatcher { public function match($pathinfo) { $parameters = array(); $allow = array(); $match = false; foreach ($_SERVER as $key => $value) { $name = $key; if (0 === strpos($name, 'REDIRECT_')) { $name = substr($name, 9); } if (0 === strpos($name, '_ROUTING_')) { $name = substr($name, 9); } else { continue; } if ('_route' == $name) { $match = true; $parameters[$name] = $value; } elseif (0 === strpos($name, '_allow_')) { $allow[] = substr($name, 7); } else { $parameters[$name] = $value; } unset($_SERVER[$key]); } if ($match) { return $parameters; } elseif (0 < count($allow)) { throw new MethodNotAllowedException($allow); } else { return parent::match($pathinfo); } } } <?php namespace Symfony\Component\Routing\Matcher\Dumper; class ApacheMatcherDumper extends MatcherDumper { public function dump(array $options = array()) { $options = array_merge(array( 'script_name' => 'app.php', 'base_uri' => '', ), $options); $options['script_name'] = self::escape($options['script_name'], ' ', '\\'); $rules = array("# skip \"real\" requests\nRewriteCond %{REQUEST_FILENAME} -f\nRewriteRule .* - [QSA,L]"); $methodVars = array(); foreach ($this->getRoutes()->all() as $name => $route) { $compiledRoute = $route->compile(); $regex = $compiledRoute->getRegex(); $delimiter = $regex[0]; $regexPatternEnd = strrpos($regex, $delimiter); if (strlen($regex) < 2 || 0 === $regexPatternEnd) { throw new \LogicException('The "%s" route regex "%s" is invalid', $name, $regex); } $regex = preg_replace('/\?<.+?>/', '', substr($regex, 1, $regexPatternEnd - 1)); $regex = '^'.self::escape(preg_quote($options['base_uri']).substr($regex, 1), ' ', '\\'); $methods = array(); if ($req = $route->getRequirement('_method')) { $methods = explode('|', strtoupper($req)); if (in_array('GET', $methods) && !in_array('HEAD', $methods)) { $methods[] = 'HEAD'; } } $hasTrailingSlash = (!$methods || in_array('HEAD', $methods)) && '/$' === substr($regex, -2) && '^/$' !== $regex; $variables = array('E=_ROUTING__route:'.$name); foreach ($compiledRoute->getVariables() as $i => $variable) { $variables[] = 'E=_ROUTING_'.$variable.':%'.($i + 1); } foreach ($route->getDefaults() as $key => $value) { $variables[] = 'E=_ROUTING_'.$key.':'.strtr($value, array( ':' => '\\:', '=' => '\\=', '\\' => '\\\\', ' ' => '\\ ', )); } $variables = implode(',', $variables); $rule = array("# $name"); if ($req = $route->getRequirement('_method')) { $methods = explode('|', strtoupper($req)); if (in_array('GET', $methods) && !in_array('HEAD', $methods)) { $methods[] = 'HEAD'; } $allow = array(); foreach ($methods as $method) { $methodVars[] = $method; $allow[] = 'E=_ROUTING__allow_'.$method.':1'; } $rule[] = "RewriteCond %{REQUEST_URI} $regex"; $rule[] = sprintf("RewriteCond %%{REQUEST_METHOD} !^(%s)$ [NC]", implode('|', $methods)); $rule[] = sprintf('RewriteRule .* - [S=%d,%s]', $hasTrailingSlash ? 2 : 1, implode(',', $allow)); } if ($hasTrailingSlash) { $rule[] = 'RewriteCond %{REQUEST_URI} '.substr($regex, 0, -2).'$'; $rule[] = 'RewriteRule .* $0/ [QSA,L,R=301]'; } $rule[] = "RewriteCond %{REQUEST_URI} $regex"; $rule[] = "RewriteRule .* {$options['script_name']} [QSA,L,$variables]"; $rules[] = implode("\n", $rule); } if (0 < count($methodVars)) { $rule = array('# 405 Method Not Allowed'); $methodVars = array_values(array_unique($methodVars)); foreach ($methodVars as $i => $methodVar) { $rule[] = sprintf('RewriteCond %%{_ROUTING__allow_%s} !-z%s', $methodVar, isset($methodVars[$i + 1]) ? ' [OR]' : ''); } $rule[] = sprintf('RewriteRule .* %s [QSA,L]', $options['script_name']); $rules[] = implode("\n", $rule); } return implode("\n\n", $rules)."\n"; } static private function escape($string, $char, $with) { $escaped = false; $output = ''; foreach(str_split($string) as $symbol) { if ($escaped) { $output .= $symbol; $escaped = false; continue; } if ($symbol === $char) { $output .= $with.$char; continue; } if ($symbol === $with) { $escaped = true; } $output .= $symbol; } return $output; } } <?php namespace Symfony\Component\Routing\Matcher\Dumper; use Symfony\Component\Routing\RouteCollection; abstract class MatcherDumper implements MatcherDumperInterface { private $routes; public function __construct(RouteCollection $routes) { $this->routes = $routes; } public function getRoutes() { return $this->routes; } } <?php namespace Symfony\Component\Routing\Matcher\Dumper; interface MatcherDumperInterface { function dump(array $options = array()); function getRoutes(); } <?php namespace Symfony\Component\Routing\Matcher\Dumper; use Symfony\Component\Routing\Route; use Symfony\Component\Routing\RouteCollection; class PhpMatcherDumper extends MatcherDumper { public function dump(array $options = array()) { $options = array_merge(array( 'class' => 'ProjectUrlMatcher', 'base_class' => 'Symfony\\Component\\Routing\\Matcher\\UrlMatcher', ), $options); $interfaces = class_implements($options['base_class']); $supportsRedirections = isset($interfaces['Symfony\\Component\\Routing\\Matcher\\RedirectableUrlMatcherInterface']); return <<<EOF <?php use Symfony\Component\Routing\Exception\MethodNotAllowedException; use Symfony\Component\Routing\Exception\ResourceNotFoundException; use Symfony\Component\Routing\RequestContext; /** * {$options['class']} * * This class has been auto-generated * by the Symfony Routing Component. */ class {$options['class']} extends {$options['base_class']} { /** * Constructor. */ public function __construct(RequestContext \$context) { \$this->context = \$context; } {$this->generateMatchMethod($supportsRedirections)} } EOF; } private function generateMatchMethod($supportsRedirections) { $code = rtrim($this->compileRoutes($this->getRoutes(), $supportsRedirections), "\n"); return <<<EOF public function match(\$pathinfo) { \$allow = array(); \$pathinfo = rawurldecode(\$pathinfo); $code throw 0 < count(\$allow) ? new MethodNotAllowedException(array_unique(\$allow)) : new ResourceNotFoundException(); } EOF; } private function countDirectChildRoutes(RouteCollection $routes) { $count = 0; foreach ($routes as $route) { if ($route instanceof Route) { $count++; } } return $count; } private function compileRoutes(RouteCollection $routes, $supportsRedirections, $parentPrefix = null) { $code = ''; $prefix = $routes->getPrefix(); $countDirectChildRoutes = $this->countDirectChildRoutes($routes); $countAllChildRoutes = count($routes->all()); $optimizable = '' !== $prefix && $prefix !== $parentPrefix && $countDirectChildRoutes > 0 && $countAllChildRoutes > 1 && false === strpos($prefix, '{'); if ($optimizable) { $code .= sprintf(" if (0 === strpos(\$pathinfo, %s)) {\n", var_export($prefix, true)); } foreach ($routes as $name => $route) { if ($route instanceof Route) { $code .= $this->compileRoute($route, $name, $supportsRedirections, 1 === $countAllChildRoutes ? null : $prefix)."\n"; } elseif ($countAllChildRoutes - $countDirectChildRoutes > 0) { $code .= $this->compileRoutes($route, $supportsRedirections, $prefix); } } if ($optimizable) { $code .= " }\n\n"; $code = preg_replace('/^.{2,}$/m', ' $0', $code); } return $code; } private function compileRoute(Route $route, $name, $supportsRedirections, $parentPrefix = null) { $code = ''; $compiledRoute = $route->compile(); $conditions = array(); $hasTrailingSlash = false; $matches = false; $methods = array(); if ($req = $route->getRequirement('_method')) { $methods = explode('|', strtoupper($req)); if (in_array('GET', $methods) && !in_array('HEAD', $methods)) { $methods[] = 'HEAD'; } } $supportsTrailingSlash = $supportsRedirections && (!$methods || in_array('HEAD', $methods)); if (!count($compiledRoute->getVariables()) && false !== preg_match('#^(.)\^(?<url>.*?)\$\1#', $compiledRoute->getRegex(), $m)) { if ($supportsTrailingSlash && substr($m['url'], -1) === '/') { $conditions[] = sprintf("rtrim(\$pathinfo, '/') === %s", var_export(rtrim(str_replace('\\', '', $m['url']), '/'), true)); $hasTrailingSlash = true; } else { $conditions[] = sprintf("\$pathinfo === %s", var_export(str_replace('\\', '', $m['url']), true)); } } else { if ($compiledRoute->getStaticPrefix() && $compiledRoute->getStaticPrefix() !== $parentPrefix) { $conditions[] = sprintf("0 === strpos(\$pathinfo, %s)", var_export($compiledRoute->getStaticPrefix(), true)); } $regex = $compiledRoute->getRegex(); if ($supportsTrailingSlash && $pos = strpos($regex, '/$')) { $regex = substr($regex, 0, $pos).'/?$'.substr($regex, $pos + 2); $hasTrailingSlash = true; } $conditions[] = sprintf("preg_match(%s, \$pathinfo, \$matches)", var_export($regex, true)); $matches = true; } $conditions = implode(' && ', $conditions); $code .= <<<EOF // $name if ($conditions) { EOF; if ($methods) { $gotoname = 'not_'.preg_replace('/[^A-Za-z0-9_]/', '', $name); if (1 === count($methods)) { $code .= <<<EOF if (\$this->context->getMethod() != '$methods[0]') { \$allow[] = '$methods[0]'; goto $gotoname; } EOF; } else { $methods = implode("', '", $methods); $code .= <<<EOF if (!in_array(\$this->context->getMethod(), array('$methods'))) { \$allow = array_merge(\$allow, array('$methods')); goto $gotoname; } EOF; } } if ($hasTrailingSlash) { $code .= <<<EOF if (substr(\$pathinfo, -1) !== '/') { return \$this->redirect(\$pathinfo.'/', '$name'); } EOF; } if ($scheme = $route->getRequirement('_scheme')) { if (!$supportsRedirections) { throw new \LogicException('The "_scheme" requirement is only supported for URL matchers that implement RedirectableUrlMatcherInterface.'); } $code .= <<<EOF if (\$this->context->getScheme() !== '$scheme') { return \$this->redirect(\$pathinfo, '$name', '$scheme'); } EOF; } if (true === $matches && $compiledRoute->getDefaults()) { $code .= sprintf(" return array_merge(\$this->mergeDefaults(\$matches, %s), array('_route' => '%s'));\n" , str_replace("\n", '', var_export($compiledRoute->getDefaults(), true)), $name); } elseif (true === $matches) { $code .= sprintf(" \$matches['_route'] = '%s';\n", $name); $code .= " return \$matches;\n"; } elseif ($compiledRoute->getDefaults()) { $code .= sprintf(" return %s;\n", str_replace("\n", '', var_export(array_merge($compiledRoute->getDefaults(), array('_route' => $name)), true))); } else { $code .= sprintf(" return array('_route' => '%s');\n", $name); } $code .= " }\n"; if ($methods) { $code .= " $gotoname:\n"; } return $code; } } <?php namespace Symfony\Component\Routing\Matcher; use Symfony\Component\Routing\Exception\ResourceNotFoundException; use Symfony\Component\Routing\Route; abstract class RedirectableUrlMatcher extends UrlMatcher implements RedirectableUrlMatcherInterface { public function match($pathinfo) { try { $parameters = parent::match($pathinfo); } catch (ResourceNotFoundException $e) { if ('/' === substr($pathinfo, -1)) { throw $e; } try { parent::match($pathinfo.'/'); return $this->redirect($pathinfo.'/', null); } catch (ResourceNotFoundException $e2) { throw $e; } } return $parameters; } protected function handleRouteRequirements($pathinfo, $name, Route $route) { $scheme = $route->getRequirement('_scheme'); if ($scheme && $this->context->getScheme() !== $scheme) { return array(self::ROUTE_MATCH, $this->redirect($pathinfo, $name, $scheme)); } return array(self::REQUIREMENT_MATCH, null); } } <?php namespace Symfony\Component\Routing\Matcher; interface RedirectableUrlMatcherInterface { function redirect($path, $route, $scheme = null); } <?php namespace Symfony\Component\Routing\Matcher; use Symfony\Component\Routing\Exception\ExceptionInterface; use Symfony\Component\Routing\Route; use Symfony\Component\Routing\RouteCollection; use Symfony\Component\Routing\Matcher\UrlMatcher; class TraceableUrlMatcher extends UrlMatcher { const ROUTE_DOES_NOT_MATCH = 0; const ROUTE_ALMOST_MATCHES = 1; const ROUTE_MATCHES = 2; protected $traces; public function getTraces($pathinfo) { $this->traces = array(); try { $this->match($pathinfo); } catch (ExceptionInterface $e) { } return $this->traces; } protected function matchCollection($pathinfo, RouteCollection $routes) { foreach ($routes as $name => $route) { if ($route instanceof RouteCollection) { if (!$ret = $this->matchCollection($pathinfo, $route)) { continue; } return true; } $compiledRoute = $route->compile(); if (!preg_match($compiledRoute->getRegex(), $pathinfo, $matches)) { $r = new Route($route->getPattern(), $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); continue; } foreach ($route->getRequirements() as $n => $regex) { $r = new Route($route->getPattern(), $route->getDefaults(), array($n => $regex), $route->getOptions()); $cr = $r->compile(); if (in_array($n, $cr->getVariables()) && !preg_match($cr->getRegex(), $pathinfo)) { $this->addTrace(sprintf('Requirement for "%s" does not match (%s)', $n, $regex), self::ROUTE_ALMOST_MATCHES, $name, $route); continue 2; } } continue; } if ($req = $route->getRequirement('_method')) { if ('HEAD' === $method = $this->context->getMethod()) { $method = 'GET'; } if (!in_array($method, $req = explode('|', strtoupper($req)))) { $this->allow = array_merge($this->allow, $req); $this->addTrace(sprintf('Method "%s" does not match the requirement ("%s")', $this->context->getMethod(), implode(', ', $req)), self::ROUTE_ALMOST_MATCHES, $name, $route); continue; } } if ($scheme = $route->getRequirement('_scheme')) { if ($this->context->getScheme() !== $scheme) { $this->addTrace(sprintf('Scheme "%s" does not match the requirement ("%s"); the user will be redirected', $this->context->getScheme(), $scheme), self::ROUTE_ALMOST_MATCHES, $name, $route); return true; } } $this->addTrace('Route matches!', self::ROUTE_MATCHES, $name, $route); return true; } } private function addTrace($log, $level = self::ROUTE_DOES_NOT_MATCH, $name = null, $route = null) { $this->traces[] = array( 'log' => $log, 'name' => $name, 'level' => $level, 'pattern' => null !== $route ? $route->getPattern() : null, ); } } <?php namespace Symfony\Component\Routing\Matcher; use Symfony\Component\Routing\Exception\MethodNotAllowedException; use Symfony\Component\Routing\Exception\ResourceNotFoundException; use Symfony\Component\Routing\RouteCollection; use Symfony\Component\Routing\RequestContext; use Symfony\Component\Routing\Route; class UrlMatcher implements UrlMatcherInterface { const REQUIREMENT_MATCH = 0; const REQUIREMENT_MISMATCH = 1; const ROUTE_MATCH = 2; protected $context; protected $allow; private $routes; public function __construct(RouteCollection $routes, RequestContext $context) { $this->routes = $routes; $this->context = $context; } public function setContext(RequestContext $context) { $this->context = $context; } public function getContext() { return $this->context; } public function match($pathinfo) { $this->allow = array(); if ($ret = $this->matchCollection(rawurldecode($pathinfo), $this->routes)) { return $ret; } throw 0 < count($this->allow) ? new MethodNotAllowedException(array_unique(array_map('strtoupper', $this->allow))) : new ResourceNotFoundException(); } protected function matchCollection($pathinfo, RouteCollection $routes) { foreach ($routes as $name => $route) { if ($route instanceof RouteCollection) { if (false === strpos($route->getPrefix(), '{') && $route->getPrefix() !== substr($pathinfo, 0, strlen($route->getPrefix()))) { continue; } if (!$ret = $this->matchCollection($pathinfo, $route)) { continue; } return $ret; } $compiledRoute = $route->compile(); if ('' !== $compiledRoute->getStaticPrefix() && 0 !== strpos($pathinfo, $compiledRoute->getStaticPrefix())) { continue; } if (!preg_match($compiledRoute->getRegex(), $pathinfo, $matches)) { continue; } if ($req = $route->getRequirement('_method')) { if ('HEAD' === $method = $this->context->getMethod()) { $method = 'GET'; } if (!in_array($method, $req = explode('|', strtoupper($req)))) { $this->allow = array_merge($this->allow, $req); continue; } } $status = $this->handleRouteRequirements($pathinfo, $name, $route); if (self::ROUTE_MATCH === $status[0]) { return $status[1]; } if (self::REQUIREMENT_MISMATCH === $status[0]) { continue; } return array_merge($this->mergeDefaults($matches, $route->getDefaults()), array('_route' => $name)); } } protected function handleRouteRequirements($pathinfo, $name, Route $route) { $scheme = $route->getRequirement('_scheme'); $status = $scheme && $scheme !== $this->context->getScheme() ? self::REQUIREMENT_MISMATCH : self::REQUIREMENT_MATCH; return array($status, null); } protected function mergeDefaults($params, $defaults) { $parameters = $defaults; foreach ($params as $key => $value) { if (!is_int($key)) { $parameters[$key] = $value; } } return $parameters; } } <?php namespace Symfony\Component\Routing\Matcher; use Symfony\Component\Routing\RequestContextAwareInterface; use Symfony\Component\Routing\Exception\ResourceNotFoundException; use Symfony\Component\Routing\Exception\MethodNotAllowedException; interface UrlMatcherInterface extends RequestContextAwareInterface { function match($pathinfo); } <?php namespace Symfony\Component\Routing; use Symfony\Component\HttpFoundation\Request; class RequestContext { private $baseUrl; private $method; private $host; private $scheme; private $httpPort; private $httpsPort; private $parameters; public function __construct($baseUrl = '', $method = 'GET', $host = 'localhost', $scheme = 'http', $httpPort = 80, $httpsPort = 443) { $this->baseUrl = $baseUrl; $this->method = strtoupper($method); $this->host = $host; $this->scheme = strtolower($scheme); $this->httpPort = $httpPort; $this->httpsPort = $httpsPort; $this->parameters = array(); } public function fromRequest(Request $request) { $this->setBaseUrl($request->getBaseUrl()); $this->setMethod($request->getMethod()); $this->setHost($request->getHost()); $this->setScheme($request->getScheme()); $this->setHttpPort($request->isSecure() ? $this->httpPort : $request->getPort()); $this->setHttpsPort($request->isSecure() ? $request->getPort() : $this->httpsPort); } public function getBaseUrl() { return $this->baseUrl; } public function setBaseUrl($baseUrl) { $this->baseUrl = $baseUrl; } public function getMethod() { return $this->method; } public function setMethod($method) { $this->method = strtoupper($method); } public function getHost() { return $this->host; } public function setHost($host) { $this->host = $host; } public function getScheme() { return $this->scheme; } public function setScheme($scheme) { $this->scheme = strtolower($scheme); } public function getHttpPort() { return $this->httpPort; } public function setHttpPort($httpPort) { $this->httpPort = $httpPort; } public function getHttpsPort() { return $this->httpsPort; } public function setHttpsPort($httpsPort) { $this->httpsPort = $httpsPort; } public function getParameters() { return $this->parameters; } public function setParameters(array $parameters) { $this->parameters = $parameters; return $this; } public function getParameter($name) { return isset($this->parameters[$name]) ? $this->parameters[$name] : null; } public function hasParameter($name) { return array_key_exists($name, $this->parameters); } public function setParameter($name, $parameter) { $this->parameters[$name] = $parameter; } } <?php namespace Symfony\Component\Routing; interface RequestContextAwareInterface { function setContext(RequestContext $context); function getContext(); } <?php namespace Symfony\Component\Routing; class Route { private $pattern; private $defaults; private $requirements; private $options; private $compiled; static private $compilers = array(); public function __construct($pattern, array $defaults = array(), array $requirements = array(), array $options = array()) { $this->setPattern($pattern); $this->setDefaults($defaults); $this->setRequirements($requirements); $this->setOptions($options); } public function __clone() { $this->compiled = null; } public function getPattern() { return $this->pattern; } public function setPattern($pattern) { $this->pattern = trim($pattern); if ('' === $this->pattern || '/' !== $this->pattern[0]) { $this->pattern = '/'.$this->pattern; } $this->compiled = null; return $this; } public function getOptions() { return $this->options; } public function setOptions(array $options) { $this->options = array( 'compiler_class' => 'Symfony\\Component\\Routing\\RouteCompiler', ); return $this->addOptions($options); } public function addOptions(array $options) { foreach ($options as $name => $option) { $this->options[(string) $name] = $option; } $this->compiled = null; return $this; } public function setOption($name, $value) { $this->options[$name] = $value; $this->compiled = null; return $this; } public function getOption($name) { return isset($this->options[$name]) ? $this->options[$name] : null; } public function getDefaults() { return $this->defaults; } public function setDefaults(array $defaults) { $this->defaults = array(); return $this->addDefaults($defaults); } public function addDefaults(array $defaults) { foreach ($defaults as $name => $default) { $this->defaults[(string) $name] = $default; } $this->compiled = null; return $this; } public function getDefault($name) { return isset($this->defaults[$name]) ? $this->defaults[$name] : null; } public function hasDefault($name) { return array_key_exists($name, $this->defaults); } public function setDefault($name, $default) { $this->defaults[(string) $name] = $default; $this->compiled = null; return $this; } public function getRequirements() { return $this->requirements; } public function setRequirements(array $requirements) { $this->requirements = array(); return $this->addRequirements($requirements); } public function addRequirements(array $requirements) { foreach ($requirements as $key => $regex) { $this->requirements[$key] = $this->sanitizeRequirement($key, $regex); } $this->compiled = null; return $this; } public function getRequirement($key) { return isset($this->requirements[$key]) ? $this->requirements[$key] : null; } public function setRequirement($key, $regex) { $this->requirements[$key] = $this->sanitizeRequirement($key, $regex); $this->compiled = null; return $this; } public function compile() { if (null !== $this->compiled) { return $this->compiled; } $class = $this->getOption('compiler_class'); if (!isset(self::$compilers[$class])) { self::$compilers[$class] = new $class; } return $this->compiled = self::$compilers[$class]->compile($this); } private function sanitizeRequirement($key, $regex) { if (!is_string($regex)) { throw new \InvalidArgumentException(sprintf('Routing requirement for "%s" must be a string', $key)); } if ('' === $regex) { throw new \InvalidArgumentException(sprintf('Routing requirement for "%s" cannot be empty', $key)); } if ('^' === $regex[0]) { $regex = substr($regex, 1); } if ('$' === substr($regex, -1)) { $regex = substr($regex, 0, -1); } return $regex; } } <?php namespace Symfony\Component\Routing; use Symfony\Component\Config\Resource\ResourceInterface; class RouteCollection implements \IteratorAggregate { private $routes; private $resources; private $prefix; private $parent; public function __construct() { $this->routes = array(); $this->resources = array(); $this->prefix = ''; } public function __clone() { foreach ($this->routes as $name => $route) { $this->routes[$name] = clone $route; if ($route instanceof RouteCollection) { $this->routes[$name]->setParent($this); } } } public function getParent() { return $this->parent; } public function getRoot() { $parent = $this; while ($parent->getParent()) { $parent = $parent->getParent(); } return $parent; } public function getIterator() { return new \ArrayIterator($this->routes); } public function add($name, Route $route) { if (!preg_match('/^[a-z0-9A-Z_.]+$/', $name)) { throw new \InvalidArgumentException(sprintf('The provided route name "%s" contains non valid characters. A route name must only contain digits (0-9), letters (a-z and A-Z), underscores (_) and dots (.).', $name)); } $this->remove($name); $this->routes[$name] = $route; } public function all() { $routes = array(); foreach ($this->routes as $name => $route) { if ($route instanceof RouteCollection) { $routes = array_merge($routes, $route->all()); } else { $routes[$name] = $route; } } return $routes; } public function get($name) { if (isset($this->routes[$name])) { return $this->routes[$name] instanceof RouteCollection ? null : $this->routes[$name]; } foreach ($this->routes as $routes) { if ($routes instanceof RouteCollection && null !== $route = $routes->get($name)) { return $route; } } return null; } public function remove($name) { $root = $this->getRoot(); foreach ((array) $name as $n) { $root->removeRecursively($n); } } public function addCollection(RouteCollection $collection, $prefix = '', $defaults = array(), $requirements = array(), $options = array()) { $root = $this->getRoot(); if ($root === $collection || $root->hasCollection($collection)) { throw new \InvalidArgumentException('The RouteCollection already exists in the tree.'); } $this->remove(array_keys($collection->all())); $collection->setParent($this); $collection->addPrefix($this->getPrefix() . $prefix, $defaults, $requirements, $options); $this->routes[] = $collection; } public function addPrefix($prefix, $defaults = array(), $requirements = array(), $options = array()) { $prefix = rtrim($prefix, '/'); if ('' === $prefix && empty($defaults) && empty($requirements) && empty($options)) { return; } if ('' !== $prefix && '/' !== $prefix[0]) { $prefix = '/'.$prefix; } $this->prefix = $prefix.$this->prefix; foreach ($this->routes as $route) { if ($route instanceof RouteCollection) { $route->addPrefix($prefix, $defaults, $requirements, $options); } else { $route->setPattern($prefix.$route->getPattern()); $route->addDefaults($defaults); $route->addRequirements($requirements); $route->addOptions($options); } } } public function getPrefix() { return $this->prefix; } public function getResources() { $resources = $this->resources; foreach ($this as $routes) { if ($routes instanceof RouteCollection) { $resources = array_merge($resources, $routes->getResources()); } } return array_unique($resources); } public function addResource(ResourceInterface $resource) { $this->resources[] = $resource; } private function setParent(RouteCollection $parent) { $this->parent = $parent; } private function removeRecursively($name) { if (isset($this->routes[$name])) { unset($this->routes[$name]); return true; } foreach ($this->routes as $routes) { if ($routes instanceof RouteCollection && $routes->removeRecursively($name)) { return true; } } return false; } private function hasCollection(RouteCollection $collection) { foreach ($this->routes as $routes) { if ($routes === $collection || $routes instanceof RouteCollection && $routes->hasCollection($collection)) { return true; } } return false; } } <?php namespace Symfony\Component\Routing; class RouteCompiler implements RouteCompilerInterface { const REGEX_DELIMITER = '#'; public function compile(Route $route) { $pattern = $route->getPattern(); $len = strlen($pattern); $tokens = array(); $variables = array(); $pos = 0; preg_match_all('#.\{([\w\d_]+)\}#', $pattern, $matches, PREG_OFFSET_CAPTURE | PREG_SET_ORDER); foreach ($matches as $match) { if ($text = substr($pattern, $pos, $match[0][1] - $pos)) { $tokens[] = array('text', $text); } $seps = array($pattern[$pos]); $pos = $match[0][1] + strlen($match[0][0]); $var = $match[1][0]; if ($req = $route->getRequirement($var)) { $regexp = $req; } else { if ($pos !== $len) { $seps[] = $pattern[$pos]; } $regexp = sprintf('[^%s]+?', preg_quote(implode('', array_unique($seps)), self::REGEX_DELIMITER)); } $tokens[] = array('variable', $match[0][0][0], $regexp, $var); if (in_array($var, $variables)) { throw new \LogicException(sprintf('Route pattern "%s" cannot reference variable name "%s" more than once.', $route->getPattern(), $var)); } $variables[] = $var; } if ($pos < $len) { $tokens[] = array('text', substr($pattern, $pos)); } $firstOptional = INF; for ($i = count($tokens) - 1; $i >= 0; $i--) { $token = $tokens[$i]; if ('variable' === $token[0] && $route->hasDefault($token[3])) { $firstOptional = $i; } else { break; } } $regexp = ''; for ($i = 0, $nbToken = count($tokens); $i < $nbToken; $i++) { $regexp .= $this->computeRegexp($tokens, $i, $firstOptional); } return new CompiledRoute( $route, 'text' === $tokens[0][0] ? $tokens[0][1] : '', self::REGEX_DELIMITER.'^'.$regexp.'$'.self::REGEX_DELIMITER.'s', array_reverse($tokens), $variables ); } private function computeRegexp(array $tokens, $index, $firstOptional) { $token = $tokens[$index]; if('text' === $token[0]) { return preg_quote($token[1], self::REGEX_DELIMITER); } else { if (0 === $index && 0 === $firstOptional && 1 == count($tokens)) { return sprintf('%s(?<%s>%s)?', preg_quote($token[1], self::REGEX_DELIMITER), $token[3], $token[2]); } else { $regexp = sprintf('%s(?<%s>%s)', preg_quote($token[1], self::REGEX_DELIMITER), $token[3], $token[2]); if ($index >= $firstOptional) { $regexp = "(?:$regexp"; $nbTokens = count($tokens); if ($nbTokens - 1 == $index) { $regexp .= str_repeat(")?", $nbTokens - $firstOptional); } } return $regexp; } } } } <?php namespace Symfony\Component\Routing; interface RouteCompilerInterface { function compile(Route $route); } <?php namespace Symfony\Component\Routing; use Symfony\Component\Config\Loader\LoaderInterface; use Symfony\Component\Config\ConfigCache; class Router implements RouterInterface { protected $matcher; protected $generator; protected $defaults; protected $context; protected $loader; protected $collection; protected $resource; protected $options; public function __construct(LoaderInterface $loader, $resource, array $options = array(), RequestContext $context = null, array $defaults = array()) { $this->loader = $loader; $this->resource = $resource; $this->context = null === $context ? new RequestContext() : $context; $this->defaults = $defaults; $this->setOptions($options); } public function setOptions(array $options) { $this->options = array( 'cache_dir' => null, 'debug' => false, 'generator_class' => 'Symfony\\Component\\Routing\\Generator\\UrlGenerator', 'generator_base_class' => 'Symfony\\Component\\Routing\\Generator\\UrlGenerator', 'generator_dumper_class' => 'Symfony\\Component\\Routing\\Generator\\Dumper\\PhpGeneratorDumper', 'generator_cache_class' => 'ProjectUrlGenerator', 'matcher_class' => 'Symfony\\Component\\Routing\\Matcher\\UrlMatcher', 'matcher_base_class' => 'Symfony\\Component\\Routing\\Matcher\\UrlMatcher', 'matcher_dumper_class' => 'Symfony\\Component\\Routing\\Matcher\\Dumper\\PhpMatcherDumper', 'matcher_cache_class' => 'ProjectUrlMatcher', 'resource_type' => null, ); $invalid = array(); $isInvalid = false; foreach ($options as $key => $value) { if (array_key_exists($key, $this->options)) { $this->options[$key] = $value; } else { $isInvalid = true; $invalid[] = $key; } } if ($isInvalid) { throw new \InvalidArgumentException(sprintf('The Router does not support the following options: "%s".', implode('\', \'', $invalid))); } } public function setOption($key, $value) { if (!array_key_exists($key, $this->options)) { throw new \InvalidArgumentException(sprintf('The Router does not support the "%s" option.', $key)); } $this->options[$key] = $value; } public function getOption($key) { if (!array_key_exists($key, $this->options)) { throw new \InvalidArgumentException(sprintf('The Router does not support the "%s" option.', $key)); } return $this->options[$key]; } public function getRouteCollection() { if (null === $this->collection) { $this->collection = $this->loader->load($this->resource, $this->options['resource_type']); } return $this->collection; } public function setContext(RequestContext $context) { $this->context = $context; $this->getMatcher()->setContext($context); $this->getGenerator()->setContext($context); } public function getContext() { return $this->context; } public function generate($name, $parameters = array(), $absolute = false) { return $this->getGenerator()->generate($name, $parameters, $absolute); } public function match($pathinfo) { return $this->getMatcher()->match($pathinfo); } public function getMatcher() { if (null !== $this->matcher) { return $this->matcher; } if (null === $this->options['cache_dir'] || null === $this->options['matcher_cache_class']) { return $this->matcher = new $this->options['matcher_class']($this->getRouteCollection(), $this->context, $this->defaults); } $class = $this->options['matcher_cache_class']; $cache = new ConfigCache($this->options['cache_dir'].'/'.$class.'.php', $this->options['debug']); if (!$cache->isFresh($class)) { $dumper = new $this->options['matcher_dumper_class']($this->getRouteCollection()); $options = array( 'class' => $class, 'base_class' => $this->options['matcher_base_class'], ); $cache->write($dumper->dump($options), $this->getRouteCollection()->getResources()); } require_once $cache; return $this->matcher = new $class($this->context, $this->defaults); } public function getGenerator() { if (null !== $this->generator) { return $this->generator; } if (null === $this->options['cache_dir'] || null === $this->options['generator_cache_class']) { return $this->generator = new $this->options['generator_class']($this->getRouteCollection(), $this->context, $this->defaults); } $class = $this->options['generator_cache_class']; $cache = new ConfigCache($this->options['cache_dir'].'/'.$class.'.php', $this->options['debug']); if (!$cache->isFresh($class)) { $dumper = new $this->options['generator_dumper_class']($this->getRouteCollection()); $options = array( 'class' => $class, 'base_class' => $this->options['generator_base_class'], ); $cache->write($dumper->dump($options), $this->getRouteCollection()->getResources()); } require_once $cache; return $this->generator = new $class($this->context, $this->defaults); } } <?php namespace Symfony\Component\Routing; use Symfony\Component\Routing\Generator\UrlGeneratorInterface; use Symfony\Component\Routing\Matcher\UrlMatcherInterface; interface RouterInterface extends UrlMatcherInterface, UrlGeneratorInterface { function getRouteCollection(); } <?php namespace Symfony\Component\BrowserKit; use Symfony\Component\DomCrawler\Crawler; use Symfony\Component\DomCrawler\Link; use Symfony\Component\DomCrawler\Form; use Symfony\Component\Process\PhpProcess; use Symfony\Component\BrowserKit\Request; use Symfony\Component\BrowserKit\Response; use Symfony\Component\BrowserKit\Client; abstract class Client { protected $history; protected $cookieJar; protected $server; protected $request; protected $response; protected $crawler; protected $insulated; protected $redirect; protected $followRedirects; public function __construct(array $server = array(), History $history = null, CookieJar $cookieJar = null) { $this->setServerParameters($server); $this->history = null === $history ? new History() : $history; $this->cookieJar = null === $cookieJar ? new CookieJar() : $cookieJar; $this->insulated = false; $this->followRedirects = true; } public function followRedirects($followRedirect = true) { $this->followRedirects = (Boolean) $followRedirect; } public function insulate($insulated = true) { if (!class_exists('Symfony\\Component\\Process\\Process')) { throw new \RuntimeException('Unable to isolate requests as the Symfony Process Component is not installed.'); } $this->insulated = (Boolean) $insulated; } public function setServerParameters(array $server) { $this->server = array_merge(array( 'HTTP_HOST' => 'localhost', 'HTTP_USER_AGENT' => 'Symfony2 BrowserKit', ), $server); } public function setServerParameter($key, $value) { $this->server[$key] = $value; } public function getServerParameter($key, $default = '') { return (isset($this->server[$key])) ? $this->server[$key] : $default; } public function getHistory() { return $this->history; } public function getCookieJar() { return $this->cookieJar; } public function getCrawler() { return $this->crawler; } public function getResponse() { return $this->response; } public function getRequest() { return $this->request; } public function click(Link $link) { if ($link instanceof Form) { return $this->submit($link); } return $this->request($link->getMethod(), $link->getUri()); } public function submit(Form $form, array $values = array()) { $form->setValues($values); return $this->request($form->getMethod(), $form->getUri(), $form->getPhpValues(), $form->getPhpFiles()); } public function request($method, $uri, array $parameters = array(), array $files = array(), array $server = array(), $content = null, $changeHistory = true) { $uri = $this->getAbsoluteUri($uri); $server = array_merge($this->server, $server); if (!$this->history->isEmpty()) { $server['HTTP_REFERER'] = $this->history->current()->getUri(); } $server['HTTP_HOST'] = parse_url($uri, PHP_URL_HOST); $server['HTTPS'] = 'https' == parse_url($uri, PHP_URL_SCHEME); $request = new Request($uri, $method, $parameters, $files, $this->cookieJar->allValues($uri), $server, $content); $this->request = $this->filterRequest($request); if (true === $changeHistory) { $this->history->add($request); } if ($this->insulated) { $this->response = $this->doRequestInProcess($this->request); } else { $this->response = $this->doRequest($this->request); } $response = $this->filterResponse($this->response); $this->cookieJar->updateFromResponse($response); $this->redirect = $response->getHeader('Location'); if ($this->followRedirects && $this->redirect) { return $this->crawler = $this->followRedirect(); } return $this->crawler = $this->createCrawlerFromContent($request->getUri(), $response->getContent(), $response->getHeader('Content-Type')); } protected function doRequestInProcess($request) { $process = new PhpProcess($this->getScript($request), null, array('TMPDIR' => sys_get_temp_dir(), 'TEMP' => sys_get_temp_dir())); $process->run(); if (!$process->isSuccessful() || !preg_match('/^O\:\d+\:/', $process->getOutput())) { throw new \RuntimeException('OUTPUT: '.$process->getOutput().' ERROR OUTPUT: '.$process->getErrorOutput()); } return unserialize($process->getOutput()); } abstract protected function doRequest($request); protected function getScript($request) { throw new \LogicException('To insulate requests, you need to override the getScript() method.'); } protected function filterRequest(Request $request) { return $request; } protected function filterResponse($response) { return $response; } protected function createCrawlerFromContent($uri, $content, $type) { if (!class_exists('Symfony\Component\DomCrawler\Crawler')) { return null; } $crawler = new Crawler(null, $uri); $crawler->addContent($content, $type); return $crawler; } public function back() { return $this->requestFromRequest($this->history->back(), false); } public function forward() { return $this->requestFromRequest($this->history->forward(), false); } public function reload() { return $this->requestFromRequest($this->history->current(), false); } public function followRedirect() { if (empty($this->redirect)) { throw new \LogicException('The request was not redirected.'); } return $this->request('get', $this->redirect); } public function restart() { $this->cookieJar->clear(); $this->history->clear(); } protected function getAbsoluteUri($uri) { if (0 === strpos($uri, 'http')) { return $uri; } if (!$this->history->isEmpty()) { $currentUri = $this->history->current()->getUri(); } else { $currentUri = sprintf('http%s://%s/', isset($this->server['HTTPS']) ? 's' : '', isset($this->server['HTTP_HOST']) ? $this->server['HTTP_HOST'] : 'localhost' ); } if (!$uri || '#' == $uri[0]) { return preg_replace('/#.*?$/', '', $currentUri).$uri; } if ('/' !== $uri[0]) { $path = parse_url($currentUri, PHP_URL_PATH); if ('/' !== substr($path, -1)) { $path = substr($path, 0, strrpos($path, '/') + 1); } $uri = $path.$uri; } return preg_replace('#^(.*?//[^/]+)\/.*$#', '$1', $currentUri).$uri; } protected function requestFromRequest(Request $request, $changeHistory = true) { return $this->request($request->getMethod(), $request->getUri(), $request->getParameters(), $request->getFiles(), $request->getServer(), $request->getContent(), $changeHistory); } } <?php namespace Symfony\Component\BrowserKit; class Cookie { private static $dateFormats = array( 'D, d M Y H:i:s T', 'D, d-M-y H:i:s T', 'D, d-M-Y H:i:s T', 'D M j G:i:s Y', ); protected $name; protected $value; protected $expires; protected $path; protected $domain; protected $secure; protected $httponly; protected $rawValue; public function __construct($name, $value, $expires = null, $path = null, $domain = '', $secure = false, $httponly = true, $encodedValue = false) { if ($encodedValue) { $this->value = urldecode($value); $this->rawValue = $value; } else { $this->value = $value; $this->rawValue = urlencode($value); } $this->name = $name; $this->expires = null === $expires ? null : (integer) $expires; $this->path = empty($path) ? '/' : $path; $this->domain = $domain; $this->secure = (Boolean) $secure; $this->httponly = (Boolean) $httponly; } public function __toString() { $cookie = sprintf('%s=%s', $this->name, $this->rawValue); if (null !== $this->expires) { $cookie .= '; expires='.substr(\DateTime::createFromFormat('U', $this->expires, new \DateTimeZone('GMT'))->format(self::$dateFormats[0]), 0, -5); } if ('' !== $this->domain) { $cookie .= '; domain='.$this->domain; } if ('/' !== $this->path) { $cookie .= '; path='.$this->path; } if ($this->secure) { $cookie .= '; secure'; } if ($this->httponly) { $cookie .= '; httponly'; } return $cookie; } static public function fromString($cookie, $url = null) { $parts = explode(';', $cookie); if (false === strpos($parts[0], '=')) { throw new \InvalidArgumentException('The cookie string "%s" is not valid.'); } list($name, $value) = explode('=', array_shift($parts), 2); $values = array( 'name' => trim($name), 'value' => trim($value), 'expires' => null, 'path' => '/', 'domain' => '', 'secure' => false, 'httponly' => false, 'passedRawValue' => true, ); if (null !== $url) { if ((false === $urlParts = parse_url($url)) || !isset($urlParts['host']) || !isset($urlParts['path'])) { throw new \InvalidArgumentException(sprintf('The URL "%s" is not valid.', $url)); } $parts = array_merge($urlParts, $parts); $values['domain'] = $parts['host']; $values['path'] = substr($parts['path'], 0, strrpos($parts['path'], '/')); } foreach ($parts as $part) { $part = trim($part); if ('secure' === strtolower($part)) { if (!$url || !isset($urlParts['scheme']) || 'https' != $urlParts['scheme']) { continue; } $values['secure'] = true; continue; } if ('httponly' === strtolower($part)) { $values['httponly'] = true; continue; } if (2 === count($elements = explode('=', $part, 2))) { if ('expires' === strtolower($elements[0])) { $elements[1] = self::parseDate($elements[1]); } $values[strtolower($elements[0])] = $elements[1]; } } return new static( $values['name'], $values['value'], $values['expires'], $values['path'], $values['domain'], $values['secure'], $values['httponly'], $values['passedRawValue'] ); } private static function parseDate($dateValue) { if (($length = strlen($dateValue)) > 1 && "'" === $dateValue[0] && "'" === $dateValue[$length-1]) { $dateValue = substr($dateValue, 1, -1); } foreach (self::$dateFormats as $dateFormat) { if (false !== $date = \DateTime::createFromFormat($dateFormat, $dateValue, new \DateTimeZone('GMT'))) { return $date->getTimestamp(); } } throw new \InvalidArgumentException(sprintf('Could not parse date "%s".', $dateValue)); } public function getName() { return $this->name; } public function getValue() { return $this->value; } public function getRawValue() { return $this->rawValue; } public function getExpiresTime() { return $this->expires; } public function getPath() { return $this->path; } public function getDomain() { return $this->domain; } public function isSecure() { return $this->secure; } public function isHttpOnly() { return $this->httponly; } public function isExpired() { return null !== $this->expires && 0 !== $this->expires && $this->expires < time(); } } <?php namespace Symfony\Component\BrowserKit; class CookieJar { protected $cookieJar = array(); public function set(Cookie $cookie) { $this->cookieJar[$cookie->getDomain()][$cookie->getPath()][$cookie->getName()] = $cookie; } public function get($name, $path = '/', $domain = null) { $this->flushExpiredCookies(); return isset($this->cookieJar[$domain][$path][$name]) ? $this->cookieJar[$domain][$path][$name] : null; } public function expire($name, $path = '/', $domain = null) { if (null === $path) { $path = '/'; } unset($this->cookieJar[$domain][$path][$name]); if (empty($this->cookieJar[$domain][$path])) { unset($this->cookieJar[$domain][$path]); if (empty($this->cookieJar[$domain])) { unset($this->cookieJar[$domain]); } } } public function clear() { $this->cookieJar = array(); } public function updateFromResponse(Response $response, $uri = null) { $cookies = array(); foreach ($response->getHeader('Set-Cookie', false) as $cookie) { foreach (explode(',', $cookie) as $i => $part) { if (0 === $i || preg_match('/^(?P<token>\s*[0-9A-Za-z!#\$%\&\'\*\+\-\.^_`\|~]+)=/', $part)) { $cookies[] = ltrim($part); } else { $cookies[count($cookies) - 1] .= ','.$part; } } } foreach ($cookies as $cookie) { $this->set(Cookie::fromString($cookie, $uri)); } } public function all() { $this->flushExpiredCookies(); $flattenedCookies = array(); foreach ($this->cookieJar as $path) { foreach ($path as $cookies) { foreach ($cookies as $cookie) { $flattenedCookies[] = $cookie; } } } return $flattenedCookies; } public function allValues($uri, $returnsRawValue = false) { $this->flushExpiredCookies(); $parts = array_replace(array('path' => '/'), parse_url($uri)); $cookies = array(); foreach ($this->cookieJar as $domain => $pathCookies) { if ($domain) { $domain = ltrim($domain, '.'); if ($domain != substr($parts['host'], -strlen($domain))) { continue; } } foreach ($pathCookies as $path => $namedCookies) { if ($path != substr($parts['path'], 0, strlen($path))) { continue; } foreach ($namedCookies as $cookie) { if ($cookie->isSecure() && 'https' != $parts['scheme']) { continue; } $cookies[$cookie->getName()] = $returnsRawValue ? $cookie->getRawValue() : $cookie->getValue(); } } } return $cookies; } public function allRawValues($uri) { return $this->allValues($uri, true); } public function flushExpiredCookies() { foreach ($this->cookieJar as $domain => $pathCookies) { foreach ($pathCookies as $path => $namedCookies) { foreach ($namedCookies as $name => $cookie) { if ($cookie->isExpired()) { unset($this->cookieJar[$domain][$path][$name]); } } } } } } <?php namespace Symfony\Component\BrowserKit; class History { protected $stack = array(); protected $position = -1; public function __construct() { $this->clear(); } public function clear() { $this->stack = array(); $this->position = -1; } public function add(Request $request) { $this->stack = array_slice($this->stack, 0, $this->position + 1); $this->stack[] = clone $request; $this->position = count($this->stack) - 1; } public function isEmpty() { return count($this->stack) == 0; } public function back() { if ($this->position < 1) { throw new \LogicException('You are already on the first page.'); } return clone $this->stack[--$this->position]; } public function forward() { if ($this->position > count($this->stack) - 2) { throw new \LogicException('You are already on the last page.'); } return clone $this->stack[++$this->position]; } public function current() { if (-1 == $this->position) { throw new \LogicException('The page history is empty.'); } return clone $this->stack[$this->position]; } } <?php namespace Symfony\Component\BrowserKit; class Request { protected $uri; protected $method; protected $parameters; protected $files; protected $cookies; protected $server; protected $content; public function __construct($uri, $method, array $parameters = array(), array $files = array(), array $cookies = array(), array $server = array(), $content = null) { $this->uri = $uri; $this->method = $method; $this->parameters = $parameters; $this->files = $files; $this->cookies = $cookies; $this->server = $server; $this->content = $content; } public function getUri() { return $this->uri; } public function getMethod() { return $this->method; } public function getParameters() { return $this->parameters; } public function getFiles() { return $this->files; } public function getCookies() { return $this->cookies; } public function getServer() { return $this->server; } public function getContent() { return $this->content; } } <?php namespace Symfony\Component\BrowserKit; class Response { protected $content; protected $status; protected $headers; public function __construct($content = '', $status = 200, array $headers = array()) { $this->content = $content; $this->status = $status; $this->headers = $headers; } public function __toString() { $headers = ''; foreach ($this->headers as $name => $value) { if (is_string($value)) { $headers .= $this->buildHeader($name, $value); } else { foreach ($value as $headerValue) { $headers .= $this->buildHeader($name, $headerValue); } } } return $headers."\n".$this->content; } protected function buildHeader($name, $value) { return sprintf("%s: %s\n", $name, $value); } public function getContent() { return $this->content; } public function getStatus() { return $this->status; } public function getHeaders() { return $this->headers; } public function getHeader($header, $first = true) { foreach ($this->headers as $key => $value) { if (str_replace('-', '_', strtolower($key)) == str_replace('-', '_', strtolower($header))) { if ($first) { return is_array($value) ? (count($value) ? $value[0] : '') : $value; } return is_array($value) ? $value : array($value); } } return $first ? null : array(); } } <?php namespace Symfony\Component\CssSelector; use Symfony\Component\CssSelector\Exception\ParseException; class CssSelector { static public function toXPath($cssExpr, $prefix = 'descendant-or-self::') { if (is_string($cssExpr)) { if (!$cssExpr) { return $prefix.'*'; } if (preg_match('#^\w+\s*$#u', $cssExpr, $match)) { return $prefix.trim($match[0]); } if (preg_match('~^(\w*)#(\w+)\s*$~u', $cssExpr, $match)) { return sprintf("%s%s[@id = '%s']", $prefix, $match[1] ? $match[1] : '*', $match[2]); } if (preg_match('#^(\w*)\.(\w+)\s*$#u', $cssExpr, $match)) { return sprintf("%s%s[contains(concat(' ', normalize-space(@class), ' '), ' %s ')]", $prefix, $match[1] ? $match[1] : '*', $match[2]); } $parser = new self(); $cssExpr = $parser->parse($cssExpr); } $expr = $cssExpr->toXpath(); if (!$expr) { throw new ParseException(sprintf('Got None for xpath expression from %s.', $cssExpr)); } if ($prefix) { $expr->addPrefix($prefix); } return (string) $expr; } public function parse($string) { $tokenizer = new Tokenizer(); $stream = new TokenStream($tokenizer->tokenize($string), $string); try { return $this->parseSelectorGroup($stream); } catch (\Exception $e) { $class = get_class($e); throw new $class(sprintf('%s at %s -> %s', $e->getMessage(), implode($stream->getUsed(), ''), $stream->peek()), 0, $e); } } private function parseSelectorGroup($stream) { $result = array(); while (true) { $result[] = $this->parseSelector($stream); if ($stream->peek() == ',') { $stream->next(); } else { break; } } if (count($result) == 1) { return $result[0]; } return new Node\OrNode($result); } private function parseSelector($stream) { $result = $this->parseSimpleSelector($stream); while (true) { $peek = $stream->peek(); if (',' == $peek || null === $peek) { return $result; } elseif (in_array($peek, array('+', '>', '~'))) { $combinator = (string) $stream->next(); } else { $combinator = ' '; } $consumed = count($stream->getUsed()); $nextSelector = $this->parseSimpleSelector($stream); if ($consumed == count($stream->getUsed())) { throw new ParseException(sprintf("Expected selector, got '%s'", $stream->peek())); } $result = new Node\CombinedSelectorNode($result, $combinator, $nextSelector); } return $result; } private function parseSimpleSelector($stream) { $peek = $stream->peek(); if ('*' != $peek && !$peek->isType('Symbol')) { $element = $namespace = '*'; } else { $next = $stream->next(); if ('*' != $next && !$next->isType('Symbol')) { throw new ParseException(sprintf("Expected symbol, got '%s'", $next)); } if ($stream->peek() == '|') { $namespace = $next; $stream->next(); $element = $stream->next(); if ('*' != $element && !$next->isType('Symbol')) { throw new ParseException(sprintf("Expected symbol, got '%s'", $next)); } } else { $namespace = '*'; $element = $next; } } $result = new Node\ElementNode($namespace, $element); $hasHash = false; while (true) { $peek = $stream->peek(); if ('#' == $peek) { if ($hasHash) { break; } $stream->next(); $result = new Node\HashNode($result, $stream->next()); $hasHash = true; continue; } elseif ('.' == $peek) { $stream->next(); $result = new Node\ClassNode($result, $stream->next()); continue; } elseif ('[' == $peek) { $stream->next(); $result = $this->parseAttrib($result, $stream); $next = $stream->next(); if (']' != $next) { throw new ParseException(sprintf("] expected, got '%s'", $next)); } continue; } elseif (':' == $peek || '::' == $peek) { $type = $stream->next(); $ident = $stream->next(); if (!$ident || !$ident->isType('Symbol')) { throw new ParseException(sprintf("Expected symbol, got '%s'", $ident)); } if ($stream->peek() == '(') { $stream->next(); $peek = $stream->peek(); if ($peek->isType('String')) { $selector = $stream->next(); } elseif ($peek->isType('Symbol') && is_int($peek)) { $selector = intval($stream->next()); } else { $selector = $this->parseSimpleSelector($stream); } $next = $stream->next(); if (')' != $next) { throw new ParseException(sprintf("Expected ')', got '%s' and '%s'", $next, $selector)); } $result = new Node\FunctionNode($result, $type, $ident, $selector); } else { $result = new Node\PseudoNode($result, $type, $ident); } continue; } else { if (' ' == $peek) { $stream->next(); } break; } } return $result; } private function parseAttrib($selector, $stream) { $attrib = $stream->next(); if ($stream->peek() == '|') { $namespace = $attrib; $stream->next(); $attrib = $stream->next(); } else { $namespace = '*'; } if ($stream->peek() == ']') { return new Node\AttribNode($selector, $namespace, $attrib, 'exists', null); } $op = $stream->next(); if (!in_array($op, array('^=', '$=', '*=', '=', '~=', '|=', '!='))) { throw new ParseException(sprintf("Operator expected, got '%s'", $op)); } $value = $stream->next(); if (!$value->isType('Symbol') && !$value->isType('String')) { throw new ParseException(sprintf("Expected string or symbol, got '%s'", $value)); } return new Node\AttribNode($selector, $namespace, $attrib, $op, $value); } } <?php namespace Symfony\Component\CssSelector\Exception; class ParseException extends \Exception { } <?php namespace Symfony\Component\CssSelector\Node; use Symfony\Component\CssSelector\XPathExpr; use Symfony\Component\CssSelector\Exception\ParseException; class AttribNode implements NodeInterface { protected $selector; protected $namespace; protected $attrib; protected $operator; protected $value; public function __construct($selector, $namespace, $attrib, $operator, $value) { $this->selector = $selector; $this->namespace = $namespace; $this->attrib = $attrib; $this->operator = $operator; $this->value = $value; } public function __toString() { if ($this->operator == 'exists') { return sprintf('%s[%s[%s]]', __CLASS__, $this->selector, $this->formatAttrib()); } return sprintf('%s[%s[%s %s %s]]', __CLASS__, $this->selector, $this->formatAttrib(), $this->operator, $this->value); } public function toXpath() { $path = $this->selector->toXpath(); $attrib = $this->xpathAttrib(); $value = $this->value; if ($this->operator == 'exists') { $path->addCondition($attrib); } elseif ($this->operator == '=') { $path->addCondition(sprintf('%s = %s', $attrib, XPathExpr::xpathLiteral($value))); } elseif ($this->operator == '!=') { if ($value) { $path->addCondition(sprintf('not(%s) or %s != %s', $attrib, $attrib, XPathExpr::xpathLiteral($value))); } else { $path->addCondition(sprintf('%s != %s', $attrib, XPathExpr::xpathLiteral($value))); } } elseif ($this->operator == '~=') { $path->addCondition(sprintf("contains(concat(' ', normalize-space(%s), ' '), %s)", $attrib, XPathExpr::xpathLiteral(' '.$value.' '))); } elseif ($this->operator == '|=') { $path->addCondition(sprintf('%s = %s or starts-with(%s, %s)', $attrib, XPathExpr::xpathLiteral($value), $attrib, XPathExpr::xpathLiteral($value.'-'))); } elseif ($this->operator == '^=') { $path->addCondition(sprintf('starts-with(%s, %s)', $attrib, XPathExpr::xpathLiteral($value))); } elseif ($this->operator == '$=') { $path->addCondition(sprintf('substring(%s, string-length(%s)-%s) = %s', $attrib, $attrib, strlen($value) - 1, XPathExpr::xpathLiteral($value))); } elseif ($this->operator == '*=') { $path->addCondition(sprintf('contains(%s, %s)', $attrib, XPathExpr::xpathLiteral($value))); } else { throw new ParseException(sprintf('Unknown operator: %s', $this->operator)); } return $path; } protected function xpathAttrib() { if ($this->namespace == '*') { return '@'.$this->attrib; } return sprintf('@%s:%s', $this->namespace, $this->attrib); } protected function formatAttrib() { if ($this->namespace == '*') { return $this->attrib; } return sprintf('%s|%s', $this->namespace, $this->attrib); } } <?php namespace Symfony\Component\CssSelector\Node; use Symfony\Component\CssSelector\XPathExpr; class ClassNode implements NodeInterface { protected $selector; protected $className; public function __construct($selector, $className) { $this->selector = $selector; $this->className = $className; } public function __toString() { return sprintf('%s[%s.%s]', __CLASS__, $this->selector, $this->className); } public function toXpath() { $selXpath = $this->selector->toXpath(); $selXpath->addCondition(sprintf("contains(concat(' ', normalize-space(@class), ' '), %s)", XPathExpr::xpathLiteral(' '.$this->className.' '))); return $selXpath; } } <?php namespace Symfony\Component\CssSelector\Node; use Symfony\Component\CssSelector\Exception\ParseException; class CombinedSelectorNode implements NodeInterface { static protected $methodMapping = array( ' ' => 'descendant', '>' => 'child', '+' => 'direct_adjacent', '~' => 'indirect_adjacent', ); protected $selector; protected $combinator; protected $subselector; public function __construct($selector, $combinator, $subselector) { $this->selector = $selector; $this->combinator = $combinator; $this->subselector = $subselector; } public function __toString() { $comb = $this->combinator == ' ' ? '<followed>' : $this->combinator; return sprintf('%s[%s %s %s]', __CLASS__, $this->selector, $comb, $this->subselector); } public function toXpath() { if (!isset(self::$methodMapping[$this->combinator])) { throw new ParseException(sprintf('Unknown combinator: %s', $this->combinator)); } $method = '_xpath_'.self::$methodMapping[$this->combinator]; $path = $this->selector->toXpath(); return $this->$method($path, $this->subselector); } protected function _xpath_descendant($xpath, $sub) { $xpath->join('/descendant::', $sub->toXpath()); return $xpath; } protected function _xpath_child($xpath, $sub) { $xpath->join('/', $sub->toXpath()); return $xpath; } protected function _xpath_direct_adjacent($xpath, $sub) { $xpath->join('/following-sibling::', $sub->toXpath()); $xpath->addNameTest(); $xpath->addCondition('position() = 1'); return $xpath; } protected function _xpath_indirect_adjacent($xpath, $sub) { $xpath->join('/following-sibling::', $sub->toXpath()); return $xpath; } } <?php namespace Symfony\Component\CssSelector\Node; use Symfony\Component\CssSelector\XPathExpr; class ElementNode implements NodeInterface { protected $namespace; protected $element; public function __construct($namespace, $element) { $this->namespace = $namespace; $this->element = $element; } public function __toString() { return sprintf('%s[%s]', __CLASS__, $this->formatElement()); } public function formatElement() { if ($this->namespace == '*') { return $this->element; } return sprintf('%s|%s', $this->namespace, $this->element); } public function toXpath() { if ($this->namespace == '*') { $el = strtolower($this->element); } else { $el = sprintf('%s:%s', $this->namespace, $this->element); } return new XPathExpr(null, null, $el); } } <?php namespace Symfony\Component\CssSelector\Node; use Symfony\Component\CssSelector\Exception\ParseException; use Symfony\Component\CssSelector\XPathExpr; class FunctionNode implements NodeInterface { static protected $unsupported = array('target', 'lang', 'enabled', 'disabled'); protected $selector; protected $type; protected $name; protected $expr; public function __construct($selector, $type, $name, $expr) { $this->selector = $selector; $this->type = $type; $this->name = $name; $this->expr = $expr; } public function __toString() { return sprintf('%s[%s%s%s(%s)]', __CLASS__, $this->selector, $this->type, $this->name, $this->expr); } public function toXpath() { $selPath = $this->selector->toXpath(); if (in_array($this->name, self::$unsupported)) { throw new ParseException(sprintf('The pseudo-class %s is not supported', $this->name)); } $method = '_xpath_'.str_replace('-', '_', $this->name); if (!method_exists($this, $method)) { throw new ParseException(sprintf('The pseudo-class %s is unknown', $this->name)); } return $this->$method($selPath, $this->expr); } protected function _xpath_nth_child($xpath, $expr, $last = false, $addNameTest = true) { list($a, $b) = $this->parseSeries($expr); if (!$a && !$b && !$last) { $xpath->addCondition('false() and position() = 0'); return $xpath; } if ($addNameTest) { $xpath->addNameTest(); } $xpath->addStarPrefix(); if ($a == 0) { if ($last) { $b = sprintf('last() - %s', $b); } $xpath->addCondition(sprintf('position() = %s', $b)); return $xpath; } if ($last) { $a = -$a; $b = -$b; } if ($b > 0) { $bNeg = -$b; } else { $bNeg = sprintf('+%s', -$b); } if ($a != 1) { $expr = array(sprintf('(position() %s) mod %s = 0', $bNeg, $a)); } else { $expr = array(); } if ($b >= 0) { $expr[] = sprintf('position() >= %s', $b); } elseif ($b < 0 && $last) { $expr[] = sprintf('position() < (last() %s)', $b); } $expr = implode($expr, ' and '); if ($expr) { $xpath->addCondition($expr); } return $xpath; } protected function _xpath_nth_last_child($xpath, $expr) { return $this->_xpath_nth_child($xpath, $expr, true); } protected function _xpath_nth_of_type($xpath, $expr) { if ($xpath->getElement() == '*') { throw new ParseException('*:nth-of-type() is not implemented'); } return $this->_xpath_nth_child($xpath, $expr, false, false); } protected function _xpath_nth_last_of_type($xpath, $expr) { return $this->_xpath_nth_child($xpath, $expr, true, false); } protected function _xpath_contains($xpath, $expr) { if ($expr instanceof ElementNode) { $expr = $expr->formatElement(); } $xpath->addCondition(sprintf('contains(string(.), %s)', XPathExpr::xpathLiteral($expr))); return $xpath; } protected function _xpath_not($xpath, $expr) { $expr = $expr->toXpath(); $cond = $expr->getCondition(); $xpath->addCondition(sprintf('not(%s)', $cond)); return $xpath; } protected function parseSeries($s) { if ($s instanceof ElementNode) { $s = $s->formatElement(); } if (!$s || '*' == $s) { return array(0, 0); } if (is_string($s)) { return array(0, $s); } if ('odd' == $s) { return array(2, 1); } if ('even' == $s) { return array(2, 0); } if ('n' == $s) { return array(1, 0); } if (false === strpos($s, 'n')) { return array(0, intval((string) $s)); } list($a, $b) = explode('n', $s); if (!$a) { $a = 1; } elseif ('-' == $a || '+' == $a) { $a = intval($a.'1'); } else { $a = intval($a); } if (!$b) { $b = 0; } elseif ('-' == $b || '+' == $b) { $b = intval($b.'1'); } else { $b = intval($b); } return array($a, $b); } } <?php namespace Symfony\Component\CssSelector\Node; use Symfony\Component\CssSelector\XPathExpr; class HashNode implements NodeInterface { protected $selector; protected $id; public function __construct($selector, $id) { $this->selector = $selector; $this->id = $id; } public function __toString() { return sprintf('%s[%s#%s]', __CLASS__, $this->selector, $this->id); } public function toXpath() { $path = $this->selector->toXpath(); $path->addCondition(sprintf('@id = %s', XPathExpr::xpathLiteral($this->id))); return $path; } } <?php namespace Symfony\Component\CssSelector\Node; interface NodeInterface { function __toString(); function toXpath(); } <?php namespace Symfony\Component\CssSelector\Node; use Symfony\Component\CssSelector\XPathExprOr; class OrNode implements NodeInterface { protected $items; public function __construct($items) { $this->items = $items; } public function __toString() { return sprintf('%s(%s)', __CLASS__, $this->items); } public function toXpath() { $paths = array(); foreach ($this->items as $item) { $paths[] = $item->toXpath(); } return new XPathExprOr($paths); } } <?php namespace Symfony\Component\CssSelector\Node; use Symfony\Component\CssSelector\Exception\ParseException; class PseudoNode implements NodeInterface { static protected $unsupported = array( 'indeterminate', 'first-line', 'first-letter', 'selection', 'before', 'after', 'link', 'visited', 'active', 'focus', 'hover', ); protected $element; protected $type; protected $ident; public function __construct($element, $type, $ident) { $this->element = $element; if (!in_array($type, array(':', '::'))) { throw new ParseException(sprintf('The PseudoNode type can only be : or :: (%s given).', $type)); } $this->type = $type; $this->ident = $ident; } public function __toString() { return sprintf('%s[%s%s%s]', __CLASS__, $this->element, $this->type, $this->ident); } public function toXpath() { $elXpath = $this->element->toXpath(); if (in_array($this->ident, self::$unsupported)) { throw new ParseException(sprintf('The pseudo-class %s is unsupported', $this->ident)); } $method = 'xpath_'.str_replace('-', '_', $this->ident); if (!method_exists($this, $method)) { throw new ParseException(sprintf('The pseudo-class %s is unknown', $this->ident)); } return $this->$method($elXpath); } protected function xpath_checked($xpath) { $xpath->addCondition("(@selected or @checked) and (name(.) = 'input' or name(.) = 'option')"); return $xpath; } protected function xpath_root($xpath) { throw new ParseException(); } protected function xpath_first_child($xpath) { $xpath->addStarPrefix(); $xpath->addNameTest(); $xpath->addCondition('position() = 1'); return $xpath; } protected function xpath_last_child($xpath) { $xpath->addStarPrefix(); $xpath->addNameTest(); $xpath->addCondition('position() = last()'); return $xpath; } protected function xpath_first_of_type($xpath) { if ($xpath->getElement() == '*') { throw new ParseException('*:first-of-type is not implemented'); } $xpath->addStarPrefix(); $xpath->addCondition('position() = 1'); return $xpath; } protected function xpath_last_of_type($xpath) { if ($xpath->getElement() == '*') { throw new ParseException('*:last-of-type is not implemented'); } $xpath->addStarPrefix(); $xpath->addCondition('position() = last()'); return $xpath; } protected function xpath_only_child($xpath) { $xpath->addNameTest(); $xpath->addStarPrefix(); $xpath->addCondition('last() = 1'); return $xpath; } protected function xpath_only_of_type($xpath) { if ($xpath->getElement() == '*') { throw new ParseException('*:only-of-type is not implemented'); } $xpath->addCondition('last() = 1'); return $xpath; } protected function xpath_empty($xpath) { $xpath->addCondition('not(*) and not(normalize-space())'); return $xpath; } } <?php namespace Symfony\Component\CssSelector; class Token { private $type; private $value; private $position; public function __construct($type, $value, $position) { $this->type = $type; $this->value = $value; $this->position = $position; } public function __toString() { return (string) $this->value; } public function isType($type) { return $this->type == $type; } public function getPosition() { return $this->position; } } <?php namespace Symfony\Component\CssSelector; use Symfony\Component\CssSelector\Exception\ParseException; class Tokenizer { public function tokenize($s) { if (function_exists('mb_internal_encoding') && ((int) ini_get('mbstring.func_overload')) & 2) { $mbEncoding = mb_internal_encoding(); mb_internal_encoding('ASCII'); } $tokens = array(); $pos = 0; $s = preg_replace('#/\*.*?\*/#s', '', $s); while (true) { if (preg_match('#\s+#A', $s, $match, 0, $pos)) { $precedingWhitespacePos = $pos; $pos += strlen($match[0]); } else { $precedingWhitespacePos = 0; } if ($pos >= strlen($s)) { if (isset($mbEncoding)) { mb_internal_encoding($mbEncoding); } return $tokens; } if (preg_match('#[+-]?\d*n(?:[+-]\d+)?#A', $s, $match, 0, $pos) && 'n' !== $match[0]) { $sym = substr($s, $pos, strlen($match[0])); $tokens[] = new Token('Symbol', $sym, $pos); $pos += strlen($match[0]); continue; } $c = $s[$pos]; $c2 = substr($s, $pos, 2); if (in_array($c2, array('~=', '|=', '^=', '$=', '*=', '::', '!='))) { $tokens[] = new Token('Token', $c2, $pos); $pos += 2; continue; } if (in_array($c, array('>', '+', '~', ',', '.', '*', '=', '[', ']', '(', ')', '|', ':', '#'))) { if (in_array($c, array('.', '#', '[')) && $precedingWhitespacePos > 0) { $tokens[] = new Token('Token', ' ', $precedingWhitespacePos); } $tokens[] = new Token('Token', $c, $pos); ++$pos; continue; } if ('"' === $c || "'" === $c) { $oldPos = $pos; list($sym, $pos) = $this->tokenizeEscapedString($s, $pos); $tokens[] = new Token('String', $sym, $oldPos); continue; } $oldPos = $pos; list($sym, $pos) = $this->tokenizeSymbol($s, $pos); $tokens[] = new Token('Symbol', $sym, $oldPos); continue; } } private function tokenizeEscapedString($s, $pos) { $quote = $s[$pos]; $pos = $pos + 1; $start = $pos; while (true) { $next = strpos($s, $quote, $pos); if (false === $next) { throw new ParseException(sprintf('Expected closing %s for string in: %s', $quote, substr($s, $start))); } $result = substr($s, $start, $next - $start); if ('\\' === $result[strlen($result) - 1]) { $pos = $next + 1; continue; } if (false !== strpos($result, '\\')) { $result = $this->unescapeStringLiteral($result); } return array($result, $next + 1); } } private function unescapeStringLiteral($literal) { return preg_replace_callback('#(\\\\(?:[A-Fa-f0-9]{1,6}(?:\r\n|\s)?|[^A-Fa-f0-9]))#', function ($matches) use ($literal) { if ($matches[0][0] == '\\' && strlen($matches[0]) > 1) { $matches[0] = substr($matches[0], 1); if (in_array($matches[0][0], array('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'a', 'b', 'c', 'd', 'e', 'f'))) { return chr(trim($matches[0])); } } else { throw new ParseException(sprintf('Invalid escape sequence %s in string %s', $matches[0], $literal)); } }, $literal); } private function tokenizeSymbol($s, $pos) { $start = $pos; if (!preg_match('#[^\w\-]#', $s, $match, PREG_OFFSET_CAPTURE, $pos)) { return array(substr($s, $start), strlen($s)); } $matchStart = $match[0][1]; if ($matchStart == $pos) { throw new ParseException(sprintf('Unexpected symbol: %s at %s', $s[$pos], $pos)); } $result = substr($s, $start, $matchStart - $start); $pos = $matchStart; return array($result, $pos); } } <?php namespace Symfony\Component\CssSelector; class TokenStream { private $used; private $tokens; private $source; private $peeked; private $peeking; public function __construct($tokens, $source = null) { $this->used = array(); $this->tokens = $tokens; $this->source = $source; $this->peeked = null; $this->peeking = false; } public function getUsed() { return $this->used; } public function next() { if ($this->peeking) { $this->peeking = false; $this->used[] = $this->peeked; return $this->peeked; } if (!count($this->tokens)) { return null; } $next = array_shift($this->tokens); $this->used[] = $next; return $next; } public function peek() { if (!$this->peeking) { if (!count($this->tokens)) { return null; } $this->peeked = array_shift($this->tokens); $this->peeking = true; } return $this->peeked; } } <?php namespace Symfony\Component\CssSelector; class XPathExpr { private $prefix; private $path; private $element; private $condition; private $starPrefix; public function __construct($prefix = null, $path = null, $element = '*', $condition = null, $starPrefix = false) { $this->prefix = $prefix; $this->path = $path; $this->element = $element; $this->condition = $condition; $this->starPrefix = $starPrefix; } public function getPrefix() { return $this->prefix; } public function getPath() { return $this->path; } public function hasStarPrefix() { return $this->starPrefix; } public function getElement() { return $this->element; } public function getCondition() { return $this->condition; } public function __toString() { $path = ''; if (null !== $this->prefix) { $path .= $this->prefix; } if (null !== $this->path) { $path .= $this->path; } $path .= $this->element; if ($this->condition) { $path .= sprintf('[%s]', $this->condition); } return $path; } public function addCondition($condition) { if ($this->condition) { $this->condition = sprintf('%s and (%s)', $this->condition, $condition); } else { $this->condition = $condition; } } public function addPrefix($prefix) { if ($this->prefix) { $this->prefix = $prefix.$this->prefix; } else { $this->prefix = $prefix; } } public function addNameTest() { if ($this->element == '*') { return; } $this->addCondition(sprintf('name() = %s', XPathExpr::xpathLiteral($this->element))); $this->element = '*'; } public function addStarPrefix() { if ($this->path) { $this->path .= '*/'; } else { $this->path = '*/'; } $this->starPrefix = true; } public function join($combiner, $other) { $prefix = (string) $this; $prefix .= $combiner; $path = $other->getPrefix().$other->getPath(); if ($other->hasStarPrefix() && '*/' == $path) { $path = ''; } $this->prefix = $prefix; $this->path = $path; $this->element = $other->getElement(); $this->condition = $other->GetCondition(); } static public function xpathLiteral($s) { if ($s instanceof Node\ElementNode) { $s = $s->formatElement(); } else { $s = (string) $s; } if (false === strpos($s, "'")) { return sprintf("'%s'", $s); } if (false === strpos($s, '"')) { return sprintf('"%s"', $s); } $string = $s; $parts = array(); while (true) { if (false !== $pos = strpos($string, "'")) { $parts[] = sprintf("'%s'", substr($string, 0, $pos)); $parts[] = "\"'\""; $string = substr($string, $pos + 1); } else { $parts[] = "'$string'"; break; } } return sprintf('concat(%s)', implode($parts, ', ')); } } <?php namespace Symfony\Component\CssSelector; class XPathExprOr extends XPathExpr { public function __construct($items, $prefix = null) { $this->items = $items; $this->prefix = $prefix; } public function __toString() { $prefix = $this->getPrefix(); $tmp = array(); foreach ($this->items as $i) { $tmp[] = sprintf('%s%s', $prefix, $i); } return implode($tmp, ' | '); } } <?php namespace Symfony\Component\DomCrawler; use Symfony\Component\CssSelector\CssSelector; class Crawler extends \SplObjectStorage { private $uri; public function __construct($node = null, $uri = null) { $this->uri = $uri; $this->add($node); } public function clear() { $this->removeAll($this); } public function add($node) { if ($node instanceof \DOMNodeList) { $this->addNodeList($node); } elseif (is_array($node)) { $this->addNodes($node); } elseif (is_string($node)) { $this->addContent($node); } elseif (is_object($node)) { $this->addNode($node); } } public function addContent($content, $type = null) { if (empty($type)) { $type = 'text/html'; } if (!preg_match('/(x|ht)ml/i', $type, $matches)) { return null; } $charset = 'ISO-8859-1'; if (false !== $pos = strpos($type, 'charset=')) { $charset = substr($type, $pos + 8); if (false !== $pos = strpos($charset, ';')) { $charset = substr($charset, 0, $pos); } } if ('x' === $matches[1]) { $this->addXmlContent($content, $charset); } else { $this->addHtmlContent($content, $charset); } } public function addHtmlContent($content, $charset = 'UTF-8') { $dom = new \DOMDocument('1.0', $charset); $dom->validateOnParse = true; $current = libxml_use_internal_errors(true); @$dom->loadHTML($content); libxml_use_internal_errors($current); $this->addDocument($dom); $base = $this->filterXPath('descendant-or-self::base')->extract(array('href')); if (count($base)) { $this->uri = current($base); } } public function addXmlContent($content, $charset = 'UTF-8') { $dom = new \DOMDocument('1.0', $charset); $dom->validateOnParse = true; $current = libxml_use_internal_errors(true); @$dom->loadXML(str_replace('xmlns', 'ns', $content)); libxml_use_internal_errors($current); $this->addDocument($dom); } public function addDocument(\DOMDocument $dom) { if ($dom->documentElement) { $this->addNode($dom->documentElement); } } public function addNodeList(\DOMNodeList $nodes) { foreach ($nodes as $node) { $this->addNode($node); } } public function addNodes(array $nodes) { foreach ($nodes as $node) { $this->add($node); } } public function addNode(\DOMNode $node) { if ($node instanceof \DOMDocument) { $this->attach($node->documentElement); } else { $this->attach($node); } } public function eq($position) { foreach ($this as $i => $node) { if ($i == $position) { return new static($node, $this->uri); } } return new static(null, $this->uri); } public function each(\Closure $closure) { $data = array(); foreach ($this as $i => $node) { $data[] = $closure($node, $i); } return $data; } public function reduce(\Closure $closure) { $nodes = array(); foreach ($this as $i => $node) { if (false !== $closure($node, $i)) { $nodes[] = $node; } } return new static($nodes, $this->uri); } public function first() { return $this->eq(0); } public function last() { return $this->eq(count($this) - 1); } public function siblings() { if (!count($this)) { throw new \InvalidArgumentException('The current node list is empty.'); } return new static($this->sibling($this->getNode(0)->parentNode->firstChild), $this->uri); } public function nextAll() { if (!count($this)) { throw new \InvalidArgumentException('The current node list is empty.'); } return new static($this->sibling($this->getNode(0)), $this->uri); } public function previousAll() { if (!count($this)) { throw new \InvalidArgumentException('The current node list is empty.'); } return new static($this->sibling($this->getNode(0), 'previousSibling'), $this->uri); } public function parents() { if (!count($this)) { throw new \InvalidArgumentException('The current node list is empty.'); } $node = $this->getNode(0); $nodes = array(); while ($node = $node->parentNode) { if (1 === $node->nodeType && '_root' !== $node->nodeName) { $nodes[] = $node; } } return new static($nodes, $this->uri); } public function children() { if (!count($this)) { throw new \InvalidArgumentException('The current node list is empty.'); } return new static($this->sibling($this->getNode(0)->firstChild), $this->uri); } public function attr($attribute) { if (!count($this)) { throw new \InvalidArgumentException('The current node list is empty.'); } return $this->getNode(0)->getAttribute($attribute); } public function text() { if (!count($this)) { throw new \InvalidArgumentException('The current node list is empty.'); } return $this->getNode(0)->nodeValue; } public function extract($attributes) { $attributes = (array) $attributes; $data = array(); foreach ($this as $node) { $elements = array(); foreach ($attributes as $attribute) { if ('_text' === $attribute) { $elements[] = $node->nodeValue; } else { $elements[] = $node->getAttribute($attribute); } } $data[] = count($attributes) > 1 ? $elements : $elements[0]; } return $data; } public function filterXPath($xpath) { $document = new \DOMDocument('1.0', 'UTF-8'); $root = $document->appendChild($document->createElement('_root')); foreach ($this as $node) { $root->appendChild($document->importNode($node, true)); } $domxpath = new \DOMXPath($document); return new static($domxpath->query($xpath), $this->uri); } public function filter($selector) { if (!class_exists('Symfony\\Component\\CssSelector\\CssSelector')) { throw new \RuntimeException('Unable to filter with a CSS selector as the Symfony CssSelector is not installed (you can use filterXPath instead).'); } return $this->filterXPath(CssSelector::toXPath($selector)); } public function selectLink($value) { $xpath = sprintf('//a[contains(concat(\' \', normalize-space(string(.)), \' \'), %s)] ', static::xpathLiteral(' '.$value.' ')). sprintf('| //a/img[contains(concat(\' \', normalize-space(string(@alt)), \' \'), %s)]/ancestor::a', static::xpathLiteral(' '.$value.' ')); return $this->filterXPath($xpath); } public function selectButton($value) { $xpath = sprintf('//input[((@type="submit" or @type="button") and contains(concat(\' \', normalize-space(string(@value)), \' \'), %s)) ', static::xpathLiteral(' '.$value.' ')). sprintf('or (@type="image" and contains(concat(\' \', normalize-space(string(@alt)), \' \'), %s)) or @id="%s" or @name="%s"] ', static::xpathLiteral(' '.$value.' '), $value, $value). sprintf('| //button[contains(concat(\' \', normalize-space(string(.)), \' \'), %s) or @id="%s" or @name="%s"]', static::xpathLiteral(' '.$value.' '), $value, $value); return $this->filterXPath($xpath); } public function link($method = 'get') { if (!count($this)) { throw new \InvalidArgumentException('The current node list is empty.'); } $node = $this->getNode(0); return new Link($node, $this->uri, $method); } public function links() { $links = array(); foreach ($this as $node) { $links[] = new Link($node, $this->uri, 'get'); } return $links; } public function form(array $values = null, $method = null) { if (!count($this)) { throw new \InvalidArgumentException('The current node list is empty.'); } $form = new Form($this->getNode(0), $this->uri, $method); if (null !== $values) { $form->setValues($values); } return $form; } static public function xpathLiteral($s) { if (false === strpos($s, "'")) { return sprintf("'%s'", $s); } if (false === strpos($s, '"')) { return sprintf('"%s"', $s); } $string = $s; $parts = array(); while (true) { if (false !== $pos = strpos($string, "'")) { $parts[] = sprintf("'%s'", substr($string, 0, $pos)); $parts[] = "\"'\""; $string = substr($string, $pos + 1); } else { $parts[] = "'$string'"; break; } } return sprintf("concat(%s)", implode($parts, ', ')); } private function getNode($position) { foreach ($this as $i => $node) { if ($i == $position) { return $node; } } return null; } private function sibling($node, $siblingDir = 'nextSibling') { $nodes = array(); do { if ($node !== $this->getNode(0) && $node->nodeType === 1) { $nodes[] = $node; } } while ($node = $node->$siblingDir); return $nodes; } } <?php namespace Symfony\Component\DomCrawler\Field; class ChoiceFormField extends FormField { private $type; private $multiple; private $options; public function hasValue() { if (in_array($this->type, array('checkbox', 'radio')) && null === $this->value) { return false; } return true; } public function isDisabled() { foreach ($this->options as $option) { if ($option['value'] == $this->value && $option['disabled']) { return true; } } return false; } public function select($value) { $this->setValue($value); } public function tick() { if ('checkbox' !== $this->type) { throw new \LogicException(sprintf('You cannot tick "%s" as it is not a checkbox (%s).', $this->name, $this->type)); } $this->setValue(true); } public function untick() { if ('checkbox' !== $this->type) { throw new \LogicException(sprintf('You cannot tick "%s" as it is not a checkbox (%s).', $this->name, $this->type)); } $this->setValue(false); } public function setValue($value) { if ('checkbox' == $this->type && false === $value) { $this->value = null; } elseif ('checkbox' == $this->type && true === $value) { $this->value = $this->options[0]['value']; } else { if (is_array($value)) { if (!$this->multiple) { throw new \InvalidArgumentException(sprintf('The value for "%s" cannot be an array.', $this->name)); } foreach ($value as $v) { if (!$this->containsOption($v, $this->options)) { throw new \InvalidArgumentException(sprintf('Input "%s" cannot take "%s" as a value (possible values: %s).', $this->name, $v, implode(', ', $this->availableOptionValues()))); } } } elseif (!$this->containsOption($value, $this->options)) { throw new \InvalidArgumentException(sprintf('Input "%s" cannot take "%s" as a value (possible values: %s).', $this->name, $value, implode(', ', $this->availableOptionValues()))); } if ($this->multiple) { $value = (array) $value; } if (is_array($value)) { $this->value = $value; } else { parent::setValue($value); } } } public function addChoice(\DOMNode $node) { if (!$this->multiple && 'radio' != $this->type) { throw new \LogicException(sprintf('Unable to add a choice for "%s" as it is not multiple or is not a radio button.', $this->name)); } $option = $this->buildOptionValue($node); $this->options[] = $option; if ($node->getAttribute('checked')) { $this->value = $option['value']; } } public function getType() { return $this->type; } public function isMultiple() { return $this->multiple; } protected function initialize() { if ('input' != $this->node->nodeName && 'select' != $this->node->nodeName) { throw new \LogicException(sprintf('A ChoiceFormField can only be created from an input or select tag (%s given).', $this->node->nodeName)); } if ('input' == $this->node->nodeName && 'checkbox' != $this->node->getAttribute('type') && 'radio' != $this->node->getAttribute('type')) { throw new \LogicException(sprintf('A ChoiceFormField can only be created from an input tag with a type of checkbox or radio (given type is %s).', $this->node->getAttribute('type'))); } $this->value = null; $this->options = array(); $this->multiple = false; if ('input' == $this->node->nodeName) { $this->type = $this->node->getAttribute('type'); $optionValue = $this->buildOptionValue($this->node); $this->options[] = $optionValue; if ($this->node->getAttribute('checked')) { $this->value = $optionValue['value']; } } else { $this->type = 'select'; if ($this->node->hasAttribute('multiple')) { $this->multiple = true; $this->value = array(); $this->name = str_replace('[]', '', $this->name); } $found = false; foreach ($this->xpath->query('descendant::option', $this->node) as $option) { $this->options[] = $this->buildOptionValue($option); if ($option->getAttribute('selected')) { $found = true; if ($this->multiple) { $this->value[] = $option->getAttribute('value'); } else { $this->value = $option->getAttribute('value'); } } } $option = $this->xpath->query('descendant::option', $this->node)->item(0); if (!$found && !$this->multiple && $option instanceof \DOMElement) { $this->value = $option->getAttribute('value'); } } } private function buildOptionValue($node) { $option = array(); $defaultValue = (isset($node->nodeValue) && !empty($node->nodeValue)) ? $node->nodeValue : '1'; $option['value'] = $node->hasAttribute('value') ? $node->getAttribute('value') : $defaultValue; $option['disabled'] = ($node->hasAttribute('disabled') && $node->getAttribute('disabled') == 'disabled'); return $option; } public function containsOption($optionValue, $options) { foreach ($options as $option) { if ($option['value'] == $optionValue) { return true; } } return false; } public function availableOptionValues() { $values = array(); foreach ($this->options as $option) { $values[] = $option['value']; } return $values; } } <?php namespace Symfony\Component\DomCrawler\Field; class FileFormField extends FormField { public function setErrorCode($error) { $codes = array(UPLOAD_ERR_INI_SIZE, UPLOAD_ERR_FORM_SIZE, UPLOAD_ERR_PARTIAL, UPLOAD_ERR_NO_FILE, UPLOAD_ERR_NO_TMP_DIR, UPLOAD_ERR_CANT_WRITE, UPLOAD_ERR_EXTENSION); if (!in_array($error, $codes)) { throw new \InvalidArgumentException(sprintf('The error code %s is not valid.', $error)); } $this->value = array('name' => '', 'type' => '', 'tmp_name' => '', 'error' => $error, 'size' => 0); } public function upload($value) { $this->setValue($value); } public function setValue($value) { if (null !== $value && is_readable($value)) { $error = UPLOAD_ERR_OK; $size = filesize($value); $name = basename($value); $tmp = tempnam(sys_get_temp_dir(), 'upload'); unlink($tmp); copy($value, $tmp); $value = $tmp; } else { $error = UPLOAD_ERR_NO_FILE; $size = 0; $name = ''; $value = ''; } $this->value = array('name' => $name, 'type' => '', 'tmp_name' => $value, 'error' => $error, 'size' => $size); } protected function initialize() { if ('input' != $this->node->nodeName) { throw new \LogicException(sprintf('A FileFormField can only be created from an input tag (%s given).', $this->node->nodeName)); } if ('file' != $this->node->getAttribute('type')) { throw new \LogicException(sprintf('A FileFormField can only be created from an input tag with a type of file (given type is %s).', $this->node->getAttribute('type'))); } $this->setValue(null); } } <?php namespace Symfony\Component\DomCrawler\Field; abstract class FormField { protected $node; protected $name; protected $value; protected $document; protected $xpath; protected $disabled; public function __construct(\DOMNode $node) { $this->node = $node; $this->name = $node->getAttribute('name'); $this->document = new \DOMDocument('1.0', 'UTF-8'); $this->node = $this->document->importNode($this->node, true); $root = $this->document->appendChild($this->document->createElement('_root')); $root->appendChild($this->node); $this->xpath = new \DOMXPath($this->document); $this->initialize(); } public function getName() { return $this->name; } public function getValue() { return $this->value; } public function setValue($value) { $this->value = (string) $value; } public function hasValue() { return true; } public function isDisabled() { return $this->node->hasAttribute('disabled'); } abstract protected function initialize(); } <?php namespace Symfony\Component\DomCrawler\Field; class InputFormField extends FormField { protected function initialize() { if ('input' != $this->node->nodeName) { throw new \LogicException(sprintf('An InputFormField can only be created from an input tag (%s given).', $this->node->nodeName)); } if ('checkbox' == $this->node->getAttribute('type')) { throw new \LogicException('Checkboxes should be instances of ChoiceFormField.'); } if ('file' == $this->node->getAttribute('type')) { throw new \LogicException('File inputs should be instances of FileFormField.'); } $this->value = $this->node->getAttribute('value'); } } <?php namespace Symfony\Component\DomCrawler\Field; class TextareaFormField extends FormField { protected function initialize() { if ('textarea' != $this->node->nodeName) { throw new \LogicException(sprintf('A TextareaFormField can only be created from a textarea tag (%s given).', $this->node->nodeName)); } $this->value = null; foreach ($this->node->childNodes as $node) { $this->value .= $this->document->saveXML($node); } } } <?php namespace Symfony\Component\DomCrawler; use Symfony\Component\DomCrawler\Field\FormField; class Form extends Link implements \ArrayAccess { private $button; private $fields; public function __construct(\DOMNode $node, $currentUri, $method = null) { parent::__construct($node, $currentUri, $method); $this->initialize(); } public function getFormNode() { return $this->node; } public function setValues(array $values) { foreach ($values as $name => $value) { $this->fields->set($name, $value); } return $this; } public function getValues() { $values = array(); foreach ($this->fields->all() as $name => $field) { if ($field->isDisabled()) { continue; } if (!$field instanceof Field\FileFormField && $field->hasValue()) { $values[$name] = $field->getValue(); } } return $values; } public function getFiles() { if (!in_array($this->getMethod(), array('POST', 'PUT', 'DELETE', 'PATCH'))) { return array(); } $files = array(); foreach ($this->fields->all() as $name => $field) { if ($field->isDisabled()) { continue; } if ($field instanceof Field\FileFormField) { $files[$name] = $field->getValue(); } } return $files; } public function getPhpValues() { $qs = http_build_query($this->getValues(), '', '&'); parse_str($qs, $values); return $values; } public function getPhpFiles() { $qs = http_build_query($this->getFiles(), '', '&'); parse_str($qs, $values); return $values; } public function getUri() { $uri = parent::getUri(); if (!in_array($this->getMethod(), array('POST', 'PUT', 'DELETE', 'PATCH')) && $queryString = http_build_query($this->getValues(), null, '&')) { $sep = false === strpos($uri, '?') ? '?' : '&'; $uri .= $sep.$queryString; } return $uri; } protected function getRawUri() { return $this->node->getAttribute('action'); } public function getMethod() { if (null !== $this->method) { return $this->method; } return $this->node->getAttribute('method') ? strtoupper($this->node->getAttribute('method')) : 'GET'; } public function has($name) { return $this->fields->has($name); } public function remove($name) { $this->fields->remove($name); } public function get($name) { return $this->fields->get($name); } public function set(FormField $field) { $this->fields->add($field); } public function all() { return $this->fields->all(); } public function offsetExists($name) { return $this->has($name); } public function offsetGet($name) { return $this->fields->get($name); } public function offsetSet($name, $value) { $this->fields->set($name, $value); } public function offsetUnset($name) { $this->fields->remove($name); } protected function setNode(\DOMNode $node) { $this->button = $node; if ('button' == $node->nodeName || ('input' == $node->nodeName && in_array($node->getAttribute('type'), array('submit', 'button', 'image')))) { do { if (null === $node = $node->parentNode) { throw new \LogicException('The selected node does not have a form ancestor.'); } } while ('form' != $node->nodeName); } elseif('form' != $node->nodeName) { throw new \LogicException(sprintf('Unable to submit on a "%s" tag.', $node->nodeName)); } $this->node = $node; } private function initialize() { $this->fields = new FormFieldRegistry(); $document = new \DOMDocument('1.0', 'UTF-8'); $node = $document->importNode($this->node, true); $button = $document->importNode($this->button, true); $root = $document->appendChild($document->createElement('_root')); $root->appendChild($node); $root->appendChild($button); $xpath = new \DOMXPath($document); foreach ($xpath->query('descendant::input | descendant::textarea | descendant::select', $root) as $node) { if (!$node->hasAttribute('name')) { continue; } $nodeName = $node->nodeName; if ($node === $button) { $this->set(new Field\InputFormField($node)); } elseif ('select' == $nodeName || 'input' == $nodeName && 'checkbox' == $node->getAttribute('type')) { $this->set(new Field\ChoiceFormField($node)); } elseif ('input' == $nodeName && 'radio' == $node->getAttribute('type')) { if ($this->has($node->getAttribute('name'))) { $this->get($node->getAttribute('name'))->addChoice($node); } else { $this->set(new Field\ChoiceFormField($node)); } } elseif ('input' == $nodeName && 'file' == $node->getAttribute('type')) { $this->set(new Field\FileFormField($node)); } elseif ('input' == $nodeName && !in_array($node->getAttribute('type'), array('submit', 'button', 'image'))) { $this->set(new Field\InputFormField($node)); } elseif ('textarea' == $nodeName) { $this->set(new Field\TextareaFormField($node)); } } } } class FormFieldRegistry { private $fields = array(); private $base; public function add(FormField $field) { $segments = $this->getSegments($field->getName()); $target =& $this->fields; while ($segments) { if (!is_array($target)) { $target = array(); } $path = array_shift($segments); if ('' === $path) { $target =& $target[]; } else { $target =& $target[$path]; } } $target = $field; } public function remove($name) { $segments = $this->getSegments($name); $target =& $this->fields; while (count($segments) > 1) { $path = array_shift($segments); if (!array_key_exists($path, $target)) { return; } $target =& $target[$path]; } unset($target[array_shift($segments)]); } public function &get($name) { $segments = $this->getSegments($name); $target =& $this->fields; while ($segments) { $path = array_shift($segments); if (!array_key_exists($path, $target)) { throw new \InvalidArgumentException(sprintf('Unreachable field "%s"', $path)); } $target =& $target[$path]; } return $target; } public function has($name) { try { $this->get($name); return true; } catch (\InvalidArgumentException $e) { return false; } } public function set($name, $value) { $target =& $this->get($name); if (is_array($value)) { $fields = self::create($name, $value); foreach ($fields->all() as $k => $v) { $this->set($k, $v); } } else { $target->setValue($value); } } public function all() { return $this->walk($this->fields, $this->base); } static private function create($base, array $values) { $registry = new static(); $registry->base = $base; $registry->fields = $values; return $registry; } private function walk(array $array, $base = '', array &$output = array()) { foreach ($array as $k => $v) { $path = empty($base) ? $k : sprintf("%s[%s]", $base, $k); if (is_array($v)) { $this->walk($v, $path, $output); } else { $output[$path] = $v; } } return $output; } private function getSegments($name) { if (preg_match('/^(?P<base>[^[]+)(?P<extra>(\[.*)|$)/', $name, $m)) { $segments = array($m['base']); while (preg_match('/^\[(?P<segment>.*?)\](?P<extra>.*)$/', $m['extra'], $m)) { $segments[] = $m['segment']; } return $segments; } throw new \InvalidArgumentException(sprintf('Malformed field path "%s"', $name)); } } <?php namespace Symfony\Component\DomCrawler; class Link { protected $node; protected $method; protected $currentUri; public function __construct(\DOMNode $node, $currentUri, $method = 'GET') { if (!in_array(substr($currentUri, 0, 4), array('http', 'file'))) { throw new \InvalidArgumentException(sprintf('Current URI must be an absolute URL ("%s").', $currentUri)); } $this->setNode($node); $this->method = $method ? strtoupper($method) : null; $this->currentUri = $currentUri; } public function getNode() { return $this->node; } public function getMethod() { return $this->method; } public function getUri() { $uri = trim($this->getRawUri()); if (0 === strpos($uri, 'http')) { return $uri; } if (!$uri) { return $this->currentUri; } if ('#' === $uri[0]) { $baseUri = $this->currentUri; if (false !== $pos = strpos($baseUri, '#')) { $baseUri = substr($baseUri, 0, $pos); } return $baseUri.$uri; } if ('?' === $uri[0]) { $baseUri = $this->currentUri; if (false !== $pos = strpos($baseUri, '?')) { $baseUri = substr($baseUri, 0, $pos); } return $baseUri.$uri; } if ('/' === $uri[0]) { return preg_replace('#^(.*?//[^/]+)(?:\/.*)?$#', '$1', $this->currentUri).$uri; } return substr($this->currentUri, 0, strrpos($this->currentUri, '/') + 1).$uri; } protected function getRawUri() { return $this->node->getAttribute('href'); } protected function setNode(\DOMNode $node) { if ('a' != $node->nodeName) { throw new \LogicException(sprintf('Unable to click on a "%s" tag.', $node->nodeName)); } $this->node = $node; } } Copyright (c) 2010 Fabien Potencier Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. <?php if (!class_exists('Composer\\Autoload\\ClassLoader', false)) { require __DIR__ . '/composer' . '/ClassLoader.php'; } return call_user_func(function() { $loader = new \Composer\Autoload\ClassLoader(); $composerDir = __DIR__ . '/composer'; $map = require $composerDir . '/autoload_namespaces.php'; foreach ($map as $namespace => $path) { $loader->add($namespace, $path); } $classMap = require $composerDir . '/autoload_classmap.php'; if ($classMap) { $loader->addClassMap($classMap); } $loader->register(); return $loader; }); <?php namespace Composer\Autoload; class ClassLoader { private $prefixes = array(); private $fallbackDirs = array(); private $useIncludePath = false; private $classMap = array(); public function getPrefixes() { return $this->prefixes; } public function getFallbackDirs() { return $this->fallbackDirs; } public function getClassMap() { return $this->classMap; } public function addClassMap(array $classMap) { if ($this->classMap) { $this->classMap = array_merge($this->classMap, $classMap); } else { $this->classMap = $classMap; } } public function add($prefix, $paths) { if (!$prefix) { foreach ((array) $paths as $path) { $this->fallbackDirs[] = $path; } return; } if (isset($this->prefixes[$prefix])) { $this->prefixes[$prefix] = array_merge( $this->prefixes[$prefix], (array) $paths ); } else { $this->prefixes[$prefix] = (array) $paths; } } public function setUseIncludePath($useIncludePath) { $this->useIncludePath = $useIncludePath; } public function getUseIncludePath() { return $this->useIncludePath; } public function register($prepend = false) { spl_autoload_register(array($this, 'loadClass'), true, $prepend); } public function unregister() { spl_autoload_unregister(array($this, 'loadClass')); } public function loadClass($class) { if ($file = $this->findFile($class)) { require $file; return true; } } public function findFile($class) { if (isset($this->classMap[$class])) { return $this->classMap[$class]; } if ('\\' == $class[0]) { $class = substr($class, 1); } if (false !== $pos = strrpos($class, '\\')) { $classPath = str_replace('\\', DIRECTORY_SEPARATOR, substr($class, 0, $pos)) . DIRECTORY_SEPARATOR; $className = substr($class, $pos + 1); } else { $classPath = null; $className = $class; } $classPath .= str_replace('_', DIRECTORY_SEPARATOR, $className) . '.php'; foreach ($this->prefixes as $prefix => $dirs) { if (0 === strpos($class, $prefix)) { foreach ($dirs as $dir) { if (file_exists($dir . DIRECTORY_SEPARATOR . $classPath)) { return $dir . DIRECTORY_SEPARATOR . $classPath; } } } } foreach ($this->fallbackDirs as $dir) { if (file_exists($dir . DIRECTORY_SEPARATOR . $classPath)) { return $dir . DIRECTORY_SEPARATOR . $classPath; } } if ($this->useIncludePath && $file = stream_resolve_include_path($classPath)) { return $file; } } } <?php $vendorDir = dirname(__DIR__); $baseDir = dirname($vendorDir); return array( 'Twig_' => $baseDir . '/vendor/twig/twig/lib/', 'Symfony\\Component\\Validator' => $baseDir . '/vendor/symfony/validator/', 'Symfony\\Component\\Translation' => $baseDir . '/vendor/symfony/translation/', 'Symfony\\Component\\Routing' => $baseDir . '/vendor/symfony/routing/', 'Symfony\\Component\\Process' => $baseDir . '/vendor/symfony/process/', 'Symfony\\Component\\Locale' => $baseDir . '/vendor/symfony/locale/', 'Symfony\\Component\\HttpKernel' => $baseDir . '/vendor/symfony/http-kernel/', 'Symfony\\Component\\HttpFoundation' => $baseDir . '/vendor/symfony/http-foundation/', 'Symfony\\Component\\Form' => $baseDir . '/vendor/symfony/form/', 'Symfony\\Component\\Finder' => $baseDir . '/vendor/symfony/finder/', 'Symfony\\Component\\EventDispatcher' => $baseDir . '/vendor/symfony/event-dispatcher/', 'Symfony\\Component\\DomCrawler' => $baseDir . '/vendor/symfony/dom-crawler/', 'Symfony\\Component\\CssSelector' => $baseDir . '/vendor/symfony/css-selector/', 'Symfony\\Component\\ClassLoader' => $baseDir . '/vendor/symfony/class-loader/', 'Symfony\\Component\\BrowserKit' => $baseDir . '/vendor/symfony/browser-kit/', 'Symfony\\Bridge\\Twig' => $baseDir . '/vendor/symfony/twig-bridge/', 'Silex' => $baseDir . '/src/', 'SessionHandlerInterface' => $baseDir . '/vendor/symfony/http-foundation/Symfony/Component/HttpFoundation/Resources/stubs', 'Pimple' => $baseDir . '/vendor/pimple/pimple/lib/', 'Monolog' => $baseDir . '/vendor/monolog/monolog/src/', 'Doctrine\\DBAL' => $baseDir . '/vendor/doctrine/dbal/lib/', 'Doctrine\\Common' => $baseDir . '/vendor/doctrine/common/lib/', ); <?php $vendorDir = dirname(__DIR__); $baseDir = dirname($vendorDir); return array( ); �I աґ��o���`<RU˿GBMB