[
  {
    "path": ".gitignore",
    "content": "/phpunit.xml\n/vendor\n/build\n/composer.lock\n\n"
  },
  {
    "path": ".travis.yml",
    "content": "language: php\n\nsudo: false\n\nenv:\n    global:\n        - SYMFONY_DEPRECATIONS_HELPER=weak\n\ncache:\n    directories:\n      - $HOME/.composer/cache\n\nbefore_install:\n    - if [[ $TRAVIS_PHP_VERSION != hhvm ]]; then phpenv config-rm xdebug.ini; fi\n\nbefore_script:\n    # symfony/*\n    - sh -c \"if [ '$TWIG_VERSION' != '2.0' ]; then sed -i 's/~1.8|~2.0/~1.8/g' composer.json; composer update; fi\"\n    - sh -c \"if [ '$SYMFONY_DEPS_VERSION' = '3.0' ]; then sed -i 's/~2\\.8|^3\\.0/3.0.*@dev/g' composer.json; composer update; fi\"\n    - sh -c \"if [ '$SYMFONY_DEPS_VERSION' = '3.1' ]; then sed -i 's/~2\\.8|^3\\.0/3.1.*@dev/g' composer.json; composer update; fi\"\n    - sh -c \"if [ '$SYMFONY_DEPS_VERSION' = '' ]; then sed -i 's/~2\\.8|^3\\.0/2.8.*@dev/g' composer.json; composer update; fi\"\n    - composer install\n\nscript: phpunit\n\nmatrix:\n    include:\n        - php: 5.5\n        - php: 5.6\n          env: TWIG_VERSION=2.0\n        - php: 5.6\n          env: SYMFONY_DEPS_VERSION=3.0\n        - php: 5.6\n          env: SYMFONY_DEPS_VERSION=3.1\n        - php: 7.0\n        - php: hhvm\n"
  },
  {
    "path": "LICENSE",
    "content": "Copyright (c) 2010-2016 Fabien Potencier\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is furnished\nto do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n"
  },
  {
    "path": "README.rst",
    "content": "Silex, a simple Web Framework\n=============================\n\nSilex is a PHP micro-framework to develop websites based on `Symfony\ncomponents`_::\n\n    <?php\n\n    require_once __DIR__.'/../vendor/autoload.php';\n\n    $app = new Silex\\Application();\n\n    $app->get('/hello/{name}', function ($name) use ($app) {\n      return 'Hello '.$app->escape($name);\n    });\n\n    $app->run();\n\nSilex works with PHP 5.5.9 or later.\n\nInstallation\n------------\n\nThe recommended way to install Silex is through `Composer`_:\n\n.. code-block:: bash\n\n    composer require silex/silex \"~2.0\"\n\nAlternatively, you can download the `silex.zip`_ file and extract it.\n\nMore Information\n----------------\n\nRead the `documentation`_ for more information and `changelog\n<doc/changelog.rst>`_ for upgrading information.\n\nTests\n-----\n\nTo run the test suite, you need `Composer`_ and `PHPUnit`_:\n\n.. code-block:: bash\n\n    $ composer install\n    $ phpunit\n\nCommunity\n---------\n\nCheck out #silex-php on irc.freenode.net.\n\nLicense\n-------\n\nSilex is licensed under the MIT license.\n\n.. _Symfony components: http://symfony.com\n.. _Composer:           http://getcomposer.org\n.. _PHPUnit:            https://phpunit.de\n.. _silex.zip:          http://silex.sensiolabs.org/download\n.. _documentation:      http://silex.sensiolabs.org/documentation\n"
  },
  {
    "path": "bin/build",
    "content": "#!/bin/sh\n\nPHP=`which php`\nGIT=`which git`\nDIR=`$PHP -r \"echo dirname(dirname(realpath('$0')));\"`\n\nif [ ! -d \"$DIR/build\" ]; then\n    mkdir -p $DIR/build\nfi\n\ncd $DIR/build\n\nif [ ! -f \"composer.phar\" ]; then\n    curl -s http://getcomposer.org/installer 2>/dev/null | $PHP >/dev/null 2>/dev/null\nelse\n    $PHP composer.phar self-update >/dev/null 2>/dev/null\nfi\n\nfor TYPE in slim fat\ndo\n    if [ -d \"$DIR/build/skeleton\" ]; then\n        rm -rf $DIR/build/skeleton\n    fi\n    mkdir -p $DIR/build/skeleton\n\n    cd \"$DIR/build/skeleton\"\n\n    mkdir -p web/\n    COMPOSER=$TYPE\"_composer.json\"\n    cp $DIR/bin/skeleton/$COMPOSER composer.json\n    cp $DIR/bin/skeleton/index.php web/index.php\n\n    $PHP ../composer.phar install -q\n\n    if [ -d \"$DIR/build/tmp/silex\" ]; then\n        rm -rf $DIR/build/tmp/silex\n    fi\n    mkdir -p $DIR/build/tmp/silex\n\n    cd \"$DIR/build/tmp/silex\"\n    cp -r ../../skeleton/* .\n\n    find . -name .DS_Store | xargs rm -rf -\n    find . -name .git | xargs rm -rf -\n    find . -name phpunit.xml.* | xargs rm -rf -\n    find . -type d -name Tests | xargs rm -rf -\n    find . -type d -name test* | xargs rm -rf -\n    find . -type d -name doc | xargs rm -rf -\n    find . -type d -name ext | xargs rm -rf -\n\n    export COPY_EXTENDED_ATTRIBUTES_DISABLE=true\n    export COPYFILE_DISABLE=true\n\n    cd \"$DIR/build/tmp\"\n\n    if [ \"slim\" = \"$TYPE\" ]; then\n        NAME=\"silex\"\n    else\n        NAME=\"silex_fat\"\n    fi\n\n    rm -f \"$DIR/build/$NAME.*\"\n    tar zcpf \"$DIR/build/$NAME.tgz\" silex\n    zip -rq \"$DIR/build/$NAME.zip\" silex\n    rm -rf \"$DIR/build/tmp\"\n    rm -rf \"$DIR/build/skeleton\"\ndone\n"
  },
  {
    "path": "bin/skeleton/fat_composer.json",
    "content": "{\n    \"require\": {\n        \"silex/silex\": \"~1.1\",\n        \"symfony/browser-kit\": \"~2.3\",\n        \"symfony/console\": \"~2.3\",\n        \"symfony/config\": \"~2.3\",\n        \"symfony/css-selector\": \"~2.3\",\n        \"symfony/dom-crawler\": \"~2.3\",\n        \"symfony/filesystem\": \"~2.3\",\n        \"symfony/finder\": \"~2.3\",\n        \"symfony/form\": \"~2.3\",\n        \"symfony/locale\": \"~2.3\",\n        \"symfony/process\": \"~2.3\",\n        \"symfony/security\": \"~2.3\",\n        \"symfony/serializer\": \"~2.3\",\n        \"symfony/translation\": \"~2.3\",\n        \"symfony/validator\": \"~2.3\",\n        \"symfony/monolog-bridge\": \"~2.3\",\n        \"symfony/twig-bridge\": \"~2.3\",\n        \"doctrine/dbal\": \">=2.2.0,<2.4.0-dev\",\n        \"swiftmailer/swiftmailer\": \"5.*\"\n    }\n}\n"
  },
  {
    "path": "bin/skeleton/index.php",
    "content": "<?php\n\nrequire_once __DIR__.'/../vendor/autoload.php';\n\n$app = new Silex\\Application();\n\n$app->get('/hello', function () {\n    return 'Hello!';\n});\n\n$app->run();\n"
  },
  {
    "path": "bin/skeleton/slim_composer.json",
    "content": "{\n    \"require\": {\n        \"silex/silex\": \"~1.1\"\n    }\n}\n"
  },
  {
    "path": "composer.json",
    "content": "{\n    \"name\": \"silex/silex\",\n    \"description\": \"The PHP micro-framework based on the Symfony Components\",\n    \"keywords\": [\"microframework\"],\n    \"homepage\": \"http://silex.sensiolabs.org\",\n    \"license\": \"MIT\",\n    \"authors\": [\n        {\n            \"name\": \"Fabien Potencier\",\n            \"email\": \"fabien@symfony.com\"\n        },\n        {\n            \"name\": \"Igor Wiedler\",\n            \"email\": \"igor@wiedler.ch\"\n        }\n    ],\n    \"require\": {\n        \"php\": \">=5.5.9\",\n        \"pimple/pimple\": \"~3.0\",\n        \"symfony/event-dispatcher\": \"~2.8|^3.0\",\n        \"symfony/http-foundation\": \"~2.8|^3.0\",\n        \"symfony/http-kernel\": \"~2.8|^3.0\",\n        \"symfony/routing\": \"~2.8|^3.0\"\n    },\n    \"require-dev\": {\n        \"symfony/asset\": \"~2.8|^3.0\",\n        \"symfony/expression-language\": \"~2.8|^3.0\",\n        \"symfony/security\": \"~2.8|^3.0\",\n        \"symfony/config\": \"~2.8|^3.0\",\n        \"symfony/form\": \"~2.8|^3.0\",\n        \"symfony/browser-kit\": \"~2.8|^3.0\",\n        \"symfony/css-selector\": \"~2.8|^3.0\",\n        \"symfony/debug\": \"~2.8|^3.0\",\n        \"symfony/dom-crawler\": \"~2.8|^3.0\",\n        \"symfony/finder\": \"~2.8|^3.0\",\n        \"symfony/intl\": \"~2.8|^3.0\",\n        \"symfony/monolog-bridge\": \"~2.8|^3.0\",\n        \"symfony/doctrine-bridge\": \"~2.8|^3.0\",\n        \"symfony/options-resolver\": \"~2.8|^3.0\",\n        \"symfony/phpunit-bridge\": \"~2.8|^3.0\",\n        \"symfony/process\": \"~2.8|^3.0\",\n        \"symfony/serializer\": \"~2.8|^3.0\",\n        \"symfony/translation\": \"~2.8|^3.0\",\n        \"symfony/twig-bridge\": \"~2.8|^3.0\",\n        \"symfony/validator\": \"~2.8|^3.0\",\n        \"symfony/var-dumper\": \"~2.8|^3.0\",\n        \"twig/twig\": \"~1.8|~2.0\",\n        \"doctrine/dbal\": \"~2.2\",\n        \"swiftmailer/swiftmailer\": \"~5\",\n        \"monolog/monolog\": \"^1.4.1\"\n    },\n    \"replace\": {\n        \"silex/api\": \"self.version\",\n        \"silex/providers\": \"self.version\"\n    },\n    \"autoload\": {\n        \"psr-4\": { \"Silex\\\\\": \"src/Silex\" }\n    },\n    \"autoload-dev\" : {\n        \"psr-4\": { \"Silex\\\\Tests\\\\\" : \"tests/Silex/Tests\" }\n    },\n    \"extra\": {\n        \"branch-alias\": {\n            \"dev-master\": \"2.0.x-dev\"\n        }\n    },\n    \"minimum-stability\": \"dev\"\n}\n"
  },
  {
    "path": "doc/changelog.rst",
    "content": "Changelog\n=========\n\n2.0.4 (2016-XX-XX)\n------------------\n\n* n/a\n\n2.0.3 (2016-08-22)\n------------------\n\n* fixed lazy evaluation of 'monolog.use_error_handler'\n* fixed PHP7 type hint on controllers\n\n2.0.2 (2016-06-14)\n------------------\n\n* fixed Symfony 3.1 deprecations\n\n2.0.1 (2016-05-27)\n------------------\n\n* fixed the silex form extension registration to allow overriding default ones\n* removed support for the obsolete Locale Symfony component (uses the Intl one now)\n* added support for Symfony 3.1\n\n2.0.0 (2016-05-18)\n------------------\n\n* decoupled the exception handler from HttpKernelServiceProvider\n* Switched to BCrypt as the default encoder in the security provider\n* added full support for RequestMatcher\n* added support for Symfony Guard\n* added support for callables in CallbackResolver\n* added FormTrait::namedForm()\n* added support for delivery_addresses, delivery_whitelist, and sender_address\n* added support to register form types / form types extensions / form types guessers as services\n* added support for callable in mounts (allow nested route collection to be built easily)\n* added support for conditions on routes\n* added support for the Symfony VarDumper Component\n* added a global Twig variable (an AppVariable instance)\n* [BC BREAK] CSRF has been moved to a standalone provider (``form.secret`` is not available anymore)\n* added support for the Symfony HttpFoundation Twig bridge extension\n* added support for the Symfony Asset Component\n* bumped minimum version of Symfony to 2.8\n* bumped minimum version of PHP to 5.5.0\n* Updated Pimple to 3.0\n* Updated session listeners to extends HttpKernel ones\n* [BC BREAK] Locale management has been moved to LocaleServiceProvider which must be registered\n  if you want Silex to manage your locale (must also be registered for the translation service provider)\n* [BC BREAK] Provider interfaces moved to Silex\\Api namespace, published as\n  separate package via subtree split\n* [BC BREAK] ServiceProviderInterface split in to EventListenerProviderInterface\n  and BootableProviderInterface\n* [BC BREAK] Service Provider support files moved under Silex\\Provider\n  namespace, allowing publishing as separate package via sub-tree split\n* ``monolog.exception.logger_filter`` option added to Monolog service provider\n* [BC BREAK] ``$app['request']`` service removed, use ``$app['request_stack']`` instead\n\n1.3.6 (2016-XX-XX)\n------------------\n\n* n/a\n\n1.3.5 (2016-01-06)\n------------------\n\n* fixed typo in SecurityServiceProvider\n\n1.3.4 (2015-09-15)\n------------------\n\n* fixed some new deprecations\n* fixed translation registration for the validators\n\n1.3.3 (2015-09-08)\n------------------\n\n* added support for Symfony 3.0 and Twig 2.0\n* fixed some Form deprecations\n* removed deprecated method call in the exception handler\n* fixed Swiftmailer spool flushing when spool is not enabled\n\n1.3.2 (2015-08-24)\n------------------\n\n* no changes\n\n1.3.1 (2015-08-04)\n------------------\n\n* added missing support for the Expression constraint\n* fixed the possibility to override translations for validator error messages\n* fixed sub-mounts with same name clash\n* fixed session logout handler when a firewall is stateless\n\n1.3.0 (2015-06-05)\n------------------\n\n* added a `$app['user']` to get the current user (security provider)\n* added view handlers\n* added support for the OPTIONS HTTP method\n* added caching for the Translator provider\n* deprecated `$app['exception_handler']->disable()` in favor of `unset($app['exception_handler'])`\n* made Silex compatible with Symfony 2.7 an 2.8 (and keep compatibility with Symfony 2.3, 2.5, and 2.6)\n* removed deprecated TwigCoreExtension class (register the new HttpFragmentServiceProvider instead)\n* bumped minimum version of PHP to 5.3.9\n\n1.2.5 (2015-06-04)\n------------------\n\n* no code changes (last version of the 1.2 branch)\n\n1.2.4 (2015-04-11)\n------------------\n\n* fixed the exception message when mounting a collection that doesn't return a ControllerCollection\n* fixed Symfony dependencies (Silex 1.2 is not compatible with Symfony 2.7)\n\n1.2.3 (2015-01-20)\n------------------\n\n* fixed remember me listener\n* fixed translation files loading when they do not exist\n* allowed global after middlewares to return responses like route specific ones\n\n1.2.2 (2014-09-26)\n------------------\n\n* fixed Translator locale management\n* added support for the $app argument in application middlewares (to make it consistent with route middlewares)\n* added form.types to the Form provider\n\n1.2.1 (2014-07-01)\n------------------\n\n* added support permissions in the Monolog provider\n* fixed Switfmailer spool where the event dispatcher is different from the other ones\n* fixed locale when changing it on the translator itself\n\n1.2.0 (2014-03-29)\n------------------\n\n* Allowed disabling the boot logic of MonologServiceProvider\n* Reverted \"convert attributes on the request that actually exist\"\n* [BC BREAK] Routes are now always added in the order of their registration (even for mounted routes)\n* Added run() on Route to be able to define the controller code\n* Deprecated TwigCoreExtension (register the new HttpFragmentServiceProvider instead)\n* Added HttpFragmentServiceProvider\n* Allowed a callback to be a method call on a service (before, after, finish, error, on Application; convert, before, after on Controller)\n\n1.1.3 (2013-XX-XX)\n------------------\n\n* Fixed translator locale management\n\n1.1.2 (2013-10-30)\n------------------\n\n* Added missing \"security.hide_user_not_found\" support in SecurityServiceProvider\n* Fixed event listeners that are registered after the boot via the on() method\n\n1.0.2 (2013-10-30)\n------------------\n\n* Fixed SecurityServiceProvider to use null as a fake controller so that routes can be dumped\n\n1.1.1 (2013-10-11)\n------------------\n\n* Removed or replaced deprecated Symfony code\n* Updated code to take advantages of 2.3 new features\n* Only convert attributes on the request that actually exist.\n\n1.1.0 (2013-07-04)\n------------------\n\n* Support for any ``Psr\\Log\\LoggerInterface`` as opposed to the monolog-bridge\n  one.\n* Made dispatcher proxy methods ``on``, ``before``, ``after`` and ``error``\n  lazy, so that they will not instantiate the dispatcher early.\n* Dropped support for 2.1 and 2.2 versions of Symfony.\n\n1.0.1 (2013-07-04)\n------------------\n\n* Fixed RedirectableUrlMatcher::redirect() when Silex is configured to use a logger\n* Make ``DoctrineServiceProvider`` multi-db support lazy.\n\n1.0.0 (2013-05-03)\n------------------\n\n* **2013-04-12**: Added support for validators as services.\n\n* **2013-04-01**: Added support for host matching with symfony 2.2::\n\n      $app->match('/', function() {\n          // app-specific action\n      })->host('example.com');\n\n      $app->match('/', function ($user) {\n          // user-specific action\n      })->host('{user}.example.com');\n\n* **2013-03-08**: Added support for form type extensions and guessers as\n  services.\n\n* **2013-03-08**: Added support for remember-me via the\n  ``RememberMeServiceProvider``.\n\n* **2013-02-07**: Added ``Application::sendFile()`` to ease sending\n  ``BinaryFileResponse``.\n\n* **2012-11-05**: Filters have been renamed to application middlewares in the\n  documentation.\n\n* **2012-11-05**: The ``before()``, ``after()``, ``error()``, and ``finish()``\n  listener priorities now set the priority of the underlying Symfony event\n  instead of a custom one before.\n\n* **2012-11-05**: Removing the default exception handler should now be done\n  via its ``disable()`` method:\n\n    Before:\n\n        unset($app['exception_handler']);\n\n    After:\n\n        $app['exception_handler']->disable();\n\n* **2012-07-15**: removed the ``monolog.configure`` service. Use the\n  ``extend`` method instead:\n\n    Before::\n\n        $app['monolog.configure'] = $app->protect(function ($monolog) use ($app) {\n            // do something\n        });\n\n    After::\n\n        $app['monolog'] = $app->share($app->extend('monolog', function($monolog, $app) {\n            // do something\n\n            return $monolog;\n        }));\n\n\n* **2012-06-17**: ``ControllerCollection`` now takes a required route instance\n  as a constructor argument.\n\n    Before::\n\n        $controllers = new ControllerCollection();\n\n    After::\n\n        $controllers = new ControllerCollection(new Route());\n\n        // or even better\n        $controllers = $app['controllers_factory'];\n\n* **2012-06-17**: added application traits for PHP 5.4\n\n* **2012-06-16**: renamed ``request.default_locale`` to ``locale``\n\n* **2012-06-16**: Removed the ``translator.loader`` service. See documentation\n  for how to use XLIFF or YAML-based translation files.\n\n* **2012-06-15**: removed the ``twig.configure`` service. Use the ``extend``\n  method instead:\n\n    Before::\n\n        $app['twig.configure'] = $app->protect(function ($twig) use ($app) {\n            // do something\n        });\n\n    After::\n\n        $app['twig'] = $app->share($app->extend('twig', function($twig, $app) {\n            // do something\n\n            return $twig;\n        }));\n\n* **2012-06-13**: Added a route ``before`` middleware\n\n* **2012-06-13**: Renamed the route ``middleware`` to ``before``\n\n* **2012-06-13**: Added an extension for the Symfony Security component\n\n* **2012-05-31**: Made the ``BrowserKit``, ``CssSelector``, ``DomCrawler``,\n  ``Finder`` and ``Process`` components optional dependencies. Projects that\n  depend on them (e.g. through functional tests) should add those dependencies\n  to their ``composer.json``.\n\n* **2012-05-26**: added ``boot()`` to ``ServiceProviderInterface``.\n\n* **2012-05-26**: Removed ``SymfonyBridgesServiceProvider``. It is now implicit\n  by checking the existence of the bridge.\n\n* **2012-05-26**: Removed the ``translator.messages`` parameter (use\n  ``translator.domains`` instead).\n\n* **2012-05-24**: Removed the ``autoloader`` service (use composer instead).\n  The ``*.class_path`` settings on all the built-in providers have also been\n  removed in favor of Composer.\n\n* **2012-05-21**: Changed error() to allow handling specific exceptions.\n\n* **2012-05-20**: Added a way to define settings on a controller collection.\n\n* **2012-05-20**: The Request instance is not available anymore from the\n  Application after it has been handled.\n\n* **2012-04-01**: Added ``finish`` filters.\n\n* **2012-03-20**: Added ``json`` helper::\n\n        $data = array('some' => 'data');\n        $response = $app->json($data);\n\n* **2012-03-11**: Added route middlewares.\n\n* **2012-03-02**: Switched to use Composer for dependency management.\n\n* **2012-02-27**: Updated to Symfony 2.1 session handling.\n\n* **2012-01-02**: Introduced support for streaming responses.\n\n* **2011-09-22**: ``ExtensionInterface`` has been renamed to\n  ``ServiceProviderInterface``. All built-in extensions have been renamed\n  accordingly (for instance, ``Silex\\Extension\\TwigExtension`` has been\n  renamed to ``Silex\\Provider\\TwigServiceProvider``).\n\n* **2011-09-22**: The way reusable applications work has changed. The\n  ``mount()`` method now takes an instance of ``ControllerCollection`` instead\n  of an ``Application`` one.\n\n    Before::\n\n        $app = new Application();\n        $app->get('/bar', function() { return 'foo'; });\n\n        return $app;\n\n    After::\n\n        $app = new ControllerCollection();\n        $app->get('/bar', function() { return 'foo'; });\n\n        return $app;\n\n* **2011-08-08**: The controller method configuration is now done on the Controller itself\n\n    Before::\n\n        $app->match('/', function () { echo 'foo'; }, 'GET|POST');\n\n    After::\n\n        $app->match('/', function () { echo 'foo'; })->method('GET|POST');\n"
  },
  {
    "path": "doc/conf.py",
    "content": "import sys, os\nfrom sphinx.highlighting import lexers\nfrom pygments.lexers.web import PhpLexer\n\nsys.path.append(os.path.abspath('_exts'))\n\nextensions = []\nmaster_doc = 'index'\nhighlight_language = 'php'\n\nproject = u'Silex'\ncopyright = u'2010 Fabien Potencier'\n\nversion = '0'\nrelease = '0.0.0'\n\nlexers['php'] = PhpLexer(startinline=True)\n"
  },
  {
    "path": "doc/contributing.rst",
    "content": "Contributing\n============\n\nWe are open to contributions to the Silex code. If you find a bug or want to\ncontribute a provider, just follow these steps:\n\n* Fork `the Silex repository <https://github.com/silexphp/Silex>`_;\n\n* Make your feature addition or bug fix;\n\n* Add tests for it;\n\n* Optionally, add some documentation;\n\n* `Send a pull request\n  <https://help.github.com/articles/creating-a-pull-request>`_, to the correct\n  target branch (1.3 for bug fixes, master for new features).\n\n.. note::\n\n    Any code you contribute must be licensed under the MIT\n    License.\n\nWriting Documentation\n=====================\n\nThe documentation is written in `reStructuredText\n<http://docutils.sourceforge.net/rst.html>`_ and can be generated using `sphinx\n<http://sphinx-doc.org>`_.\n\n.. code-block:: bash\n\n    $ cd doc\n    $ sphinx-build -b html . build\n"
  },
  {
    "path": "doc/cookbook/error_handler.rst",
    "content": "Converting Errors to Exceptions\n===============================\n\nSilex catches exceptions that are thrown from within a request/response cycle.\nHowever, it does *not* catch PHP errors and notices. This recipe tells you how\nto catch them by converting them to exceptions.\n\nRegistering the ErrorHandler\n----------------------------\n\nThe ``Symfony/Debug`` package has an ``ErrorHandler`` class that solves this\nproblem. It converts all errors to exceptions, and exceptions are then caught\nby Silex.\n\nRegister it by calling the static ``register`` method::\n\n    use Symfony\\Component\\Debug\\ErrorHandler;\n\n    ErrorHandler::register();\n\nIt is recommended that you do this as early as possible.\n\nHandling fatal errors\n---------------------\n\nTo handle fatal errors, you can additionally register a global\n``ExceptionHandler``::\n\n    use Symfony\\Component\\Debug\\ExceptionHandler;\n\n    ExceptionHandler::register();\n\nIn production you may want to disable the debug output by passing ``false`` as\nthe ``$debug`` argument::\n\n    use Symfony\\Component\\Debug\\ExceptionHandler;\n\n    ExceptionHandler::register(false);\n"
  },
  {
    "path": "doc/cookbook/form_no_csrf.rst",
    "content": "Disabling CSRF Protection on a Form using the FormExtension\n===========================================================\n\nThe *FormExtension* provides a service for building form in your application\nwith the Symfony Form component. When the :doc:`CSRF Service Provider\n</providers/csrf>` is registered, the *FormExtension* uses the CSRF Protection\navoiding Cross-site request forgery, a method by which a malicious user\nattempts to make your legitimate users unknowingly submit data that they don't\nintend to submit.\n\nYou can find more details about CSRF Protection and CSRF token in the\n`Symfony Book\n<http://symfony.com/doc/current/book/forms.html#csrf-protection>`_.\n\nIn some cases (for example, when embedding a form in an html email) you might\nwant not to use this protection. The easiest way to avoid this is to\nunderstand that it is possible to give specific options to your form builder\nthrough the ``createBuilder()`` function.\n\nExample\n-------\n\n.. code-block:: php\n\n    $form = $app['form.factory']->createBuilder('form', null, array('csrf_protection' => false));\n\nThat's it, your form could be submitted from everywhere without CSRF Protection.\n\nGoing further\n-------------\n\nThis specific example showed how to change the ``csrf_protection`` in the\n``$options`` parameter of the ``createBuilder()`` function. More of them could\nbe passed through this parameter, it is as simple as using the Symfony\n``getDefaultOptions()`` method in your form classes. `See more here\n<http://symfony.com/doc/current/book/forms.html#book-form-creating-form-classes>`_.\n"
  },
  {
    "path": "doc/cookbook/guard_authentication.rst",
    "content": "How to Create a Custom Authentication System with Guard\n=======================================================\n\nWhether you need to build a traditional login form, an API token\nauthentication system or you need to integrate with some proprietary\nsingle-sign-on system, the Guard component can make it easy... and fun!\n\nIn this example, you'll build an API token authentication system and\nlearn how to work with Guard.\n\nStep 1) Create the Authenticator Class\n--------------------------------------\n\nSuppose you have an API where your clients will send an X-AUTH-TOKEN\nheader on each request. This token is composed of the username followed\nby a password, separated by a colon (e.g. ``X-AUTH-TOKEN: coolguy:awesomepassword``).\nYour job is to read this, find theassociated user (if any) and check\nthe password.\n\nTo create a custom authentication system, just create a class and make\nit implement GuardAuthenticatorInterface. Or, extend the simpler\nAbstractGuardAuthenticator. This requires you to implement six methods:\n\n.. code-block:: php\n\n    <?php\n\n    namespace App\\Security;\n\n    use Symfony\\Component\\HttpFoundation\\Request;\n    use Symfony\\Component\\HttpFoundation\\JsonResponse;\n    use Symfony\\Component\\Security\\Core\\User\\UserInterface;\n    use Symfony\\Component\\Security\\Core\\User\\UserProviderInterface;\n    use Symfony\\Component\\Security\\Guard\\AbstractGuardAuthenticator;\n    use Symfony\\Component\\Security\\Core\\Authentication\\Token\\TokenInterface;\n    use Symfony\\Component\\Security\\Core\\Exception\\AuthenticationException;\n\n    class TokenAuthenticator extends AbstractGuardAuthenticator\n    {\n        private $encoderFactory;\n\n        public function __construct(EncoderFactoryInterface $encoderFactory)\n        {\n            $this->encoderFactory = $encoderFactory;\n        }\n\n        public function getCredentials(Request $request)\n        {\n            // Checks if the credential header is provided\n            if (!$token = $request->headers->get('X-AUTH-TOKEN')) {\n                return;\n            }\n\n            // Parse the header or ignore it if the format is incorrect.\n            if (false === strpos($token, ':')) {\n                return;\n            }\n            list($username, $secret) = explode(':', $token, 2);\n\n            return array(\n                'username' => $username,\n                'secret' => $secret,\n            );\n        }\n\n        public function getUser($credentials, UserProviderInterface $userProvider)\n        {\n            return $userProvider->loadUserByUsername($credentials['username']);\n        }\n\n        public function checkCredentials($credentials, UserInterface $user)\n        {\n            // check credentials - e.g. make sure the password is valid\n            // return true to cause authentication success\n\n            $encoder = $this->encoderFactory->getEncoder($user);\n\n            return $encoder->isPasswordValid(\n                $user->getPassword(),\n                $credentials['secret'],\n                $user->getSalt()\n            );\n        }\n\n        public function onAuthenticationSuccess(Request $request, TokenInterface $token, $providerKey)\n        {\n            // on success, let the request continue\n            return;\n        }\n\n        public function onAuthenticationFailure(Request $request, AuthenticationException $exception)\n        {\n            $data = array(\n                'message' => strtr($exception->getMessageKey(), $exception->getMessageData()),\n\n                // or to translate this message\n                // $this->translator->trans($exception->getMessageKey(), $exception->getMessageData())\n            );\n\n            return new JsonResponse($data, 403);\n        }\n\n        /**\n         * Called when authentication is needed, but it's not sent\n         */\n        public function start(Request $request, AuthenticationException $authException = null)\n        {\n            $data = array(\n                // you might translate this message\n                'message' => 'Authentication Required',\n            );\n\n            return new JsonResponse($data, 401);\n        }\n\n        public function supportsRememberMe()\n        {\n            return false;\n        }\n    }\n\n\nStep 2) Configure the Authenticator\n-----------------------------------\n\nTo finish this, register the class as a service:\n\n.. code-block:: php\n\n    $app['app.token_authenticator'] = function ($app) {\n        return new App\\Security\\TokenAuthenticator($app['security.encoder_factory']);\n    };\n\n\nFinally, configure your `security.firewalls` key to use this authenticator:\n\n.. code-block:: php\n\n    $app['security.firewalls'] => array(\n        'main' => array(\n            'guard' => array(\n                'authenticators' => array(\n                    'app.token_authenticator'\n                ),\n\n                // Using more than 1 authenticator, you must specify\n                // which one is used as entry point.\n                // 'entry_point' => 'app.token_authenticator',\n            ),\n            // configure where your users come from. Hardcode them, or load them from somewhere\n            // http://silex.sensiolabs.org/doc/providers/security.html#defining-a-custom-user-provider\n            'users' => array(\n                'victoria' => array('ROLE_USER', 'randomsecret'),\n            ),\n            // 'anonymous' => true\n        ),\n    );\n\n.. note::\n    You can use many authenticators, they are executed by the order\n    they are configured.\n\nYou did it! You now have a fully-working API token authentication\nsystem. If your homepage required ROLE_USER, then you could test it\nunder different conditions:\n\n.. code-block:: bash\n\n    # test with no token\n    curl http://localhost:8000/\n    # {\"message\":\"Authentication Required\"}\n\n    # test with a bad token\n    curl -H \"X-AUTH-TOKEN: alan\" http://localhost:8000/\n    # {\"message\":\"Username could not be found.\"}\n\n    # test with a working token\n    curl -H \"X-AUTH-TOKEN: victoria:randomsecret\" http://localhost:8000/\n    # the homepage controller is executed: the page loads normally\n\nFor more details read the Symfony cookbook entry on\n`How to Create a Custom Authentication System with Guard <http://symfony.com/doc/current/cookbook/security/guard-authentication.html>`_.\n"
  },
  {
    "path": "doc/cookbook/index.rst",
    "content": "Cookbook\n========\n\nThe cookbook section contains recipes for solving specific problems.\n\n.. toctree::\n    :maxdepth: 1\n    :hidden:\n\n    json_request_body\n    session_storage\n    form_no_csrf\n    validator_yaml\n    sub_requests\n    error_handler\n    multiple_loggers\n    guard_authentication\n\nRecipes\n-------\n\n* :doc:`Accepting a JSON Request Body <json_request_body>` A common need when\n  building a restful API is the ability to accept a JSON encoded entity from\n  the request body.\n\n* :doc:`Using PdoSessionStorage to store Sessions in the Database\n  <session_storage>`.\n\n* :doc:`Disabling the CSRF Protection on a Form using the FormExtension\n  <form_no_csrf>`.\n\n* :doc:`Using YAML to configure Validation <validator_yaml>`.\n\n* :doc:`Making sub-Requests <sub_requests>`.\n\n* :doc:`Converting Errors to Exceptions <error_handler>`.\n\n* :doc:`Using multiple Monolog Loggers <multiple_loggers>`.\n\n* :doc:`How to Create a Custom Authentication System with Guard <guard_authentication>`.\n"
  },
  {
    "path": "doc/cookbook/json_request_body.rst",
    "content": "Accepting a JSON Request Body\n=============================\n\nA common need when building a restful API is the ability to accept a JSON\nencoded entity from the request body.\n\nAn example for such an API could be a blog post creation.\n\nExample API\n-----------\n\nIn this example we will create an API for creating a blog post. The following\nis a spec of how we want it to work.\n\nRequest\n~~~~~~~\n\nIn the request we send the data for the blog post as a JSON object. We also\nindicate that using the ``Content-Type`` header:\n\n.. code-block:: text\n\n    POST /blog/posts\n    Accept: application/json\n    Content-Type: application/json\n    Content-Length: 57\n\n    {\"title\":\"Hello World!\",\"body\":\"This is my first post!\"}\n\nResponse\n~~~~~~~~\n\nThe server responds with a 201 status code, telling us that the post was\ncreated. It tells us the ``Content-Type`` of the response, which is also\nJSON:\n\n.. code-block:: text\n\n    HTTP/1.1 201 Created\n    Content-Type: application/json\n    Content-Length: 65\n    Connection: close\n\n    {\"id\":\"1\",\"title\":\"Hello World!\",\"body\":\"This is my first post!\"}\n\nParsing the request body\n------------------------\n\nThe request body should only be parsed as JSON if the ``Content-Type`` header\nbegins with ``application/json``. Since we want to do this for every request,\nthe easiest solution is to use an application before middleware.\n\nWe simply use ``json_decode`` to parse the content of the request and then\nreplace the request data on the ``$request`` object::\n\n    use Symfony\\Component\\HttpFoundation\\Request;\n    use Symfony\\Component\\HttpFoundation\\ParameterBag;\n\n    $app->before(function (Request $request) {\n        if (0 === strpos($request->headers->get('Content-Type'), 'application/json')) {\n            $data = json_decode($request->getContent(), true);\n            $request->request->replace(is_array($data) ? $data : array());\n        }\n    });\n\nController implementation\n-------------------------\n\nOur controller will create a new blog post from the data provided and will\nreturn the post object, including its ``id``, as JSON::\n\n    use Symfony\\Component\\HttpFoundation\\Request;\n    use Symfony\\Component\\HttpFoundation\\Response;\n\n    $app->post('/blog/posts', function (Request $request) use ($app) {\n        $post = array(\n            'title' => $request->request->get('title'),\n            'body'  => $request->request->get('body'),\n        );\n\n        $post['id'] = createPost($post);\n\n        return $app->json($post, 201);\n    });\n\nManual testing\n--------------\n\nIn order to manually test our API, we can use the ``curl`` command line\nutility, which allows sending HTTP requests:\n\n.. code-block:: bash\n\n    $ curl http://blog.lo/blog/posts -d '{\"title\":\"Hello World!\",\"body\":\"This is my first post!\"}' -H 'Content-Type: application/json'\n    {\"id\":\"1\",\"title\":\"Hello World!\",\"body\":\"This is my first post!\"}\n"
  },
  {
    "path": "doc/cookbook/multiple_loggers.rst",
    "content": "Using multiple Monolog Loggers\n==============================\n\nHaving separate instances of Monolog for different parts of your system is\noften desirable and allows you to configure them independently, allowing for fine\ngrained control of where your logging goes and in what detail.\n\nThis simple example allows you to quickly configure several monolog instances,\nusing the bundled handler, but each with a different channel. \n\n.. code-block:: php\n\n    $app['monolog.factory'] = $app->protect(function ($name) use ($app) {\n        $log = new $app['monolog.logger.class']($name);\n        $log->pushHandler($app['monolog.handler']);\n\n        return $log;\n    });\n\n    foreach (array('auth', 'payments', 'stats') as $channel) {\n        $app['monolog.'.$channel] = function ($app) use ($channel) {\n            return $app['monolog.factory']($channel);\n        };\n    }\n\nAs your application grows, or your logging needs for certain areas of the\nsystem become apparent, it should be straightforward to then configure that\nparticular service separately, including your customizations.\n\n.. code-block:: php\n\n    use Monolog\\Handler\\StreamHandler;\n\n    $app['monolog.payments'] = function ($app) {\n        $log = new $app['monolog.logger.class']('payments');\n        $handler = new StreamHandler($app['monolog.payments.logfile'], $app['monolog.payment.level']);\n        $log->pushHandler($handler);\n\n        return $log;\n    };\n\nAlternatively, you could attempt to make the factory more complicated, and rely\non some conventions, such as checking for an array of handlers registered with\nthe container with the channel name, defaulting to the bundled handler.\n\n.. code-block:: php\n\n    use Monolog\\Handler\\StreamHandler;\n    use Monolog\\Logger;\n\n    $app['monolog.factory'] = $app->protect(function ($name) use ($app) {\n        $log = new $app['monolog.logger.class']($name);\n\n        $handlers = isset($app['monolog.'.$name.'.handlers'])\n            ? $app['monolog.'.$name.'.handlers']\n            : array($app['monolog.handler']);\n\n        foreach ($handlers as $handler) {\n            $log->pushHandler($handler);\n        }\n\n        return $log;\n    });\n\n    $app['monolog.payments.handlers'] = function ($app) {\n        return array(\n            new StreamHandler(__DIR__.'/../payments.log', Logger::DEBUG),\n        );\n    };\n"
  },
  {
    "path": "doc/cookbook/session_storage.rst",
    "content": "Using PdoSessionStorage to store Sessions in the Database\n=========================================================\n\nBy default, the :doc:`SessionServiceProvider </providers/session>` writes\nsession information in files using Symfony NativeFileSessionStorage. Most\nmedium to large websites use a database to store sessions instead of files,\nbecause databases are easier to use and scale in a multi-webserver environment.\n\nSymfony's `NativeSessionStorage\n<http://api.symfony.com/master/Symfony/Component/HttpFoundation/Session/Storage/NativeSessionStorage.html>`_\nhas multiple storage handlers and one of them uses PDO to store sessions,\n`PdoSessionHandler\n<http://api.symfony.com/master/Symfony/Component/HttpFoundation/Session/Storage/Handler/PdoSessionHandler.html>`_.\nTo use it, replace the ``session.storage.handler`` service in your application\nlike explained below.\n\nWith a dedicated PDO service\n----------------------------\n\n.. code-block:: php\n\n    use Symfony\\Component\\HttpFoundation\\Session\\Storage\\Handler\\PdoSessionHandler;\n\n    $app->register(new Silex\\Provider\\SessionServiceProvider());\n\n    $app['pdo.dsn'] = 'mysql:dbname=mydatabase';\n    $app['pdo.user'] = 'myuser';\n    $app['pdo.password'] = 'mypassword';\n\n    $app['session.db_options'] = array(\n        'db_table'      => 'session',\n        'db_id_col'     => 'session_id',\n        'db_data_col'   => 'session_value',\n        'db_time_col'   => 'session_time',\n    );\n\n    $app['pdo'] = function () use ($app) {\n        return new PDO(\n            $app['pdo.dsn'],\n            $app['pdo.user'],\n            $app['pdo.password']\n        );\n    };\n\n    $app['session.storage.handler'] = function () use ($app) {\n        return new PdoSessionHandler(\n            $app['pdo'],\n            $app['session.db_options'],\n            $app['session.storage.options']\n        );\n    };\n\nUsing the DoctrineServiceProvider\n---------------------------------\n\nWhen using the :doc:`DoctrineServiceProvider </providers/doctrine>` You don't\nhave to make another database connection, simply pass the getWrappedConnection method.\n\n.. code-block:: php\n\n    use Symfony\\Component\\HttpFoundation\\Session\\Storage\\Handler\\PdoSessionHandler;\n\n    $app->register(new Silex\\Provider\\SessionServiceProvider());\n\n    $app['session.db_options'] = array(\n        'db_table'        => 'session',\n        'db_id_col'       => 'session_id',\n        'db_data_col'     => 'session_value',\n        'db_lifetime_col' => 'session_lifetime',\n        'db_time_col'     => 'session_time',\n    );\n\n    $app['session.storage.handler'] = function () use ($app) {\n        return new PdoSessionHandler(\n            $app['db']->getWrappedConnection(),\n            $app['session.db_options'],\n            $app['session.storage.options']\n        );\n    };\n\nDatabase structure\n------------------\n\nPdoSessionStorage needs a database table with 3 columns:\n\n* ``session_id``: ID column (VARCHAR(255) or larger)\n* ``session_value``: Value column (TEXT or CLOB)\n* ``session_lifetime``: Lifetime column (INTEGER)\n* ``session_time``: Time column (INTEGER)\n\nYou can find examples of SQL statements to create the session table in the\n`Symfony cookbook\n<http://symfony.com/doc/current/cookbook/configuration/pdo_session_storage.html#example-sql-statements>`_\n"
  },
  {
    "path": "doc/cookbook/sub_requests.rst",
    "content": "Making sub-Requests\n===================\n\nSince Silex is based on the ``HttpKernelInterface``, it allows you to simulate\nrequests against your application. This means that you can embed a page within\nanother, it also allows you to forward a request which is essentially an\ninternal redirect that does not change the URL.\n\nBasics\n------\n\nYou can make a sub-request by calling the ``handle`` method on the\n``Application``. This method takes three arguments:\n\n* ``$request``: An instance of the ``Request`` class which represents the\n   HTTP request.\n\n* ``$type``: Must be either ``HttpKernelInterface::MASTER_REQUEST`` or\n  ``HttpKernelInterface::SUB_REQUEST``. Certain listeners are only executed for\n  the master request, so it's important that this is set to ``SUB_REQUEST``.\n\n* ``$catch``: Catches exceptions and turns them into a response with status code\n  ``500``. This argument defaults to ``true``. For sub-requests you will most\n  likely want to set it to ``false``.\n\nBy calling ``handle``, you can make a sub-request manually. Here's an example::\n\n    use Symfony\\Component\\HttpFoundation\\Request;\n    use Symfony\\Component\\HttpKernel\\HttpKernelInterface;\n\n    $subRequest = Request::create('/');\n    $response = $app->handle($subRequest, HttpKernelInterface::SUB_REQUEST, false);\n\nThere's some more things that you need to keep in mind though. In most cases\nyou will want to forward some parts of the current master request to the\nsub-request like cookies, server information, or the session.\n\nHere is a more advanced example that forwards said information (``$request``\nholds the master request)::\n\n    use Symfony\\Component\\HttpFoundation\\Request;\n    use Symfony\\Component\\HttpKernel\\HttpKernelInterface;\n\n    $subRequest = Request::create('/', 'GET', array(), $request->cookies->all(), array(), $request->server->all());\n    if ($request->getSession()) {\n        $subRequest->setSession($request->getSession());\n    }\n\n    $response = $app->handle($subRequest, HttpKernelInterface::SUB_REQUEST, false);\n\nTo forward this response to the client, you can simply return it from a\ncontroller::\n\n    use Silex\\Application;\n    use Symfony\\Component\\HttpFoundation\\Request;\n    use Symfony\\Component\\HttpKernel\\HttpKernelInterface;\n\n    $app->get('/foo', function (Application $app, Request $request) {\n        $subRequest = Request::create('/', ...);\n        $response = $app->handle($subRequest, HttpKernelInterface::SUB_REQUEST, false);\n\n        return $response;\n    });\n\nIf you want to embed the response as part of a larger page you can call\n``Response::getContent``::\n\n    $header = ...;\n    $footer = ...;\n    $body = $response->getContent();\n\n    return $header.$body.$footer;\n\nRendering pages in Twig templates\n---------------------------------\n\nThe :doc:`TwigServiceProvider </providers/twig>` provides a ``render``\nfunction that you can use in Twig templates. It gives you a convenient way to\nembed pages.\n\n.. code-block:: jinja\n\n    {{ render('/sidebar') }}\n\nFor details, refer to the :doc:`TwigServiceProvider </providers/twig>` docs.\n\nEdge Side Includes\n------------------\n\nYou can use ESI either through the :doc:`HttpCacheServiceProvider\n</providers/http_cache>` or a reverse proxy cache such as Varnish. This also\nallows you to embed pages, however it also gives you the benefit of caching\nparts of the page.\n\nHere is an example of how you would embed a page via ESI:\n\n.. code-block:: jinja\n\n    <esi:include src=\"/sidebar\" />\n\nFor details, refer to the :doc:`HttpCacheServiceProvider\n</providers/http_cache>` docs.\n\nDealing with the request base URL\n---------------------------------\n\nOne thing to watch out for is the base URL. If your application is not\nhosted at the webroot of your web server, then you may have an URL like\n``http://example.org/foo/index.php/articles/42``.\n\nIn this case, ``/foo/index.php`` is your request base path. Silex accounts for\nthis path prefix in the routing process, it reads it from\n``$request->server``. In the context of sub-requests this can lead to issues,\nbecause if you do not prepend the base path the request could mistake a part\nof the path you want to match as the base path and cut it off.\n\nYou can prevent that from happening by always prepending the base path when\nconstructing a request::\n\n    $url = $request->getUriForPath('/');\n    $subRequest = Request::create($url, 'GET', array(), $request->cookies->all(), array(), $request->server->all());\n\nThis is something to be aware of when making sub-requests by hand.\n\nServices depending on the Request\n---------------------------------\n\nThe container is a concept that is global to a Silex application, since the\napplication object **is** the container. Any request that is run against an\napplication will re-use the same set of services. Since these services are\nmutable, code in a master request can affect the sub-requests and vice versa.\nAny services depending on the ``request`` service will store the first request\nthat they get (could be master or sub-request), and keep using it, even if\nthat request is already over.\n\nInstead of injecting the ``request`` service, you should always inject the\n``request_stack`` one instead.\n"
  },
  {
    "path": "doc/cookbook/validator_yaml.rst",
    "content": "Using YAML to configure Validation\n==================================\n\nSimplicity is at the heart of Silex so there is no out of the box solution to\nuse YAML files for validation. But this doesn't mean that this is not\npossible. Let's see how to do it.\n\nFirst, you need to install the YAML Component:\n\n.. code-block:: bash\n\n    composer require symfony/yaml\n\nNext, you need to tell the Validation Service that you are not using\n``StaticMethodLoader`` to load your class metadata but a YAML file::\n\n    $app->register(new ValidatorServiceProvider());\n\n    $app['validator.mapping.class_metadata_factory'] = new Symfony\\Component\\Validator\\Mapping\\ClassMetadataFactory(\n        new Symfony\\Component\\Validator\\Mapping\\Loader\\YamlFileLoader(__DIR__.'/validation.yml')\n    );\n\nNow, we can replace the usage of the static method and move all the validation\nrules to ``validation.yml``:\n\n.. code-block:: yaml\n\n    # validation.yml\n    Post:\n      properties:\n        title:\n          - NotNull: ~\n          - NotBlank: ~\n        body:\n          - Min: 100\n"
  },
  {
    "path": "doc/index.rst",
    "content": "The Book\n========\n\n.. toctree::\n    :maxdepth: 1\n\n    intro\n    usage\n    middlewares\n    organizing_controllers\n    services\n    providers\n    testing\n    cookbook/index\n    internals\n    contributing\n    providers/index\n    web_servers\n    changelog\n"
  },
  {
    "path": "doc/internals.rst",
    "content": "Internals\n=========\n\nThis chapter will tell you how Silex works internally.\n\nSilex\n-----\n\nApplication\n~~~~~~~~~~~\n\nThe application is the main interface to Silex. It implements Symfony's\n`HttpKernelInterface\n<http://api.symfony.com/master/Symfony/Component/HttpKernel/HttpKernelInterface.html>`_,\nso you can pass a `Request\n<http://api.symfony.com/master/Symfony/Component/HttpFoundation/Request.html>`_\nto the ``handle`` method and it will return a `Response\n<http://api.symfony.com/master/Symfony/Component/HttpFoundation/Response.html>`_.\n\nIt extends the ``Pimple`` service container, allowing for flexibility on the\noutside as well as the inside. You could replace any service, and you are also\nable to read them.\n\nThe application makes strong use of the `EventDispatcher\n<http://api.symfony.com/master/Symfony/Component/EventDispatcher/EventDispatcher\n.html>`_ to hook into the Symfony `HttpKernel\n<http://api.symfony.com/master/Symfony/Component/HttpKernel/HttpKernel.html>`_\nevents. This allows fetching the ``Request``, converting string responses into\n``Response`` objects and handling Exceptions. We also use it to dispatch some\ncustom events like before/after middlewares and errors.\n\nController\n~~~~~~~~~~\n\nThe Symfony `Route\n<http://api.symfony.com/master/Symfony/Component/Routing/Route.html>`_ is\nactually quite powerful. Routes can be named, which allows for URL generation.\nThey can also have requirements for the variable parts. In order to allow\nsetting these through a nice interface, the ``match`` method (which is used by\n``get``, ``post``, etc.) returns an instance of the ``Controller``, which\nwraps a route.\n\nControllerCollection\n~~~~~~~~~~~~~~~~~~~~\n\nOne of the goals of exposing the `RouteCollection\n<http://api.symfony.com/master/Symfony/Component/Routing/RouteCollection.html>`_\nwas to make it mutable, so providers could add stuff to it. The challenge here\nis the fact that routes know nothing about their name. The name only has\nmeaning in context of the ``RouteCollection`` and cannot be changed.\n\nTo solve this challenge we came up with a staging area for routes. The\n``ControllerCollection`` holds the controllers until ``flush`` is called, at\nwhich point the routes are added to the ``RouteCollection``. Also, the\ncontrollers are then frozen. This means that they can no longer be modified\nand will throw an Exception if you try to do so.\n\nUnfortunately no good way for flushing implicitly could be found, which is why\nflushing is now always explicit. The Application will flush, but if you want\nto read the ``ControllerCollection`` before the request takes place, you will\nhave to call flush yourself.\n\nThe ``Application`` provides a shortcut ``flush`` method for flushing the\n``ControllerCollection``.\n\n.. tip::\n\n    Instead of creating an instance of ``RouteCollection`` yourself, use the\n    ``$app['controllers_factory']`` factory instead.\n\nSymfony\n-------\n\nFollowing Symfony components are used by Silex:\n\n* **HttpFoundation**: For ``Request`` and ``Response``.\n\n* **HttpKernel**: Because we need a heart.\n\n* **Routing**: For matching defined routes.\n\n* **EventDispatcher**: For hooking into the HttpKernel.\n\nFor more information, `check out the Symfony website <http://symfony.com/>`_.\n"
  },
  {
    "path": "doc/intro.rst",
    "content": "Introduction\n============\n\nSilex is a PHP microframework. It is built on the shoulders of `Symfony`_ and\n`Pimple`_ and also inspired by `Sinatra`_.\n\nSilex aims to be:\n\n* *Concise*: Silex exposes an intuitive and concise API.\n\n* *Extensible*: Silex has an extension system based around the Pimple\n  service-container that makes it easy to tie in third party libraries.\n\n* *Testable*: Silex uses Symfony's HttpKernel which abstracts request and\n  response. This makes it very easy to test apps and the framework itself. It\n  also respects the HTTP specification and encourages its proper use.\n\nIn a nutshell, you define controllers and map them to routes, all in one step.\n\nUsage\n-----\n\n.. code-block:: php\n\n    <?php\n\n    // web/index.php\n    require_once __DIR__.'/../vendor/autoload.php';\n\n    $app = new Silex\\Application();\n\n    $app->get('/hello/{name}', function ($name) use ($app) {\n        return 'Hello '.$app->escape($name);\n    });\n\n    $app->run();\n\nAll that is needed to get access to the Framework is to include the\nautoloader.\n\nNext, a route for ``/hello/{name}`` that matches for ``GET`` requests is\ndefined. When the route matches, the function is executed and the return value\nis sent back to the client.\n\nFinally, the app is run. Visit ``/hello/world`` to see the result. It's really\nthat easy!\n\n.. _Symfony: http://symfony.com/\n.. _Pimple: http://pimple.sensiolabs.org/\n.. _Sinatra: http://www.sinatrarb.com/\n"
  },
  {
    "path": "doc/middlewares.rst",
    "content": "Middleware\n==========\n\nSilex allows you to run code, that changes the default Silex behavior, at\ndifferent stages during the handling of a request through *middleware*:\n\n* *Application middleware* is triggered independently of the current handled\n  request;\n\n* *Route middleware* is triggered when its associated route is matched.\n\nApplication Middleware\n----------------------\n\nApplication middleware is only run for the \"master\" Request.\n\nBefore Middleware\n~~~~~~~~~~~~~~~~~\n\nA *before* application middleware allows you to tweak the Request before the\ncontroller is executed::\n\n    $app->before(function (Request $request, Application $app) {\n        // ...\n    });\n\nBy default, the middleware is run after the routing and the security.\n\nIf you want your middleware to be run even if an exception is thrown early on\n(on a 404 or 403 error for instance), then, you need to register it as an\nearly event::\n\n    $app->before(function (Request $request, Application $app) {\n        // ...\n    }, Application::EARLY_EVENT);\n\nIn this case, the routing and the security won't have been executed, and so you\nwon't have access to the locale, the current route, or the security user.\n\n.. note::\n\n    The before middleware is an event registered on the Symfony *request*\n    event.\n\nAfter Middleware\n~~~~~~~~~~~~~~~~\n\nAn *after* application middleware allows you to tweak the Response before it\nis sent to the client::\n\n    $app->after(function (Request $request, Response $response) {\n        // ...\n    });\n\n.. note::\n\n    The after middleware is an event registered on the Symfony *response*\n    event.\n\nFinish Middleware\n~~~~~~~~~~~~~~~~~\n\nA *finish* application middleware allows you to execute tasks after the\nResponse has been sent to the client (like sending emails or logging)::\n\n    $app->finish(function (Request $request, Response $response) {\n        // ...\n        // Warning: modifications to the Request or Response will be ignored\n    });\n\n.. note::\n\n    The finish middleware is an event registered on the Symfony *terminate*\n    event.\n\nRoute Middleware\n----------------\n\nRoute middleware is added to routes or route collections and it is only\ntriggered when the corresponding route is matched. You can also stack them::\n\n    $app->get('/somewhere', function () {\n        // ...\n    })\n    ->before($before1)\n    ->before($before2)\n    ->after($after1)\n    ->after($after2)\n    ;\n\nBefore Middleware\n~~~~~~~~~~~~~~~~~\n\nA *before* route middleware is fired just before the route callback, but after\nthe *before* application middleware::\n\n    $before = function (Request $request, Application $app) {\n        // ...\n    };\n\n    $app->get('/somewhere', function () {\n        // ...\n    })\n    ->before($before);\n\nAfter Middleware\n~~~~~~~~~~~~~~~~\n\nAn *after* route middleware is fired just after the route callback, but before\nthe application *after* application middleware::\n\n    $after = function (Request $request, Response $response, Application $app) {\n        // ...\n    };\n\n    $app->get('/somewhere', function () {\n        // ...\n    })\n    ->after($after);\n\nMiddleware Priority\n-------------------\n\nYou can add as much middleware as you want, in which case they are triggered\nin the same order as you added them.\n\nYou can explicitly control the priority of your middleware by passing an\nadditional argument to the registration methods::\n\n    $app->before(function (Request $request) {\n        // ...\n    }, 32);\n\nAs a convenience, two constants allow you to register an event as early as\npossible or as late as possible::\n\n    $app->before(function (Request $request) {\n        // ...\n    }, Application::EARLY_EVENT);\n\n    $app->before(function (Request $request) {\n        // ...\n    }, Application::LATE_EVENT);\n\nShort-circuiting the Controller\n-------------------------------\n\nIf a *before* middleware returns a ``Response`` object, the request handling is\nshort-circuited (the next middleware won't be run, nor the route\ncallback), and the Response is passed to the *after* middleware right away::\n\n    $app->before(function (Request $request) {\n        // redirect the user to the login screen if access to the Resource is protected\n        if (...) {\n            return new RedirectResponse('/login');\n        }\n    });\n\n.. note::\n\n    A ``RuntimeException`` is thrown if a before middleware does not return a\n    Response or ``null``.\n"
  },
  {
    "path": "doc/organizing_controllers.rst",
    "content": "Organizing Controllers\n======================\n\nWhen your application starts to define too many controllers, you might want to\ngroup them logically::\n\n    // define controllers for a blog\n    $blog = $app['controllers_factory'];\n    $blog->get('/', function () {\n        return 'Blog home page';\n    });\n    // ...\n\n    // define controllers for a forum\n    $forum = $app['controllers_factory'];\n    $forum->get('/', function () {\n        return 'Forum home page';\n    });\n\n    // define \"global\" controllers\n    $app->get('/', function () {\n        return 'Main home page';\n    });\n\n    $app->mount('/blog', $blog);\n    $app->mount('/forum', $forum);\n\n    // define controllers for a admin\n    $app->mount('/admin', function ($admin) {\n        // recursively mount\n        $admin->mount('/blog', function ($user) {\n            $user->get('/', function () {\n                return 'Admin Blog home page';\n            });\n        });\n    });\n\n.. note::\n\n    ``$app['controllers_factory']`` is a factory that returns a new instance\n    of ``ControllerCollection`` when used.\n\n``mount()`` prefixes all routes with the given prefix and merges them into the\nmain Application. So, ``/`` will map to the main home page, ``/blog/`` to the\nblog home page, ``/forum/`` to the forum home page, and ``/admin/blog/`` to the\nadmin blog home page.\n\n.. caution::\n\n    When mounting a route collection under ``/blog``, it is not possible to\n    define a route for the ``/blog`` URL. The shortest possible URL is\n    ``/blog/``.\n\n.. note::\n\n    When calling ``get()``, ``match()``, or any other HTTP methods on the\n    Application, you are in fact calling them on a default instance of\n    ``ControllerCollection`` (stored in ``$app['controllers']``).\n\nAnother benefit is the ability to apply settings on a set of controllers very\neasily. Building on the example from the middleware section, here is how you\nwould secure all controllers for the backend collection::\n\n    $backend = $app['controllers_factory'];\n\n    // ensure that all controllers require logged-in users\n    $backend->before($mustBeLogged);\n\n.. tip::\n\n    For a better readability, you can split each controller collection into a\n    separate file::\n\n        // blog.php\n        $blog = $app['controllers_factory'];\n        $blog->get('/', function () { return 'Blog home page'; });\n\n        return $blog;\n\n        // app.php\n        $app->mount('/blog', include 'blog.php');\n\n    Instead of requiring a file, you can also create a :ref:`Controller\n    provider <controller-providers>`.\n"
  },
  {
    "path": "doc/providers/asset.rst",
    "content": "Asset\n=====\n\nThe *AssetServiceProvider* provides a way to manage URL generation and\nversioning of web assets such as CSS stylesheets, JavaScript files and image\nfiles.\n\nParameters\n----------\n\n* **assets.version**: Default version for assets.\n\n* **assets.format_version** (optional): Default format for assets.\n\n* **assets.named_packages** (optional): Named packages. Keys are the package\n  names and values the configuration (supported keys are ``version``,\n  ``version_format``, ``base_urls``, and ``base_path``).\n\nServices\n--------\n\n* **assets.packages**: The asset service.\n\nRegistering\n-----------\n\n.. code-block:: php\n\n    $app->register(new Silex\\Provider\\AssetServiceProvider(), array(\n        'assets.version' => 'v1',\n        'assets.version_format' => '%s?version=%s',\n        'assets.named_packages' => array(\n            'css' => array('version' => 'css2', 'base_path' => '/whatever-makes-sense'),\n            'images' => array('base_urls' => array('https://img.example.com')),\n        ),\n    ));\n\n.. note::\n\n    Add the Symfony Asset Component as a dependency:\n\n    .. code-block:: bash\n\n        composer require symfony/asset\n\nUsage\n-----\n\nThe AssetServiceProvider is mostly useful with the Twig provider:\n\n.. code-block:: jinja\n\n    {{ asset('/css/foo.png') }}\n    {{ asset('/css/foo.css', 'css') }}\n    {{ asset('/img/foo.png', 'images') }}\n\n    {{ asset_version('/css/foo.png') }}\n\nFor more information, check out the `Asset Component documentation\n<https://symfony.com/doc/current/components/asset/introduction.html>`_.\n"
  },
  {
    "path": "doc/providers/csrf.rst",
    "content": "CSRF\n====\n\nThe *CsrfServiceProvider* provides a service for building forms in your\napplication with the Symfony Form component.\n\nParameters\n----------\n\n* none\n\nServices\n--------\n\n* **csrf.token_manager**: An instance of an implementation of the\n  `CsrfProviderInterface\n  <http://api.symfony.com/master/Symfony/Component/Form/Extension/Csrf/CsrfProvider/CsrfProviderInterface.html>`_,\n  defaults to a `DefaultCsrfProvider\n  <http://api.symfony.com/master/Symfony/Component/Form/Extension/Csrf/CsrfProvider/DefaultCsrfProvider.html>`_.\n\nRegistering\n-----------\n\n.. code-block:: php\n\n    use Silex\\Provider\\CsrfServiceProvider;\n\n    $app->register(new CsrfServiceProvider());\n\n.. note::\n\n    Add the Symfony's `Security CSRF Component\n    <http://symfony.com/doc/current/components/security/index.html>`_ as a\n    dependency:\n\n    .. code-block:: bash\n\n        composer require symfony/security-csrf\n\nUsage\n-----\n\nWhen the CSRF Service Provider is registered, all forms created via the Form\nService Provider are protected against CSRF by default.\n\nYou can also use the CSRF protection even without using the Symfony Form\ncomponent. If, for example, you're doing a DELETE action, you can check the\nCSRF token::\n\n    use Symfony\\Component\\Security\\Csrf\\CsrfToken;\n\n    $app['csrf.token_manager']->isTokenValid(new CsrfToken('token_id', 'TOKEN'));\n"
  },
  {
    "path": "doc/providers/doctrine.rst",
    "content": "Doctrine\n========\n\nThe *DoctrineServiceProvider* provides integration with the `Doctrine DBAL\n<http://www.doctrine-project.org/projects/dbal>`_ for easy database access\n(Doctrine ORM integration is **not** supplied).\n\nParameters\n----------\n\n* **db.options**: Array of Doctrine DBAL options.\n\n  These options are available:\n\n  * **driver**: The database driver to use, defaults to ``pdo_mysql``.\n    Can be any of: ``pdo_mysql``, ``pdo_sqlite``, ``pdo_pgsql``,\n    ``pdo_oci``, ``oci8``, ``ibm_db2``, ``pdo_ibm``, ``pdo_sqlsrv``.\n\n  * **dbname**: The name of the database to connect to.\n\n  * **host**: The host of the database to connect to. Defaults to\n    localhost.\n\n  * **user**: The user of the database to connect to. Defaults to\n    root.\n\n  * **password**: The password of the database to connect to.\n\n  * **charset**: Only relevant for ``pdo_mysql``, and ``pdo_oci/oci8``,\n    specifies the charset used when connecting to the database.\n\n  * **path**: Only relevant for ``pdo_sqlite``, specifies the path to\n    the SQLite database.\n\n  * **port**: Only relevant for ``pdo_mysql``, ``pdo_pgsql``, and ``pdo_oci/oci8``,\n    specifies the port of the database to connect to.\n\n  These and additional options are described in detail in the `Doctrine DBAL\n  configuration documentation <http://docs.doctrine-project.org/projects/doctrine-dbal/en/latest/reference/configuration.html>`_.\n\nServices\n--------\n\n* **db**: The database connection, instance of\n  ``Doctrine\\DBAL\\Connection``.\n\n* **db.config**: Configuration object for Doctrine. Defaults to\n  an empty ``Doctrine\\DBAL\\Configuration``.\n\n* **db.event_manager**: Event Manager for Doctrine.\n\nRegistering\n-----------\n\n.. code-block:: php\n\n    $app->register(new Silex\\Provider\\DoctrineServiceProvider(), array(\n        'db.options' => array(\n            'driver'   => 'pdo_sqlite',\n            'path'     => __DIR__.'/app.db',\n        ),\n    ));\n\n.. note::\n\n    Add the Doctrine DBAL as a dependency:\n\n    .. code-block:: bash\n\n        composer require \"doctrine/dbal:~2.2\"\n\nUsage\n-----\n\nThe Doctrine provider provides a ``db`` service. Here is a usage\nexample::\n\n    $app->get('/blog/{id}', function ($id) use ($app) {\n        $sql = \"SELECT * FROM posts WHERE id = ?\";\n        $post = $app['db']->fetchAssoc($sql, array((int) $id));\n\n        return  \"<h1>{$post['title']}</h1>\".\n                \"<p>{$post['body']}</p>\";\n    });\n\nUsing multiple databases\n------------------------\n\nThe Doctrine provider can allow access to multiple databases. In order to\nconfigure the data sources, replace the **db.options** with **dbs.options**.\n**dbs.options** is an array of configurations where keys are connection names\nand values are options::\n\n    $app->register(new Silex\\Provider\\DoctrineServiceProvider(), array(\n        'dbs.options' => array (\n            'mysql_read' => array(\n                'driver'    => 'pdo_mysql',\n                'host'      => 'mysql_read.someplace.tld',\n                'dbname'    => 'my_database',\n                'user'      => 'my_username',\n                'password'  => 'my_password',\n                'charset'   => 'utf8mb4',\n            ),\n            'mysql_write' => array(\n                'driver'    => 'pdo_mysql',\n                'host'      => 'mysql_write.someplace.tld',\n                'dbname'    => 'my_database',\n                'user'      => 'my_username',\n                'password'  => 'my_password',\n                'charset'   => 'utf8mb4',\n            ),\n        ),\n    ));\n\nThe first registered connection is the default and can simply be accessed as\nyou would if there was only one connection. Given the above configuration,\nthese two lines are equivalent::\n\n    $app['db']->fetchAll('SELECT * FROM table');\n\n    $app['dbs']['mysql_read']->fetchAll('SELECT * FROM table');\n\nUsing multiple connections::\n\n    $app->get('/blog/{id}', function ($id) use ($app) {\n        $sql = \"SELECT * FROM posts WHERE id = ?\";\n        $post = $app['dbs']['mysql_read']->fetchAssoc($sql, array((int) $id));\n\n        $sql = \"UPDATE posts SET value = ? WHERE id = ?\";\n        $app['dbs']['mysql_write']->executeUpdate($sql, array('newValue', (int) $id));\n\n        return  \"<h1>{$post['title']}</h1>\".\n                \"<p>{$post['body']}</p>\";\n    });\n\nFor more information, consult the `Doctrine DBAL documentation\n<http://docs.doctrine-project.org/projects/doctrine-dbal/en/latest/>`_.\n"
  },
  {
    "path": "doc/providers/form.rst",
    "content": "Form\n====\n\nThe *FormServiceProvider* provides a service for building forms in\nyour application with the Symfony Form component.\n\nParameters\n----------\n\n* none\n\nServices\n--------\n\n* **form.factory**: An instance of `FormFactory\n  <http://api.symfony.com/master/Symfony/Component/Form/FormFactory.html>`_,\n  that is used to build a form.\n\nRegistering\n-----------\n\n.. code-block:: php\n\n    use Silex\\Provider\\FormServiceProvider;\n\n    $app->register(new FormServiceProvider());\n\n.. note::\n\n    If you don't want to create your own form layout, it's fine: a default one\n    will be used. But you will have to register the :doc:`translation provider\n    <translation>` as the default form layout requires it::\n\n        $app->register(new Silex\\Provider\\TranslationServiceProvider(), array(\n            'translator.domains' => array(),\n        ));\n\n    If you want to use validation with forms, do not forget to register the\n    :doc:`Validator provider <validator>`.\n\n.. note::\n\n    Add the Symfony Form Component as a dependency:\n\n    .. code-block:: bash\n\n        composer require symfony/form\n\n    If you are going to use the validation extension with forms, you must also\n    add a dependency to the ``symfony/config`` and ``symfony/translation``\n    components:\n\n    .. code-block:: bash\n\n        composer require symfony/validator symfony/config symfony/translation\n\n    If you want to use forms in your Twig templates, you can also install the\n    Symfony Twig Bridge. Make sure to install, if you didn't do that already,\n    the Translation component in order for the bridge to work:\n\n    .. code-block:: bash\n\n        composer require symfony/twig-bridge symfony/translation\n\nUsage\n-----\n\nThe FormServiceProvider provides a ``form.factory`` service. Here is a usage\nexample::\n\n    use Symfony\\Component\\Form\\Extension\\Core\\Type\\FormType;\n    use Symfony\\Component\\Form\\Extension\\Core\\Type\\ChoiceType;\n\n    $app->match('/form', function (Request $request) use ($app) {\n        // some default data for when the form is displayed the first time\n        $data = array(\n            'name' => 'Your name',\n            'email' => 'Your email',\n        );\n\n        $form = $app['form.factory']->createBuilder(FormType::class, $data)\n            ->add('name')\n            ->add('email')\n            ->add('billing_plan', ChoiceType::class, array(\n                'choices' => array(1 => 'free', 2 => 'small_business', 3 => 'corporate'),\n                'expanded' => true,\n            ))\n            ->getForm();\n\n        $form->handleRequest($request);\n\n        if ($form->isValid()) {\n            $data = $form->getData();\n\n            // do something with the data\n\n            // redirect somewhere\n            return $app->redirect('...');\n        }\n\n        // display the form\n        return $app['twig']->render('index.twig', array('form' => $form->createView()));\n    });\n\nAnd here is the ``index.twig`` form template (requires ``symfony/twig-bridge``):\n\n.. code-block:: jinja\n\n    <form action=\"#\" method=\"post\">\n        {{ form_widget(form) }}\n\n        <input type=\"submit\" name=\"submit\" />\n    </form>\n\nIf you are using the validator provider, you can also add validation to your\nform by adding constraints on the fields::\n\n    use Symfony\\Component\\Form\\Extension\\Core\\Type\\FormType;\n    use Symfony\\Component\\Form\\Extension\\Core\\Type\\TextType;\n    use Symfony\\Component\\Form\\Extension\\Core\\Type\\ChoiceType;\n    use Symfony\\Component\\Validator\\Constraints as Assert;\n\n    $app->register(new Silex\\Provider\\ValidatorServiceProvider());\n    $app->register(new Silex\\Provider\\TranslationServiceProvider(), array(\n        'translator.domains' => array(),\n    ));\n\n    $form = $app['form.factory']->createBuilder(FormType::class)\n        ->add('name', TextType::class, array(\n            'constraints' => array(new Assert\\NotBlank(), new Assert\\Length(array('min' => 5)))\n        ))\n        ->add('email', TextType::class, array(\n            'constraints' => new Assert\\Email()\n        ))\n        ->add('billing_plan', ChoiceType::class, array(\n            'choices' => array(1 => 'free', 2 => 'small_business', 3 => 'corporate'),\n            'expanded' => true,\n            'constraints' => new Assert\\Choice(array(1, 2, 3)),\n        ))\n        ->getForm();\n\nYou can register form types by extending ``form.types``::\n\n    $app['your.type.service'] = function ($app) {\n        return new YourServiceFormType();\n    };\n    $app->extend('form.types', function ($types) use ($app) {\n        $types[] = new YourFormType();\n        $types[] = 'your.type.service';\n\n        return $types;\n    }));\n\nYou can register form extensions by extending ``form.extensions``::\n\n    $app->extend('form.extensions', function ($extensions) use ($app) {\n        $extensions[] = new YourTopFormExtension();\n\n        return $extensions;\n    });\n\n\nYou can register form type extensions by extending ``form.type.extensions``::\n\n    $app['your.type.extension.service'] = function ($app) {\n        return new YourServiceFormTypeExtension();\n    };\n    $app->extend('form.type.extensions', function ($extensions) use ($app) {\n        $extensions[] = new YourFormTypeExtension();\n        $extensions[] = 'your.type.extension.service';\n\n        return $extensions;\n    });\n\nYou can register form type guessers by extending ``form.type.guessers``::\n\n    $app['your.type.guesser.service'] = function ($app) {\n        return new YourServiceFormTypeGuesser();\n    };\n    $app->extend('form.type.guessers', function ($guessers) use ($app) {\n        $guessers[] = new YourFormTypeGuesser();\n        $guessers[] = 'your.type.guesser.service';\n\n        return $guessers;\n    });\n\n.. warning::\n\n    CSRF protection is only available and automatically enabled when the\n    :doc:`CSRF Service Provider </providers/csrf>` is registered.\n\nTraits\n------\n\n``Silex\\Application\\FormTrait`` adds the following shortcuts:\n\n* **form**: Creates a FormBuilder instance.\n\n.. code-block:: php\n\n    $app->form($data);\n\nFor more information, consult the `Symfony Forms documentation\n<http://symfony.com/doc/2.8/book/forms.html>`_.\n"
  },
  {
    "path": "doc/providers/http_cache.rst",
    "content": "HTTP Cache\n==========\n\nThe *HttpCacheServiceProvider* provides support for the Symfony Reverse\nProxy.\n\nParameters\n----------\n\n* **http_cache.cache_dir**: The cache directory to store the HTTP cache data.\n\n* **http_cache.options** (optional): An array of options for the `HttpCache\n  <http://api.symfony.com/master/Symfony/Component/HttpKernel/HttpCache/HttpCache.html>`_\n  constructor.\n\nServices\n--------\n\n* **http_cache**: An instance of `HttpCache\n  <http://api.symfony.com/master/Symfony/Component/HttpKernel/HttpCache/HttpCache.html>`_.\n\n* **http_cache.esi**: An instance of `Esi\n  <http://api.symfony.com/master/Symfony/Component/HttpKernel/HttpCache/Esi.html>`_,\n  that implements the ESI capabilities to Request and Response instances.\n\n* **http_cache.store**: An instance of `Store\n  <http://api.symfony.com/master/Symfony/Component/HttpKernel/HttpCache/Store.html>`_,\n  that implements all the logic for storing cache metadata (Request and Response\n  headers).\n\nRegistering\n-----------\n\n.. code-block:: php\n\n    $app->register(new Silex\\Provider\\HttpCacheServiceProvider(), array(\n        'http_cache.cache_dir' => __DIR__.'/cache/',\n    ));\n\nUsage\n-----\n\nSilex already supports any reverse proxy like Varnish out of the box by\nsetting Response HTTP cache headers::\n\n    use Symfony\\Component\\HttpFoundation\\Response;\n\n    $app->get('/', function() {\n        return new Response('Foo', 200, array(\n            'Cache-Control' => 's-maxage=5',\n        ));\n    });\n\n.. tip::\n\n    If you want Silex to trust the ``X-Forwarded-For*`` headers from your\n    reverse proxy at address $ip, you will need to whitelist it as documented\n    in `Trusting Proxies\n    <http://symfony.com/doc/current/components/http_foundation/trusting_proxies.html>`_.\n\n    If you would be running Varnish in front of your application on the same machine::\n\n        use Symfony\\Component\\HttpFoundation\\Request;\n        \n        Request::setTrustedProxies(array('127.0.0.1', '::1'));\n        $app->run();\n\nThis provider allows you to use the Symfony reverse proxy natively with\nSilex applications by using the ``http_cache`` service. The Symfony reverse proxy\nacts much like any other proxy would, so you will want to whitelist it::\n\n    use Symfony\\Component\\HttpFoundation\\Request;\n        \n    Request::setTrustedProxies(array('127.0.0.1'));\n    $app['http_cache']->run();\n\nThe provider also provides ESI support::\n\n    $app->get('/', function() {\n        $response = new Response(<<<EOF\n    <html>\n        <body>\n            Hello\n            <esi:include src=\"/included\" />\n        </body>\n    </html>\n\n    EOF\n        , 200, array(\n            'Surrogate-Control' => 'content=\"ESI/1.0\"',\n        ));\n\n        $response->setTtl(20);\n\n        return $response;\n    });\n\n    $app->get('/included', function() {\n        $response = new Response('Foo');\n        $response->setTtl(5);\n\n        return $response;\n    });\n\n    $app['http_cache']->run();\n\nIf your application doesn't use ESI, you can disable it to slightly improve the\noverall performance::\n\n    $app->register(new Silex\\Provider\\HttpCacheServiceProvider(), array(\n       'http_cache.cache_dir' => __DIR__.'/cache/',\n       'http_cache.esi'       => null,\n    ));\n\n.. tip::\n\n    To help you debug caching issues, set your application ``debug`` to true.\n    Symfony automatically adds a ``X-Symfony-Cache`` header to each response\n    with useful information about cache hits and misses.\n\n    If you are *not* using the Symfony Session provider, you might want to set\n    the PHP ``session.cache_limiter`` setting to an empty value to avoid the\n    default PHP behavior.\n\n    Finally, check that your Web server does not override your caching strategy.\n\nFor more information, consult the `Symfony HTTP Cache documentation\n<http://symfony.com/doc/current/book/http_cache.html>`_.\n"
  },
  {
    "path": "doc/providers/http_fragment.rst",
    "content": "HTTP Fragment\n=============\n\nThe *HttpFragmentServiceProvider* provides support for the Symfony fragment\nsub-framework, which allows you to embed fragments of HTML in a template.\n\nParameters\n----------\n\n* **fragment.path**: The path to use for the URL generated for ESI and\n  HInclude URLs (``/_fragment`` by default).\n\n* **uri_signer.secret**: The secret to use for the URI signer service (used\n  for the HInclude renderer).\n\n* **fragment.renderers.hinclude.global_template**: The content or Twig\n  template to use for the default content when using the HInclude renderer.\n\nServices\n--------\n\n* **fragment.handler**: An instance of `FragmentHandler\n  <http://api.symfony.com/master/Symfony/Component/HttpKernel/Fragment/FragmentHandler.html>`_.\n\n* **fragment.renderers**: An array of fragment renderers (by default, the\n  inline, ESI, and HInclude renderers are pre-configured).\n\nRegistering\n-----------\n\n.. code-block:: php\n\n    $app->register(new Silex\\Provider\\HttpFragmentServiceProvider());\n\nUsage\n-----\n\n.. note::\n\n    This section assumes that you are using Twig for your templates.\n\nInstead of building a page out of a single request/controller/template, the\nfragment framework allows you to build a page from several\ncontrollers/sub-requests/sub-templates by using **fragments**.\n\nIncluding \"sub-pages\" in the main page can be done with the Twig ``render()``\nfunction:\n\n.. code-block:: jinja\n\n    The main page content.\n\n    {{ render('/foo') }}\n\n    The main page content resumes here.\n\nThe ``render()`` call is replaced by the content of the ``/foo`` URL\n(internally, a sub-request is handled by Silex to render the sub-page).\n\nInstead of making internal sub-requests, you can also use the ESI (the\nsub-request is handled by a reverse proxy) or the HInclude strategies (the\nsub-request is handled by a web browser):\n\n.. code-block:: jinja\n\n    {{ render(url('route_name')) }}\n\n    {{ render_esi(url('route_name')) }}\n\n    {{ render_hinclude(url('route_name')) }}\n"
  },
  {
    "path": "doc/providers/index.rst",
    "content": "Built-in Service Providers\n==========================\n\n.. toctree::\n    :maxdepth: 1\n\n    twig\n    asset\n    monolog\n    session\n    swiftmailer\n    locale\n    translation\n    validator\n    form\n    csrf\n    http_cache\n    http_fragment\n    security\n    remember_me\n    serializer\n    service_controller\n    var_dumper\n    doctrine\n"
  },
  {
    "path": "doc/providers/locale.rst",
    "content": "Locale\n======\n\nThe *LocaleServiceProvider* manages the locale of an application.\n\nParameters\n----------\n\n* **locale**: The locale of the user. When set before any request handling, it\n  defines the default locale (``en`` by default). When a request is being\n  handled, it is automatically set according to the ``_locale`` request\n  attribute of the current route.\n\nServices\n--------\n\n* n/a\n\nRegistering\n-----------\n\n.. code-block:: php\n\n    $app->register(new Silex\\Provider\\LocaleServiceProvider());\n"
  },
  {
    "path": "doc/providers/monolog.rst",
    "content": "Monolog\n=======\n\nThe *MonologServiceProvider* provides a default logging mechanism through\nJordi Boggiano's `Monolog <https://github.com/Seldaek/monolog>`_ library.\n\nIt will log requests and errors and allow you to add logging to your\napplication. This allows you to debug and monitor the behaviour,\neven in production.\n\nParameters\n----------\n\n* **monolog.logfile**: File where logs are written to.\n* **monolog.bubble**: (optional) Whether the messages that are handled can bubble up the stack or not.\n* **monolog.permission**: (optional) File permissions default (null), nothing change.\n\n* **monolog.level** (optional): Level of logging, defaults\n  to ``DEBUG``. Must be one of ``Logger::DEBUG``, ``Logger::INFO``,\n  ``Logger::WARNING``, ``Logger::ERROR``. ``DEBUG`` will log\n  everything, ``INFO`` will log everything except ``DEBUG``,\n  etc.\n\n  In addition to the ``Logger::`` constants, it is also possible to supply the\n  level in string form, for example: ``\"DEBUG\"``, ``\"INFO\"``, ``\"WARNING\"``,\n  ``\"ERROR\"``.\n\n* **monolog.name** (optional): Name of the monolog channel,\n  defaults to ``myapp``.\n\n* **monolog.exception.logger_filter** (optional): An anonymous function that\n  filters which exceptions should be logged.\n\n* **monolog.use_error_handler** (optional): Whether errors and uncaught exceptions\n  should be handled by the Monolog ``ErrorHandler`` class and added to the log.\n  By default the error handler is enabled unless the application ``debug`` parameter\n  is set to true.\n\n  Please note that enabling the error handler may silence some errors,\n  ignoring the PHP ``display_errors`` configuration setting.\n\nServices\n--------\n\n* **monolog**: The monolog logger instance.\n\n  Example usage::\n\n    $app['monolog']->addDebug('Testing the Monolog logging.');\n\n* **monolog.listener**: An event listener to log requests, responses and errors.\n\nRegistering\n-----------\n\n.. code-block:: php\n\n    $app->register(new Silex\\Provider\\MonologServiceProvider(), array(\n        'monolog.logfile' => __DIR__.'/development.log',\n    ));\n\n.. note::\n\n    Add Monolog as a dependency:\n\n    .. code-block:: bash\n\n        composer require monolog/monolog\n\nUsage\n-----\n\nThe MonologServiceProvider provides a ``monolog`` service. You can use it to\nadd log entries for any logging level through ``addDebug()``, ``addInfo()``,\n``addWarning()`` and ``addError()``::\n\n    use Symfony\\Component\\HttpFoundation\\Response;\n\n    $app->post('/user', function () use ($app) {\n        // ...\n\n        $app['monolog']->addInfo(sprintf(\"User '%s' registered.\", $username));\n\n        return new Response('', 201);\n    });\n\nCustomization\n-------------\n\nYou can configure Monolog (like adding or changing the handlers) before using\nit by extending the ``monolog`` service::\n\n    $app->extend('monolog', function($monolog, $app) {\n        $monolog->pushHandler(...);\n\n        return $monolog;\n    });\n\nBy default, all requests, responses and errors are logged by an event listener\nregistered as a service called `monolog.listener`. You can replace or remove\nthis service if you want to modify or disable the logged information.\n\nTraits\n------\n\n``Silex\\Application\\MonologTrait`` adds the following shortcuts:\n\n* **log**: Logs a message.\n\n.. code-block:: php\n\n    $app->log(sprintf(\"User '%s' registered.\", $username));\n\nFor more information, check out the `Monolog documentation\n<https://github.com/Seldaek/monolog>`_.\n"
  },
  {
    "path": "doc/providers/remember_me.rst",
    "content": "Remember Me\n===========\n\nThe *RememberMeServiceProvider* adds \"Remember-Me\" authentication to the\n*SecurityServiceProvider*.\n\nParameters\n----------\n\nn/a\n\nServices\n--------\n\nn/a\n\n.. note::\n\n    The service provider defines many other services that are used internally\n    but rarely need to be customized.\n\nRegistering\n-----------\n\nBefore registering this service provider, you must register the\n*SecurityServiceProvider*::\n\n    $app->register(new Silex\\Provider\\SecurityServiceProvider());\n    $app->register(new Silex\\Provider\\RememberMeServiceProvider());\n\n    $app['security.firewalls'] = array(\n        'my-firewall' => array(\n            'pattern'     => '^/secure$',\n            'form'        => true,\n            'logout'      => true,\n            'remember_me' => array(\n                'key'                => 'Choose_A_Unique_Random_Key',\n                'always_remember_me' => true,\n                /* Other options */\n            ),\n            'users' => array( /* ... */ ),\n        ),\n    );\n\nOptions\n-------\n\n* **key**: A secret key to generate tokens (you should generate a random\n  string).\n\n* **name**: Cookie name (default: ``REMEMBERME``).\n\n* **lifetime**: Cookie lifetime (default: ``31536000`` ~ 1 year).\n\n* **path**: Cookie path (default: ``/``).\n\n* **domain**: Cookie domain (default: ``null`` = request domain).\n\n* **secure**: Cookie is secure (default: ``false``).\n\n* **httponly**: Cookie is HTTP only (default: ``true``).\n\n* **always_remember_me**: Enable remember me (default: ``false``).\n\n* **remember_me_parameter**: Name of the request parameter enabling remember_me\n  on login. To add the checkbox to the login form. You can find more\n  information in the `Symfony cookbook\n  <http://symfony.com/doc/current/cookbook/security/remember_me.html>`_\n  (default: ``_remember_me``).\n"
  },
  {
    "path": "doc/providers/security.rst",
    "content": "Security\n========\n\nThe *SecurityServiceProvider* manages authentication and authorization for\nyour applications.\n\nParameters\n----------\n\n* **security.hide_user_not_found** (optional): Defines whether to hide user not\n  found exception or not. Defaults to ``true``.\n\n* **security.encoder.bcrypt.cost** (optional): Defines BCrypt password encoder cost. Defaults to 13.\n\nServices\n--------\n\n* **security.token_storage**: Gives access to the user token.\n\n* **security.authorization_checker**: Allows to check authorizations for the\n  users.\n\n* **security.authentication_manager**: An instance of\n  `AuthenticationProviderManager\n  <http://api.symfony.com/master/Symfony/Component/Security/Core/Authentication/AuthenticationProviderManager.html>`_,\n  responsible for authentication.\n\n* **security.access_manager**: An instance of `AccessDecisionManager\n  <http://api.symfony.com/master/Symfony/Component/Security/Core/Authorization/AccessDecisionManager.html>`_,\n  responsible for authorization.\n\n* **security.session_strategy**: Define the session strategy used for\n  authentication (default to a migration strategy).\n\n* **security.user_checker**: Checks user flags after authentication.\n\n* **security.last_error**: Returns the last authentication errors when given a\n  Request object.\n\n* **security.encoder_factory**: Defines the encoding strategies for user\n  passwords (uses ``security.default_encoder``).\n\n* **security.default_encoder**: The encoder to use by default for all users (BCrypt).\n\n* **security.encoder.digest**: Digest password encoder.\n\n* **security.encoder.bcrypt**: BCrypt password encoder.\n\n* **security.encoder.pbkdf2**: Pbkdf2 password encoder.\n\n* **user**: Returns the current user\n\n.. note::\n\n    The service provider defines many other services that are used internally\n    but rarely need to be customized.\n\nRegistering\n-----------\n\n.. code-block:: php\n\n    $app->register(new Silex\\Provider\\SecurityServiceProvider(), array(\n        'security.firewalls' => // see below\n    ));\n\n.. note::\n\n    Add the Symfony Security Component as a dependency:\n\n    .. code-block:: bash\n\n        composer require symfony/security\n\n.. caution::\n\n    If you're using a form to authenticate users, you need to enable\n    ``SessionServiceProvider``.\n\n.. caution::\n\n    The security features are only available after the Application has been\n    booted. So, if you want to use it outside of the handling of a request,\n    don't forget to call ``boot()`` first::\n\n        $app->boot();\n\nUsage\n-----\n\nThe Symfony Security component is powerful. To learn more about it, read the\n`Symfony Security documentation\n<http://symfony.com/doc/2.8/book/security.html>`_.\n\n.. tip::\n\n    When a security configuration does not behave as expected, enable logging\n    (with the Monolog extension for instance) as the Security Component logs a\n    lot of interesting information about what it does and why.\n\nBelow is a list of recipes that cover some common use cases.\n\nAccessing the current User\n~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nThe current user information is stored in a token that is accessible via the\n``security`` service::\n\n    $token = $app['security.token_storage']->getToken();\n\nIf there is no information about the user, the token is ``null``. If the user\nis known, you can get it with a call to ``getUser()``::\n\n    if (null !== $token) {\n        $user = $token->getUser();\n    }\n\nThe user can be a string, an object with a ``__toString()`` method, or an\ninstance of `UserInterface\n<http://api.symfony.com/master/Symfony/Component/Security/Core/User/UserInterface.html>`_.\n\nSecuring a Path with HTTP Authentication\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nThe following configuration uses HTTP basic authentication to secure URLs\nunder ``/admin/``::\n\n    $app['security.firewalls'] = array(\n        'admin' => array(\n            'pattern' => '^/admin',\n            'http' => true,\n            'users' => array(\n                // raw password is foo\n                'admin' => array('ROLE_ADMIN', '$2y$10$3i9/lVd8UOFIJ6PAMFt8gu3/r5g0qeCJvoSlLCsvMTythye19F77a'),\n            ),\n        ),\n    );\n\nThe ``pattern`` is a regular expression on the URL path; the ``http`` setting\ntells the security layer to use HTTP basic authentication and the ``users``\nentry defines valid users.\n\nIf you want to restrict the firewall by more than the URL pattern (like the\nHTTP method, the client IP, the hostname, or any Request attributes), use an\ninstance of a `RequestMatcher\n<http://api.symfony.com/master/Symfony/Component/HttpFoundation/RequestMatcher.html>`_\nfor the ``pattern`` option::\n\n    use Symfony/Component/HttpFoundation/RequestMatcher;\n\n    $app['security.firewalls'] = array(\n        'admin' => array(\n            'pattern' => new RequestMatcher('^/admin', 'example.com', 'POST'),\n            // ...\n        ),\n    );\n\nEach user is defined with the following information:\n\n* The role or an array of roles for the user (roles are strings beginning with\n  ``ROLE_`` and ending with anything you want);\n\n* The user encoded password.\n\n.. caution::\n\n    All users must at least have one role associated with them.\n\nThe default configuration of the extension enforces encoded passwords. To\ngenerate a valid encoded password from a raw password, use the\n``security.encoder_factory`` service::\n\n    // find the encoder for a UserInterface instance\n    $encoder = $app['security.encoder_factory']->getEncoder($user);\n\n    // compute the encoded password for foo\n    $password = $encoder->encodePassword('foo', $user->getSalt());\n\nWhen the user is authenticated, the user stored in the token is an instance of\n`User\n<http://api.symfony.com/master/Symfony/Component/Security/Core/User/User.html>`_\n\n.. caution::\n\n    If you are using php-cgi under Apache, you need to add this configuration\n    to make things work correctly:\n\n    .. code-block:: apache\n\n        RewriteEngine On\n        RewriteCond %{HTTP:Authorization} ^(.+)$\n        RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]\n        RewriteCond %{REQUEST_FILENAME} !-f\n        RewriteRule ^(.*)$ app.php [QSA,L]\n\nSecuring a Path with a Form\n~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nUsing a form to authenticate users is very similar to the above configuration.\nInstead of using the ``http`` setting, use the ``form`` one and define these\ntwo parameters:\n\n* **login_path**: The login path where the user is redirected when they are\n  accessing a secured area without being authenticated so that they can enter\n  their credentials;\n\n* **check_path**: The check URL used by Symfony to validate the credentials of\n  the user.\n\nHere is how to secure all URLs under ``/admin/`` with a form::\n\n    $app['security.firewalls'] = array(\n        'admin' => array(\n            'pattern' => '^/admin/',\n            'form' => array('login_path' => '/login', 'check_path' => '/admin/login_check'),\n            'users' => array(\n                'admin' => array('ROLE_ADMIN', '$2y$10$3i9/lVd8UOFIJ6PAMFt8gu3/r5g0qeCJvoSlLCsvMTythye19F77a'),\n            ),\n        ),\n    );\n\nAlways keep in mind the following two golden rules:\n\n* The ``login_path`` path must always be defined **outside** the secured area\n  (or if it is in the secured area, the ``anonymous`` authentication mechanism\n  must be enabled -- see below);\n\n* The ``check_path`` path must always be defined **inside** the secured area.\n\nFor the login form to work, create a controller like the following::\n\n    use Symfony\\Component\\HttpFoundation\\Request;\n\n    $app->get('/login', function(Request $request) use ($app) {\n        return $app['twig']->render('login.html', array(\n            'error'         => $app['security.last_error']($request),\n            'last_username' => $app['session']->get('_security.last_username'),\n        ));\n    });\n\nThe ``error`` and ``last_username`` variables contain the last authentication\nerror and the last username entered by the user in case of an authentication\nerror.\n\nCreate the associated template:\n\n.. code-block:: jinja\n\n    <form action=\"{{ path('admin_login_check') }}\" method=\"post\">\n        {{ error }}\n        <input type=\"text\" name=\"_username\" value=\"{{ last_username }}\" />\n        <input type=\"password\" name=\"_password\" value=\"\" />\n        <input type=\"submit\" />\n    </form>\n\n.. note::\n\n    The ``admin_login_check`` route is automatically defined by Silex and its\n    name is derived from the ``check_path`` value (all ``/`` are replaced with\n    ``_`` and the leading ``/`` is stripped).\n\nDefining more than one Firewall\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nYou are not limited to define one firewall per project.\n\nConfiguring several firewalls is useful when you want to secure different\nparts of your website with different authentication strategies or for\ndifferent users (like using an HTTP basic authentication for the website API\nand a form to secure your website administration area).\n\nIt's also useful when you want to secure all URLs except the login form::\n\n    $app['security.firewalls'] = array(\n        'login' => array(\n            'pattern' => '^/login$',\n        ),\n        'secured' => array(\n            'pattern' => '^.*$',\n            'form' => array('login_path' => '/login', 'check_path' => '/login_check'),\n            'users' => array(\n                'admin' => array('ROLE_ADMIN', '$2y$10$3i9/lVd8UOFIJ6PAMFt8gu3/r5g0qeCJvoSlLCsvMTythye19F77a'),\n            ),\n        ),\n    );\n\nThe order of the firewall configurations is significant as the first one to\nmatch wins. The above configuration first ensures that the ``/login`` URL is\nnot secured (no authentication settings), and then it secures all other URLs.\n\n.. tip::\n\n    You can toggle all registered authentication mechanisms for a particular\n    area on and off with the ``security`` flag::\n\n        $app['security.firewalls'] = array(\n            'api' => array(\n                'pattern' => '^/api',\n                'security' => $app['debug'] ? false : true,\n                'wsse' => true,\n\n                // ...\n            ),\n        );\n\nAdding a Logout\n~~~~~~~~~~~~~~~\n\nWhen using a form for authentication, you can let users log out if you add the\n``logout`` setting, where ``logout_path`` must match the main firewall\npattern::\n\n    $app['security.firewalls'] = array(\n        'secured' => array(\n            'pattern' => '^/admin/',\n            'form' => array('login_path' => '/login', 'check_path' => '/admin/login_check'),\n            'logout' => array('logout_path' => '/admin/logout', 'invalidate_session' => true),\n\n            // ...\n        ),\n    );\n\nA route is automatically generated, based on the configured path (all ``/``\nare replaced with ``_`` and the leading ``/`` is stripped):\n\n.. code-block:: jinja\n\n    <a href=\"{{ path('admin_logout') }}\">Logout</a>\n\nAllowing Anonymous Users\n~~~~~~~~~~~~~~~~~~~~~~~~\n\nWhen securing only some parts of your website, the user information are not\navailable in non-secured areas. To make the user accessible in such areas,\nenabled the ``anonymous`` authentication mechanism::\n\n    $app['security.firewalls'] = array(\n        'unsecured' => array(\n            'anonymous' => true,\n\n            // ...\n        ),\n    );\n\nWhen enabling the anonymous setting, a user will always be accessible from the\nsecurity context; if the user is not authenticated, it returns the ``anon.``\nstring.\n\nChecking User Roles\n~~~~~~~~~~~~~~~~~~~\n\nTo check if a user is granted some role, use the ``isGranted()`` method on the\nsecurity context::\n\n    if ($app['security.authorization_checker']->isGranted('ROLE_ADMIN')) {\n        // ...\n    }\n\nYou can check roles in Twig templates too:\n\n.. code-block:: jinja\n\n    {% if is_granted('ROLE_ADMIN') %}\n        <a href=\"/secured?_switch_user=fabien\">Switch to Fabien</a>\n    {% endif %}\n\nYou can check if a user is \"fully authenticated\" (not an anonymous user for\ninstance) with the special ``IS_AUTHENTICATED_FULLY`` role:\n\n.. code-block:: jinja\n\n    {% if is_granted('IS_AUTHENTICATED_FULLY') %}\n        <a href=\"{{ path('logout') }}\">Logout</a>\n    {% else %}\n        <a href=\"{{ path('login') }}\">Login</a>\n    {% endif %}\n\nOf course you will need to define a ``login`` route for this to work.\n\n.. tip::\n\n    Don't use the ``getRoles()`` method to check user roles.\n\n.. caution::\n\n    ``isGranted()`` throws an exception when no authentication information is\n    available (which is the case on non-secured area).\n\nImpersonating a User\n~~~~~~~~~~~~~~~~~~~~\n\nIf you want to be able to switch to another user (without knowing the user\ncredentials), enable the ``switch_user`` authentication strategy::\n\n    $app['security.firewalls'] = array(\n        'unsecured' => array(\n            'switch_user' => array('parameter' => '_switch_user', 'role' => 'ROLE_ALLOWED_TO_SWITCH'),\n\n            // ...\n        ),\n    );\n\nSwitching to another user is now a matter of adding the ``_switch_user`` query\nparameter to any URL when logged in as a user who has the\n``ROLE_ALLOWED_TO_SWITCH`` role:\n\n.. code-block:: jinja\n\n    {% if is_granted('ROLE_ALLOWED_TO_SWITCH') %}\n        <a href=\"?_switch_user=fabien\">Switch to user Fabien</a>\n    {% endif %}\n\nYou can check that you are impersonating a user by checking the special\n``ROLE_PREVIOUS_ADMIN``. This is useful for instance to allow the user to\nswitch back to their primary account:\n\n.. code-block:: jinja\n\n    {% if is_granted('ROLE_PREVIOUS_ADMIN') %}\n        You are an admin but you've switched to another user,\n        <a href=\"?_switch_user=_exit\"> exit</a> the switch.\n    {% endif %}\n\nDefining a Role Hierarchy\n~~~~~~~~~~~~~~~~~~~~~~~~~\n\nDefining a role hierarchy allows to automatically grant users some additional\nroles::\n\n    $app['security.role_hierarchy'] = array(\n        'ROLE_ADMIN' => array('ROLE_USER', 'ROLE_ALLOWED_TO_SWITCH'),\n    );\n\nWith this configuration, all users with the ``ROLE_ADMIN`` role also\nautomatically have the ``ROLE_USER`` and ``ROLE_ALLOWED_TO_SWITCH`` roles.\n\nDefining Access Rules\n~~~~~~~~~~~~~~~~~~~~~\n\nRoles are a great way to adapt the behavior of your website depending on\ngroups of users, but they can also be used to further secure some areas by\ndefining access rules::\n\n    $app['security.access_rules'] = array(\n        array('^/admin', 'ROLE_ADMIN', 'https'),\n        array('^.*$', 'ROLE_USER'),\n    );\n\nWith the above configuration, users must have the ``ROLE_ADMIN`` to access the\n``/admin`` section of the website, and ``ROLE_USER`` for everything else.\nFurthermore, the admin section can only be accessible via HTTPS (if that's not\nthe case, the user will be automatically redirected).\n\n.. note::\n\n    The first argument can also be a `RequestMatcher\n    <http://api.symfony.com/master/Symfony/Component/HttpFoundation/RequestMatcher.html>`_\n    instance.\n\nDefining a custom User Provider\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nUsing an array of users is simple and useful when securing an admin section of\na personal website, but you can override this default mechanism with you own.\n\nThe ``users`` setting can be defined as a service that returns an instance of\n`UserProviderInterface\n<http://api.symfony.com/master/Symfony/Component/Security/Core/User/UserProviderInterface.html>`_::\n\n    'users' => function () use ($app) {\n        return new UserProvider($app['db']);\n    },\n\nHere is a simple example of a user provider, where Doctrine DBAL is used to\nstore the users::\n\n    use Symfony\\Component\\Security\\Core\\User\\UserProviderInterface;\n    use Symfony\\Component\\Security\\Core\\User\\UserInterface;\n    use Symfony\\Component\\Security\\Core\\User\\User;\n    use Symfony\\Component\\Security\\Core\\Exception\\UnsupportedUserException;\n    use Symfony\\Component\\Security\\Core\\Exception\\UsernameNotFoundException;\n    use Doctrine\\DBAL\\Connection;\n\n    class UserProvider implements UserProviderInterface\n    {\n        private $conn;\n\n        public function __construct(Connection $conn)\n        {\n            $this->conn = $conn;\n        }\n\n        public function loadUserByUsername($username)\n        {\n            $stmt = $this->conn->executeQuery('SELECT * FROM users WHERE username = ?', array(strtolower($username)));\n\n            if (!$user = $stmt->fetch()) {\n                throw new UsernameNotFoundException(sprintf('Username \"%s\" does not exist.', $username));\n            }\n\n            return new User($user['username'], $user['password'], explode(',', $user['roles']), true, true, true, true);\n        }\n\n        public function refreshUser(UserInterface $user)\n        {\n            if (!$user instanceof User) {\n                throw new UnsupportedUserException(sprintf('Instances of \"%s\" are not supported.', get_class($user)));\n            }\n\n            return $this->loadUserByUsername($user->getUsername());\n        }\n\n        public function supportsClass($class)\n        {\n            return $class === 'Symfony\\Component\\Security\\Core\\User\\User';\n        }\n    }\n\nIn this example, instances of the default ``User`` class are created for the\nusers, but you can define your own class; the only requirement is that the\nclass must implement `UserInterface\n<http://api.symfony.com/master/Symfony/Component/Security/Core/User/UserInterface.html>`_\n\nAnd here is the code that you can use to create the database schema and some\nsample users::\n\n    use Doctrine\\DBAL\\Schema\\Table;\n\n    $schema = $app['db']->getSchemaManager();\n    if (!$schema->tablesExist('users')) {\n        $users = new Table('users');\n        $users->addColumn('id', 'integer', array('unsigned' => true, 'autoincrement' => true));\n        $users->setPrimaryKey(array('id'));\n        $users->addColumn('username', 'string', array('length' => 32));\n        $users->addUniqueIndex(array('username'));\n        $users->addColumn('password', 'string', array('length' => 255));\n        $users->addColumn('roles', 'string', array('length' => 255));\n\n        $schema->createTable($users);\n\n        $app['db']->insert('users', array(\n          'username' => 'fabien',\n          'password' => '$2y$10$3i9/lVd8UOFIJ6PAMFt8gu3/r5g0qeCJvoSlLCsvMTythye19F77a',\n          'roles' => 'ROLE_USER'\n        ));\n\n        $app['db']->insert('users', array(\n          'username' => 'admin',\n          'password' => '$2y$10$3i9/lVd8UOFIJ6PAMFt8gu3/r5g0qeCJvoSlLCsvMTythye19F77a',\n          'roles' => 'ROLE_ADMIN'\n        ));\n    }\n\n.. tip::\n\n    If you are using the Doctrine ORM, the Symfony bridge for Doctrine\n    provides a user provider class that is able to load users from your\n    entities.\n\nDefining a custom Encoder\n~~~~~~~~~~~~~~~~~~~~~~~~~\n\nBy default, Silex uses the ``BCrypt`` algorithm to encode passwords.\nAdditionally, the password is encoded multiple times.\nYou can change these defaults by overriding ``security.default_encoder``\nservice to return one of the predefined encoders:\n\n* **security.encoder.digest**: Digest password encoder.\n\n* **security.encoder.bcrypt**: BCrypt password encoder.\n\n* **security.encoder.pbkdf2**: Pbkdf2 password encoder.\n\n.. code-block:: php\n\n    $app['security.default_encoder'] = function ($app) {\n        return $app['security.encoder.pbkdf2'];\n    };\n\nOr you can define you own, fully customizable encoder::\n\n    use Symfony\\Component\\Security\\Core\\Encoder\\PlaintextPasswordEncoder;\n\n    $app['security.default_encoder'] = function ($app) {\n        // Plain text (e.g. for debugging)\n        return new PlaintextPasswordEncoder();\n    };\n\n.. tip::\n\n    You can change the default BCrypt encoding cost by overriding ``security.encoder.bcrypt.cost``\n\nDefining a custom Authentication Provider\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nThe Symfony Security component provides a lot of ready-to-use authentication\nproviders (form, HTTP, X509, remember me, ...), but you can add new ones\neasily. To register a new authentication provider, create a service named\n``security.authentication_listener.factory.XXX`` where ``XXX`` is the name you want to\nuse in your configuration::\n\n    $app['security.authentication_listener.factory.wsse'] = $app->protect(function ($name, $options) use ($app) {\n        // define the authentication provider object\n        $app['security.authentication_provider.'.$name.'.wsse'] = function () use ($app) {\n            return new WsseProvider($app['security.user_provider.default'], __DIR__.'/security_cache');\n        };\n\n        // define the authentication listener object\n        $app['security.authentication_listener.'.$name.'.wsse'] = function () use ($app) {\n            return new WsseListener($app['security.token_storage'], $app['security.authentication_manager']);\n        };\n\n        return array(\n            // the authentication provider id\n            'security.authentication_provider.'.$name.'.wsse',\n            // the authentication listener id\n            'security.authentication_listener.'.$name.'.wsse',\n            // the entry point id\n            null,\n            // the position of the listener in the stack\n            'pre_auth'\n        );\n    });\n\nYou can now use it in your configuration like any other built-in\nauthentication provider::\n\n    $app->register(new Silex\\Provider\\SecurityServiceProvider(), array(\n        'security.firewalls' => array(\n            'default' => array(\n                'wsse' => true,\n\n                // ...\n            ),\n        ),\n    ));\n\nInstead of ``true``, you can also define an array of options that customize\nthe behavior of your authentication factory; it will be passed as the second\nargument of your authentication factory (see above).\n\nThis example uses the authentication provider classes as described in the\nSymfony `cookbook`_.\n\n\n.. note::\n\n    The Guard component simplifies the creation of custom authentication\n    providers. :doc:`How to Create a Custom Authentication System with Guard\n    </cookbook/guard_authentication>`\n\nStateless Authentication\n~~~~~~~~~~~~~~~~~~~~~~~~\n\nBy default, a session cookie is created to persist the security context of\nthe user. However, if you use certificates, HTTP authentication, WSSE and so\non, the credentials are sent for each request. In that case, you can turn off\npersistence by activating the ``stateless`` authentication flag::\n\n    $app['security.firewalls'] = array(\n        'default' => array(\n            'stateless' => true,\n            'wsse' => true,\n\n            // ...\n        ),\n    );\n\nTraits\n------\n\n``Silex\\Application\\SecurityTrait`` adds the following shortcuts:\n\n* **encodePassword**: Encode a given password.\n\n.. code-block:: php\n\n    $user = $app->user();\n\n    $encoded = $app->encodePassword($user, 'foo');\n\n``Silex\\Route\\SecurityTrait`` adds the following methods to the controllers:\n\n* **secure**: Secures a controller for the given roles.\n\n.. code-block:: php\n\n    $app->get('/', function () {\n        // do something but only for admins\n    })->secure('ROLE_ADMIN');\n\n.. caution::\n\n    The ``Silex\\Route\\SecurityTrait`` must be used with a user defined\n    ``Route`` class, not the application.\n\n    .. code-block:: php\n\n        use Silex\\Route;\n\n        class MyRoute extends Route\n        {\n            use Route\\SecurityTrait;\n        }\n\n    .. code-block:: php\n\n        $app['route_class'] = 'MyRoute';\n\n\n.. _cookbook: http://symfony.com/doc/current/cookbook/security/custom_authentication_provider.html\n"
  },
  {
    "path": "doc/providers/serializer.rst",
    "content": "Serializer\n==========\n\nThe *SerializerServiceProvider* provides a service for serializing objects.\n\nParameters\n----------\n\nNone.\n\nServices\n--------\n\n* **serializer**: An instance of `Symfony\\\\Component\\\\Serializer\\\\Serializer\n  <http://api.symfony.com/master/Symfony/Component/Serializer/Serializer.html>`_.\n\n* **serializer.encoders**: `Symfony\\\\Component\\\\Serializer\\\\Encoder\\\\JsonEncoder\n  <http://api.symfony.com/master/Symfony/Component/Serializer/Encoder/JsonEncoder.html>`_\n  and `Symfony\\\\Component\\\\Serializer\\\\Encoder\\\\XmlEncoder\n  <http://api.symfony.com/master/Symfony/Component/Serializer/Encoder/XmlEncoder.html>`_.\n\n* **serializer.normalizers**: `Symfony\\\\Component\\\\Serializer\\\\Normalizer\\\\CustomNormalizer\n  <http://api.symfony.com/master/Symfony/Component/Serializer/Normalizer/CustomNormalizer.html>`_\n  and `Symfony\\\\Component\\\\Serializer\\\\Normalizer\\\\GetSetMethodNormalizer\n  <http://api.symfony.com/master/Symfony/Component/Serializer/Normalizer/GetSetMethodNormalizer.html>`_.\n\nRegistering\n-----------\n\n.. code-block:: php\n\n    $app->register(new Silex\\Provider\\SerializerServiceProvider());\n    \n.. note::\n\n    Add the Symfony's `Serializer Component\n    <http://symfony.com/doc/current/components/serializer.html>`_ as a\n    dependency:\n\n    .. code-block:: bash\n\n        composer require symfony/serializer\n\nUsage\n-----\n\nThe ``SerializerServiceProvider`` provider provides a ``serializer`` service::\n\n    use Silex\\Application;\n    use Silex\\Provider\\SerializerServiceProvider;\n    use Symfony\\Component\\HttpFoundation\\Request;\n    use Symfony\\Component\\HttpFoundation\\Response;\n\n    $app = new Application();\n\n    $app->register(new SerializerServiceProvider());\n\n    // only accept content types supported by the serializer via the assert method.\n    $app->get(\"/pages/{id}.{_format}\", function (Request $request, $id) use ($app) {\n        // assume a page_repository service exists that returns Page objects. The\n        // object returned has getters and setters exposing the state.\n        $page = $app['page_repository']->find($id);\n        $format = $request->getRequestFormat();\n\n        if (!$page instanceof Page) {\n            $app->abort(\"No page found for id: $id\");\n        }\n\n        return new Response($app['serializer']->serialize($page, $format), 200, array(\n            \"Content-Type\" => $request->getMimeType($format)\n        ));\n    })->assert(\"_format\", \"xml|json\")\n      ->assert(\"id\", \"\\d+\");\n"
  },
  {
    "path": "doc/providers/service_controller.rst",
    "content": "Service Controllers\n===================\n\nAs your Silex application grows, you may wish to begin organizing your\ncontrollers in a more formal fashion. Silex can use controller classes out of\nthe box, but with a bit of work, your controllers can be created as services,\ngiving you the full power of dependency injection and lazy loading.\n\n.. ::todo Link above to controller classes cookbook\n\nWhy would I want to do this?\n----------------------------\n\n- Dependency Injection over Service Location\n\n  Using this method, you can inject the actual dependencies required by your\n  controller and gain total inversion of control, while still maintaining the\n  lazy loading of your controllers and its dependencies. Because your\n  dependencies are clearly defined, they are easily mocked, allowing you to test\n  your controllers in isolation.\n\n- Framework Independence\n\n  Using this method, your controllers start to become more independent of the\n  framework you are using. Carefully crafted, your controllers will become\n  reusable with multiple frameworks. By keeping careful control of your\n  dependencies, your controllers could easily become compatible with Silex,\n  Symfony (full stack) and Drupal, to name just a few.\n\nParameters\n----------\n\nThere are currently no parameters for the ``ServiceControllerServiceProvider``.\n\nServices\n--------\n\nThere are no extra services provided, the ``ServiceControllerServiceProvider``\nsimply extends the existing **resolver** service.\n\nRegistering\n-----------\n\n.. code-block:: php\n\n    $app->register(new Silex\\Provider\\ServiceControllerServiceProvider());\n\nUsage\n-----\n\nIn this slightly contrived example of a blog API, we're going to change the\n``/posts.json`` route to use a controller, that is defined as a service.\n\n.. code-block:: php\n\n    use Silex\\Application;\n    use Demo\\Repository\\PostRepository;\n\n    $app = new Application();\n\n    $app['posts.repository'] = function() {\n        return new PostRepository;\n    };\n\n    $app->get('/posts.json', function() use ($app) {\n        return $app->json($app['posts.repository']->findAll());\n    });\n\nRewriting your controller as a service is pretty simple, create a Plain Ol' PHP\nObject with your ``PostRepository`` as a dependency, along with an\n``indexJsonAction`` method to handle the request. Although not shown in the\nexample below, you can use type hinting and parameter naming to get the\nparameters you need, just like with standard Silex routes.\n\nIf you are a TDD/BDD fan (and you should be), you may notice that this\ncontroller has well defined responsibilities and dependencies, and is easily\ntested/specced. You may also notice that the only external dependency is on\n``Symfony\\Component\\HttpFoundation\\JsonResponse``, meaning this controller could\neasily be used in a Symfony (full stack) application, or potentially with other\napplications or frameworks that know how to handle a `Symfony/HttpFoundation\n<http://symfony.com/doc/master/components/http_foundation/introduction.html>`_\n``Response`` object.\n\n.. code-block:: php\n\n    namespace Demo\\Controller;\n\n    use Demo\\Repository\\PostRepository;\n    use Symfony\\Component\\HttpFoundation\\JsonResponse;\n\n    class PostController\n    {\n        protected $repo;\n\n        public function __construct(PostRepository $repo)\n        {\n            $this->repo = $repo;\n        }\n\n        public function indexJsonAction()\n        {\n            return new JsonResponse($this->repo->findAll());\n        }\n    }\n\nAnd lastly, define your controller as a service in the application, along with\nyour route. The syntax in the route definition is the name of the service,\nfollowed by a single colon (:), followed by the method name.\n\n.. code-block:: php\n\n    $app['posts.controller'] = function() use ($app) {\n        return new PostController($app['posts.repository']);\n    };\n\n    $app->get('/posts.json', \"posts.controller:indexJsonAction\");\n\nIn addition to using classes for service controllers, you can define any\ncallable as a service in the application to be used for a route.\n\n.. code-block:: php\n\n    namespace Demo\\Controller;\n\n    use Demo\\Repository\\PostRepository;\n    use Symfony\\Component\\HttpFoundation\\JsonResponse;\n\n    function postIndexJson(PostRepository $repo) {\n        return function() use ($repo) {\n            return new JsonResponse($repo->findAll());\n        };\n    }\n\nAnd when defining your route, the code would look like the following:\n\n.. code-block:: php\n\n    $app['posts.controller'] = function($app) {\n        return Demo\\Controller\\postIndexJson($app['posts.repository']);\n    };\n\n    $app->get('/posts.json', 'posts.controller');\n"
  },
  {
    "path": "doc/providers/session.rst",
    "content": "Session\n=======\n\nThe *SessionServiceProvider* provides a service for storing data persistently\nbetween requests.\n\nParameters\n----------\n\n* **session.storage.save_path** (optional): The path for the\n  ``NativeFileSessionHandler``, defaults to the value of\n  ``sys_get_temp_dir()``.\n\n* **session.storage.options**: An array of options that is passed to the\n  constructor of the ``session.storage`` service.\n\n  In case of the default `NativeSessionStorage\n  <http://api.symfony.com/master/Symfony/Component/HttpFoundation/Session/Storage/NativeSessionStorage.html>`_,\n  the most useful options are:\n\n  * **name**: The cookie name (_SESS by default)\n  * **id**: The session id (null by default)\n  * **cookie_lifetime**: Cookie lifetime\n  * **cookie_path**: Cookie path\n  * **cookie_domain**: Cookie domain\n  * **cookie_secure**: Cookie secure (HTTPS)\n  * **cookie_httponly**: Whether the cookie is http only\n\n  However, all of these are optional. Default Sessions life time is 1800\n  seconds (30 minutes). To override this, set the ``lifetime`` option.\n\n  For a full list of available options, read the `PHP\n  <http://php.net/session.configuration>`_ official documentation.\n\n* **session.test**: Whether to simulate sessions or not (useful when writing\n  functional tests).\n\nServices\n--------\n\n* **session**: An instance of Symfony's `Session\n  <http://api.symfony.com/master/Symfony/Component/HttpFoundation/Session/Session.html>`_.\n\n* **session.storage**: A service that is used for persistence of the session\n  data.\n\n* **session.storage.handler**: A service that is used by the\n  ``session.storage`` for data access. Defaults to a `NativeFileSessionHandler\n  <http://api.symfony.com/master/Symfony/Component/HttpFoundation/Session/Storage/Handler/NativeFileSessionHandler.html>`_\n  storage handler.\n\nRegistering\n-----------\n\n.. code-block:: php\n\n    $app->register(new Silex\\Provider\\SessionServiceProvider());\n\nUsage\n-----\n\nThe Session provider provides a ``session`` service. Here is an example that\nauthenticates a user and creates a session for them::\n\n    use Symfony\\Component\\HttpFoundation\\Request;\n    use Symfony\\Component\\HttpFoundation\\Response;\n\n    $app->get('/login', function (Request $request) use ($app) {\n        $username = $request->server->get('PHP_AUTH_USER', false);\n        $password = $request->server->get('PHP_AUTH_PW');\n\n        if ('igor' === $username && 'password' === $password) {\n            $app['session']->set('user', array('username' => $username));\n            return $app->redirect('/account');\n        }\n\n        $response = new Response();\n        $response->headers->set('WWW-Authenticate', sprintf('Basic realm=\"%s\"', 'site_login'));\n        $response->setStatusCode(401, 'Please sign in.');\n        return $response;\n    });\n\n    $app->get('/account', function () use ($app) {\n        if (null === $user = $app['session']->get('user')) {\n            return $app->redirect('/login');\n        }\n\n        return \"Welcome {$user['username']}!\";\n    });\n\n\nCustom Session Configurations\n-----------------------------\n\nIf your system is using a custom session configuration (such as a redis handler\nfrom a PHP extension) then you need to disable the NativeFileSessionHandler by\nsetting ``session.storage.handler`` to null. You will have to configure the\n``session.save_path`` ini setting yourself in that case.\n\n.. code-block:: php\n\n    $app['session.storage.handler'] = null;\n\n"
  },
  {
    "path": "doc/providers/swiftmailer.rst",
    "content": "Swiftmailer\n===========\n\nThe *SwiftmailerServiceProvider* provides a service for sending email through\nthe `Swift Mailer <http://swiftmailer.org>`_ library.\n\nYou can use the ``mailer`` service to send messages easily. By default, it\nwill attempt to send emails through SMTP.\n\nParameters\n----------\n\n* **swiftmailer.use_spool**: A boolean to specify whether or not to use the\n  memory spool, defaults to true.\n\n* **swiftmailer.options**: An array of options for the default SMTP-based\n  configuration.\n\n  The following options can be set:\n\n  * **host**: SMTP hostname, defaults to 'localhost'.\n  * **port**: SMTP port, defaults to 25.\n  * **username**: SMTP username, defaults to an empty string.\n  * **password**: SMTP password, defaults to an empty string.\n  * **encryption**: SMTP encryption, defaults to null. Valid values are 'tls', 'ssl', or null (indicating no encryption).\n  * **auth_mode**: SMTP authentication mode, defaults to null. Valid values are 'plain', 'login', 'cram-md5', or null.\n\n  Example usage::\n\n    $app['swiftmailer.options'] = array(\n        'host' => 'host',\n        'port' => '25',\n        'username' => 'username',\n        'password' => 'password',\n        'encryption' => null,\n        'auth_mode' => null\n    );\n\n* **swiftmailer.sender_address**: If set, all messages will be delivered with\n  this address as the \"return path\" address.\n\n* **swiftmailer.delivery_addresses**: If not empty, all email messages will be\n  sent to those addresses instead of being sent to their actual recipients. This\n  is often useful when developing.\n\n* **swiftmailer.delivery_whitelist**: Used in combination with\n  ``delivery_addresses``. If set, emails matching any of these patterns will be\n  delivered like normal, as well as being sent to ``delivery_addresses``.\n\nServices\n--------\n\n* **mailer**: The mailer instance.\n\n  Example usage::\n\n    $message = \\Swift_Message::newInstance();\n\n    // ...\n\n    $app['mailer']->send($message);\n\n* **swiftmailer.transport**: The transport used for e-mail\n  delivery. Defaults to a ``Swift_Transport_EsmtpTransport``.\n\n* **swiftmailer.transport.buffer**: StreamBuffer used by\n  the transport.\n\n* **swiftmailer.transport.authhandler**: Authentication\n  handler used by the transport. Will try the following\n  by default: CRAM-MD5, login, plaintext.\n\n* **swiftmailer.transport.eventdispatcher**: Internal event\n  dispatcher used by Swiftmailer.\n\nRegistering\n-----------\n\n.. code-block:: php\n\n    $app->register(new Silex\\Provider\\SwiftmailerServiceProvider());\n\n.. note::\n\n    Add SwiftMailer as a dependency:\n\n    .. code-block:: bash\n\n        composer require swiftmailer/swiftmailer\n\nUsage\n-----\n\nThe Swiftmailer provider provides a ``mailer`` service::\n\n    use Symfony\\Component\\HttpFoundation\\Request;\n\n    $app->post('/feedback', function (Request $request) use ($app) {\n        $message = \\Swift_Message::newInstance()\n            ->setSubject('[YourSite] Feedback')\n            ->setFrom(array('noreply@yoursite.com'))\n            ->setTo(array('feedback@yoursite.com'))\n            ->setBody($request->get('message'));\n\n        $app['mailer']->send($message);\n\n        return new Response('Thank you for your feedback!', 201);\n    });\n\nUsage in commands\n~~~~~~~~~~~~~~~~~\n\nBy default, the Swiftmailer provider sends the emails using the ``KernelEvents::TERMINATE``\nevent, which is fired after the response has been sent. However, as this event\nisn't fired for console commands, your emails won't be sent.\n\nFor that reason, if you send emails using a command console, it is recommended\nthat you disable the use of the memory spool (before accessing ``$app['mailer']``)::\n\n    $app['swiftmailer.use_spool'] = false;\n\nAlternatively, you can just make sure to flush the message spool by hand before\nending the command execution. To do so, use the following code::\n\n    $app['swiftmailer.spooltransport']\n        ->getSpool()\n        ->flushQueue($app['swiftmailer.transport'])\n    ;\n\nTraits\n------\n\n``Silex\\Application\\SwiftmailerTrait`` adds the following shortcuts:\n\n* **mail**: Sends an email.\n\n.. code-block:: php\n\n    $app->mail(\\Swift_Message::newInstance()\n        ->setSubject('[YourSite] Feedback')\n        ->setFrom(array('noreply@yoursite.com'))\n        ->setTo(array('feedback@yoursite.com'))\n        ->setBody($request->get('message')));\n\nFor more information, check out the `Swift Mailer documentation\n<http://swiftmailer.org>`_.\n"
  },
  {
    "path": "doc/providers/translation.rst",
    "content": "Translation\n===========\n\nThe *TranslationServiceProvider* provides a service for translating your\napplication into different languages.\n\nParameters\n----------\n\n* **translator.domains** (optional): A mapping of domains/locales/messages.\n  This parameter contains the translation data for all languages and domains.\n\n* **locale** (optional): The locale for the translator. You will most likely\n  want to set this based on some request parameter. Defaults to ``en``.\n\n* **locale_fallbacks** (optional): Fallback locales for the translator. It will\n  be used when the current locale has no messages set. Defaults to ``en``.\n\nServices\n--------\n\n* **translator**: An instance of `Translator\n  <http://api.symfony.com/master/Symfony/Component/Translation/Translator.html>`_,\n  that is used for translation.\n\n* **translator.loader**: An instance of an implementation of the translation\n  `LoaderInterface\n  <http://api.symfony.com/master/Symfony/Component/Translation/Loader/LoaderInterface.html>`_,\n  defaults to an `ArrayLoader\n  <http://api.symfony.com/master/Symfony/Component/Translation/Loader/ArrayLoader.html>`_.\n\n* **translator.message_selector**: An instance of `MessageSelector\n  <http://api.symfony.com/master/Symfony/Component/Translation/MessageSelector.html>`_.\n\nRegistering\n-----------\n\n.. code-block:: php\n\n    $app->register(new Silex\\Provider\\LocaleServiceProvider());\n    $app->register(new Silex\\Provider\\TranslationServiceProvider(), array(\n        'locale_fallbacks' => array('en'),\n    ));\n\n.. note::\n\n    Add the Symfony Translation Component as a dependency:\n\n    .. code-block:: bash\n\n        composer require symfony/translation\n\nUsage\n-----\n\nThe Translation provider provides a ``translator`` service and makes use of\nthe ``translator.domains`` parameter::\n\n    $app['translator.domains'] = array(\n        'messages' => array(\n            'en' => array(\n                'hello'     => 'Hello %name%',\n                'goodbye'   => 'Goodbye %name%',\n            ),\n            'de' => array(\n                'hello'     => 'Hallo %name%',\n                'goodbye'   => 'Tschüss %name%',\n            ),\n            'fr' => array(\n                'hello'     => 'Bonjour %name%',\n                'goodbye'   => 'Au revoir %name%',\n            ),\n        ),\n        'validators' => array(\n            'fr' => array(\n                'This value should be a valid number.' => 'Cette valeur doit être un nombre.',\n            ),\n        ),\n    );\n\n    $app->get('/{_locale}/{message}/{name}', function ($message, $name) use ($app) {\n        return $app['translator']->trans($message, array('%name%' => $name));\n    });\n\nThe above example will result in following routes:\n\n* ``/en/hello/igor`` will return ``Hello igor``.\n\n* ``/de/hello/igor`` will return ``Hallo igor``.\n\n* ``/fr/hello/igor`` will return ``Bonjour igor``.\n\n* ``/it/hello/igor`` will return ``Hello igor`` (because of the fallback).\n\nUsing Resources\n---------------\n\nWhen translations are stored in a file, you can load them as follows::\n\n    $app = new Application();\n    \n    $app->register(new TranslationServiceProvider());\n    $app->extend('translator.resources', function ($resources, $app) {\n        $resources = array_merge($resources, array(\n            array('array', array('This value should be a valid number.' => 'Cette valeur doit être un nombre.'), 'fr', 'validators'),\n        ));\n\n        return $resources;\n    });\n\nTraits\n------\n\n``Silex\\Application\\TranslationTrait`` adds the following shortcuts:\n\n* **trans**: Translates the given message.\n\n* **transChoice**: Translates the given choice message by choosing a\n  translation according to a number.\n\n.. code-block:: php\n\n    $app->trans('Hello World');\n\n    $app->transChoice('Hello World');\n\nRecipes\n-------\n\nYAML-based language files\n~~~~~~~~~~~~~~~~~~~~~~~~~\n\nHaving your translations in PHP files can be inconvenient. This recipe will\nshow you how to load translations from external YAML files.\n\nFirst, add the Symfony ``Config`` and ``Yaml`` components as dependencies:\n\n.. code-block:: bash\n\n    composer require symfony/config symfony/yaml\n\nNext, you have to create the language mappings in YAML files. A naming you can\nuse is ``locales/en.yml``. Just do the mapping in this file as follows:\n\n.. code-block:: yaml\n\n    hello: Hello %name%\n    goodbye: Goodbye %name%\n\nThen, register the ``YamlFileLoader`` on the ``translator`` and add all your\ntranslation files::\n\n    use Symfony\\Component\\Translation\\Loader\\YamlFileLoader;\n\n    $app->extend('translator', function($translator, $app) {\n        $translator->addLoader('yaml', new YamlFileLoader());\n\n        $translator->addResource('yaml', __DIR__.'/locales/en.yml', 'en');\n        $translator->addResource('yaml', __DIR__.'/locales/de.yml', 'de');\n        $translator->addResource('yaml', __DIR__.'/locales/fr.yml', 'fr');\n\n        return $translator;\n    });\n\nXLIFF-based language files\n~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nJust as you would do with YAML translation files, you first need to add the\nSymfony ``Config`` component as a dependency (see above for details).\n\nThen, similarly, create XLIFF files in your locales directory and add them to\nthe translator::\n\n    $translator->addResource('xliff', __DIR__.'/locales/en.xlf', 'en');\n    $translator->addResource('xliff', __DIR__.'/locales/de.xlf', 'de');\n    $translator->addResource('xliff', __DIR__.'/locales/fr.xlf', 'fr');\n\n.. note::\n\n    The XLIFF loader is already pre-configured by the extension.\n\nAccessing translations in Twig templates\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nOnce loaded, the translation service provider is available from within Twig\ntemplates when using the Twig bridge provided by Symfony (see\n:doc:`TwigServiceProvider </providers/twig>`):\n\n.. code-block:: jinja\n\n    {{ 'translation_key'|trans }}\n    {{ 'translation_key'|transchoice }}\n    {% trans %}translation_key{% endtrans %}\n"
  },
  {
    "path": "doc/providers/twig.rst",
    "content": "Twig\n====\n\nThe *TwigServiceProvider* provides integration with the `Twig\n<http://twig.sensiolabs.org/>`_ template engine.\n\nParameters\n----------\n\n* **twig.path** (optional): Path to the directory containing twig template\n  files (it can also be an array of paths).\n\n* **twig.templates** (optional): An associative array of template names to\n  template contents. Use this if you want to define your templates inline.\n\n* **twig.options** (optional): An associative array of twig\n  options. Check out the `twig documentation <http://twig.sensiolabs.org/doc/api.html#environment-options>`_\n  for more information.\n\n* **twig.form.templates** (optional): An array of templates used to render\n  forms (only available when the ``FormServiceProvider`` is enabled). The\n  default theme is ``form_div_layout.html.twig``, but you can use the other\n  built-in themes: ``form_table_layout.html.twig``,\n  ``bootstrap_3_layout.html.twig``, and\n  ``bootstrap_3_horizontal_layout.html.twig``.\n\nServices\n--------\n\n* **twig**: The ``Twig_Environment`` instance. The main way of\n  interacting with Twig.\n\n* **twig.loader**: The loader for Twig templates which uses the ``twig.path``\n  and the ``twig.templates`` options. You can also replace the loader\n  completely.\n\nRegistering\n-----------\n\n.. code-block:: php\n\n    $app->register(new Silex\\Provider\\TwigServiceProvider(), array(\n        'twig.path' => __DIR__.'/views',\n    ));\n\n.. note::\n\n    Add Twig as a dependency:\n\n    .. code-block:: bash\n\n        composer require twig/twig\n\nUsage\n-----\n\nThe Twig provider provides a ``twig`` service that can render templates::\n\n    $app->get('/hello/{name}', function ($name) use ($app) {\n        return $app['twig']->render('hello.twig', array(\n            'name' => $name,\n        ));\n    });\n\nSymfony Components Integration\n------------------------------\n\nSymfony provides a Twig bridge that provides additional integration between\nsome Symfony components and Twig. Add it as a dependency:\n\n.. code-block:: bash\n\n    composer require symfony/twig-bridge\n\nWhen present, the ``TwigServiceProvider`` will provide you with the following\nadditional capabilities.\n\n* Access to the ``path()`` and ``url()`` functions. You can find more\n  information in the `Symfony Routing documentation\n  <http://symfony.com/doc/current/book/routing.html#generating-urls-from-a-template>`_:\n\n  .. code-block:: jinja\n  \n      {{ path('homepage') }}\n      {{ url('homepage') }} {# generates the absolute url http://example.org/ #}\n      {{ path('hello', {name: 'Fabien'}) }}\n      {{ url('hello', {name: 'Fabien'}) }} {# generates the absolute url http://example.org/hello/Fabien #}\n\n* Access to the ``absolute_url()`` and ``relative_path()`` Twig functions.\n\nTranslations Support\n~~~~~~~~~~~~~~~~~~~~\n\nIf you are using the ``TranslationServiceProvider``, you will get the\n``trans()`` and ``transchoice()`` functions for translation in Twig templates.\nYou can find more information in the `Symfony Translation documentation\n<http://symfony.com/doc/current/book/translation.html#twig-templates>`_.\n\nForm Support\n~~~~~~~~~~~~\n\nIf you are using the ``FormServiceProvider``, you will get a set of helpers for\nworking with forms in templates. You can find more information in the `Symfony\nForms reference\n<http://symfony.com/doc/current/reference/forms/twig_reference.html>`_.\n\nSecurity Support\n~~~~~~~~~~~~~~~~\n\nIf you are using the ``SecurityServiceProvider``, you will have access to the\n``is_granted()`` function in templates. You can find more information in the\n`Symfony Security documentation\n<http://symfony.com/doc/current/book/security.html#access-control-in-templates>`_.\n\nGlobal Variable\n~~~~~~~~~~~~~~~\n\nWhen the Twig bridge is available, the ``global`` variable refers to an\ninstance of `AppVariable <http://api.symfony.com/master/Symfony/Bridge/Twig/AppVariable.html>`_.\nIt gives access to the following methods:\n\n.. code-block:: jinja\n\n    {# The current Request #}\n    {{ global.request }}\n\n    {# The current User (when security is enabled) #}\n    {{ global.user }}\n\n    {# The current Session #}\n    {{ global.session }}\n\n    {# The debug flag #}\n    {{ global.debug }}\n\nRendering a Controller\n~~~~~~~~~~~~~~~~~~~~~~\n\nA ``render`` function is also registered to help you render another controller\nfrom a template (available when the :doc:`HttpFragment Service Provider\n</providers/http_fragment>` is registered):\n\n.. code-block:: jinja\n\n    {{ render(url('sidebar')) }}\n\n    {# or you can reference a controller directly without defining a route for it #}\n    {{ render(controller(controller)) }}\n\n.. note::\n\n    You must prepend the ``app.request.baseUrl`` to render calls to ensure\n    that the render works when deployed into a sub-directory of the docroot.\n\n.. note::\n\n    Read the Twig `reference`_ for Symfony document to learn more about the\n    various Twig functions.\n\nTraits\n------\n\n``Silex\\Application\\TwigTrait`` adds the following shortcuts:\n\n* **render**: Renders a view with the given parameters and returns a Response\n  object.\n\n.. code-block:: php\n\n    return $app->render('index.html', ['name' => 'Fabien']);\n\n    $response = new Response();\n    $response->setTtl(10);\n\n    return $app->render('index.html', ['name' => 'Fabien'], $response);\n\n.. code-block:: php\n\n    // stream a view\n    use Symfony\\Component\\HttpFoundation\\StreamedResponse;\n\n    return $app->render('index.html', ['name' => 'Fabien'], new StreamedResponse());\n\nCustomization\n-------------\n\nYou can configure the Twig environment before using it by extending the\n``twig`` service::\n\n    $app->extend('twig', function($twig, $app) {\n        $twig->addGlobal('pi', 3.14);\n        $twig->addFilter('levenshtein', new \\Twig_Filter_Function('levenshtein'));\n\n        return $twig;\n    });\n\nFor more information, check out the `official Twig documentation\n<http://twig.sensiolabs.org>`_.\n\n.. _reference: https://symfony.com/doc/current/reference/twig_reference.html#controller\n"
  },
  {
    "path": "doc/providers/validator.rst",
    "content": "Validator\n=========\n\nThe *ValidatorServiceProvider* provides a service for validating data. It is\nmost useful when used with the *FormServiceProvider*, but can also be used\nstandalone.\n\nParameters\n----------\n\n* **validator.validator_service_ids**: An array of service names representing\n  validators.\n\nServices\n--------\n\n* **validator**: An instance of `Validator\n  <http://api.symfony.com/master/Symfony/Component/Validator/ValidatorInterface.html>`_.\n\n* **validator.mapping.class_metadata_factory**: Factory for metadata loaders,\n  which can read validation constraint information from classes. Defaults to\n  StaticMethodLoader--ClassMetadataFactory.\n\n  This means you can define a static ``loadValidatorMetadata`` method on your\n  data class, which takes a ClassMetadata argument. Then you can set\n  constraints on this ClassMetadata instance.\n\nRegistering\n-----------\n\n.. code-block:: php\n\n    $app->register(new Silex\\Provider\\ValidatorServiceProvider());\n\n.. note::\n\n    Add the Symfony Validator Component as a dependency:\n\n    .. code-block:: bash\n\n        composer require symfony/validator\n\nUsage\n-----\n\nThe Validator provider provides a ``validator`` service.\n\nValidating Values\n~~~~~~~~~~~~~~~~~\n\nYou can validate values directly using the ``validate`` validator\nmethod::\n\n    use Symfony\\Component\\Validator\\Constraints as Assert;\n\n    $app->get('/validate/{email}', function ($email) use ($app) {\n        $errors = $app['validator']->validate($email, new Assert\\Email());\n\n        if (count($errors) > 0) {\n            return (string) $errors;\n        } else {\n            return 'The email is valid';\n        }\n    });\n\nValidating Associative Arrays\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nValidating associative arrays is like validating simple values, with a\ncollection of constraints::\n\n    use Symfony\\Component\\Validator\\Constraints as Assert;\n\n    $book = array(\n        'title' => 'My Book',\n        'author' => array(\n            'first_name' => 'Fabien',\n            'last_name'  => 'Potencier',\n        ),\n    );\n\n    $constraint = new Assert\\Collection(array(\n        'title' => new Assert\\Length(array('min' => 10)),\n        'author' => new Assert\\Collection(array(\n            'first_name' => array(new Assert\\NotBlank(), new Assert\\Length(array('min' => 10))),\n            'last_name'  => new Assert\\Length(array('min' => 10)),\n        )),\n    ));\n    $errors = $app['validator']->validate($book, $constraint);\n\n    if (count($errors) > 0) {\n        foreach ($errors as $error) {\n            echo $error->getPropertyPath().' '.$error->getMessage().\"\\n\";\n        }\n    } else {\n        echo 'The book is valid';\n    }\n\nValidating Objects\n~~~~~~~~~~~~~~~~~~\n\nIf you want to add validations to a class, you can define the constraint for\nthe class properties and getters, and then call the ``validate`` method::\n\n    use Symfony\\Component\\Validator\\Constraints as Assert;\n\n    class Book\n    {\n        public $title;\n        public $author;\n    }\n\n    class Author\n    {\n        public $first_name;\n        public $last_name;\n    }\n\n    $author = new Author();\n    $author->first_name = 'Fabien';\n    $author->last_name = 'Potencier';\n\n    $book = new Book();\n    $book->title = 'My Book';\n    $book->author = $author;\n\n    $metadata = $app['validator.mapping.class_metadata_factory']->getMetadataFor('Author');\n    $metadata->addPropertyConstraint('first_name', new Assert\\NotBlank());\n    $metadata->addPropertyConstraint('first_name', new Assert\\Length(array('min' => 10)));\n    $metadata->addPropertyConstraint('last_name', new Assert\\Length(array('min' => 10)));\n\n    $metadata = $app['validator.mapping.class_metadata_factory']->getMetadataFor('Book');\n    $metadata->addPropertyConstraint('title', new Assert\\Length(array('min' => 10)));\n    $metadata->addPropertyConstraint('author', new Assert\\Valid());\n\n    $errors = $app['validator']->validate($book);\n\n    if (count($errors) > 0) {\n        foreach ($errors as $error) {\n            echo $error->getPropertyPath().' '.$error->getMessage().\"\\n\";\n        }\n    } else {\n        echo 'The author is valid';\n    }\n\nYou can also declare the class constraint by adding a static\n``loadValidatorMetadata`` method to your classes::\n\n    use Symfony\\Component\\Validator\\Mapping\\ClassMetadata;\n    use Symfony\\Component\\Validator\\Constraints as Assert;\n\n    class Book\n    {\n        public $title;\n        public $author;\n\n        static public function loadValidatorMetadata(ClassMetadata $metadata)\n        {\n            $metadata->addPropertyConstraint('title', new Assert\\Length(array('min' => 10)));\n            $metadata->addPropertyConstraint('author', new Assert\\Valid());\n        }\n    }\n\n    class Author\n    {\n        public $first_name;\n        public $last_name;\n\n        static public function loadValidatorMetadata(ClassMetadata $metadata)\n        {\n            $metadata->addPropertyConstraint('first_name', new Assert\\NotBlank());\n            $metadata->addPropertyConstraint('first_name', new Assert\\Length(array('min' => 10)));\n            $metadata->addPropertyConstraint('last_name', new Assert\\Length(array('min' => 10)));\n        }\n    }\n\n    $app->get('/validate/{email}', function ($email) use ($app) {\n        $author = new Author();\n        $author->first_name = 'Fabien';\n        $author->last_name = 'Potencier';\n\n        $book = new Book();\n        $book->title = 'My Book';\n        $book->author = $author;\n\n        $errors = $app['validator']->validate($book);\n\n        if (count($errors) > 0) {\n            foreach ($errors as $error) {\n                echo $error->getPropertyPath().' '.$error->getMessage().\"\\n\";\n            }\n        } else {\n            echo 'The author is valid';\n        }\n    });\n\n.. note::\n\n    Use ``addGetterConstraint()`` to add constraints on getter methods and\n    ``addConstraint()`` to add constraints on the class itself.\n\nTranslation\n~~~~~~~~~~~\n\nTo be able to translate the error messages, you can use the translator\nprovider and register the messages under the ``validators`` domain::\n\n    $app['translator.domains'] = array(\n        'validators' => array(\n            'fr' => array(\n                'This value should be a valid number.' => 'Cette valeur doit être un nombre.',\n            ),\n        ),\n    );\n\nFor more information, consult the `Symfony Validation documentation\n<http://symfony.com/doc/master/book/validation.html>`_.\n"
  },
  {
    "path": "doc/providers/var_dumper.rst",
    "content": "Var Dumper\n==========\n\nThe *VarDumperServiceProvider* provides a mechanism that allows exploring then\ndumping any PHP variable.\n\nParameters\n----------\n\n* **var_dumper.dump_destination**: A stream URL where dumps should be written\n  to (defaults to ``null``).\n\nServices\n--------\n\n* n/a\n\nRegistering\n-----------\n\n.. code-block:: php\n\n    $app->register(new Silex\\Provider\\VarDumperServiceProvider());\n\n.. note::\n\n    Add the Symfony VarDumper Component as a dependency:\n\n    .. code-block:: bash\n\n        composer require symfony/var-dumper\n\nUsage\n-----\n\nAdding the VarDumper component as a Composer dependency gives you access to the\n``dump()`` PHP function anywhere in your code.\n\nIf you are using Twig, it also provides a ``dump()`` Twig function and a\n``dump`` Twig tag.\n\nThe VarDumperServiceProvider is also useful when used with the Silex\nWebProfiler as the dumps are made available in the web debug toolbar and in the\nweb profiler.\n"
  },
  {
    "path": "doc/providers.rst",
    "content": "Providers\n=========\n\nProviders allow the developer to reuse parts of an application into another\none. Silex provides two types of providers defined by two interfaces:\n``ServiceProviderInterface`` for services and ``ControllerProviderInterface``\nfor controllers.\n\nService Providers\n-----------------\n\nLoading providers\n~~~~~~~~~~~~~~~~~\n\nIn order to load and use a service provider, you must register it on the\napplication::\n\n    $app = new Silex\\Application();\n\n    $app->register(new Acme\\DatabaseServiceProvider());\n\nYou can also provide some parameters as a second argument. These will be set\n**after** the provider is registered, but **before** it is booted::\n\n    $app->register(new Acme\\DatabaseServiceProvider(), array(\n        'database.dsn'      => 'mysql:host=localhost;dbname=myapp',\n        'database.user'     => 'root',\n        'database.password' => 'secret_root_password',\n    ));\n\nConventions\n~~~~~~~~~~~\n\nYou need to watch out in what order you do certain things when interacting\nwith providers. Just keep these rules in mind:\n\n* Overriding existing services must occur **after** the provider is\n  registered.\n\n  *Reason: If the service already exists, the provider will overwrite it.*\n\n* You can set parameters any time **after** the provider is registered, but\n  **before** the service is accessed.\n\n  *Reason: Providers can set default values for parameters. Just like with\n  services, the provider will overwrite existing values.*\n\nIncluded providers\n~~~~~~~~~~~~~~~~~~\n\nThere are a few providers that you get out of the box. All of these are within\nthe ``Silex\\Provider`` namespace:\n\n* :doc:`DoctrineServiceProvider <providers/doctrine>`\n* :doc:`FormServiceProvider <providers/form>`\n* :doc:`HttpCacheServiceProvider <providers/http_cache>`\n* :doc:`MonologServiceProvider <providers/monolog>`\n* :doc:`RememberMeServiceProvider <providers/remember_me>`\n* :doc:`SecurityServiceProvider <providers/security>`\n* :doc:`SerializerServiceProvider <providers/serializer>`\n* :doc:`ServiceControllerServiceProvider <providers/service_controller>`\n* :doc:`SessionServiceProvider <providers/session>`\n* :doc:`SwiftmailerServiceProvider <providers/swiftmailer>`\n* :doc:`TranslationServiceProvider <providers/translation>`\n* :doc:`TwigServiceProvider <providers/twig>`\n* :doc:`ValidatorServiceProvider <providers/validator>`\n\n.. note::\n\n    The Silex core team maintains a `WebProfiler\n    <https://github.com/silexphp/Silex-WebProfiler>`_ provider that helps debug\n    code in the development environment thanks to the Symfony web debug toolbar\n    and the Symfony profiler.\n\nThird party providers\n~~~~~~~~~~~~~~~~~~~~~\n\nSome service providers are developed by the community. Those third-party\nproviders are listed on `Silex' repository wiki\n<https://github.com/silexphp/Silex/wiki/Third-Party-ServiceProviders>`_.\n\nYou are encouraged to share yours.\n\nCreating a provider\n~~~~~~~~~~~~~~~~~~~\n\nProviders must implement the ``Pimple\\ServiceProviderInterface``::\n\n    interface ServiceProviderInterface\n    {\n        public function register(Container $container);\n    }\n\nThis is very straight forward, just create a new class that implements the\nregister method. In the ``register()`` method, you can define services on the\napplication which then may make use of other services and parameters. \n\n.. tip::\n\n    The ``Pimple\\ServiceProviderInterface`` belongs to the Pimple package, so\n    take care to only use the API of ``Pimple\\Container`` within your\n    ``register`` method. Not only is this a good practice due to the way Pimple\n    and Silex work, but may allow your provider to be used outside of Silex.\n\nOptionally, your service provider can implement the\n``Silex\\Api\\BootableProviderInterface``. A bootable provider must\nimplement the ``boot()`` method, with which you can configure the application, just\nbefore it handles a request::\n\n    interface BootableProviderInterface\n    {\n        function boot(Application $app);\n    }\n\nAnother optional interface, is the ``Silex\\Api\\EventListenerProviderInterface``.\nThis interface contains the ``subscribe()`` method, which allows your provider to\nsubscribe event listener with Silex's EventDispatcher, just before it handles a\nrequest::\n\n    interface EventListenerProviderInterface\n    {\n        function subscribe(Container $app, EventDispatcherInterface $dispatcher);\n    }\n\nHere is an example of such a provider::\n\n    namespace Acme;\n\n    use Pimple\\Container;\n    use Pimple\\ServiceProviderInterface;\n    use Silex\\Application;\n    use Silex\\Api\\BootableProviderInterface;\n    use Silex\\Api\\EventListenerProviderInterface;\n    use Symfony\\Component\\HttpKernel\\KernelEvents;\n    use Symfony\\Component\\HttpKernel\\Event\\FilterResponseEvent;\n\n    class HelloServiceProvider implements ServiceProviderInterface, BootableProviderInterface, EventListenerProviderInterface\n    {\n        public function register(Container $app)\n        {\n            $app['hello'] = $app->protect(function ($name) use ($app) {\n                $default = $app['hello.default_name'] ? $app['hello.default_name'] : '';\n                $name = $name ?: $default;\n\n                return 'Hello '.$app->escape($name);\n            });\n        }\n\n        public function boot(Application $app)\n        {\n            // do something \n        }\n\n        public function subscribe(Container $app, EventDispatcherInterface $dispatcher)\n        {\n            $dispatcher->addListener(KernelEvents::REQUEST, function(FilterResponseEvent $event) use ($app) {\n                // do something \n            });\n        }\n    }\n\nThis class provides a ``hello`` service which is a protected closure. It takes\na ``name`` argument and will return ``hello.default_name`` if no name is\ngiven. If the default is also missing, it will use an empty string.\n\nYou can now use this provider as follows::\n\n    use Symfony\\Component\\HttpFoundation\\Request;\n\n    $app = new Silex\\Application();\n\n    $app->register(new Acme\\HelloServiceProvider(), array(\n        'hello.default_name' => 'Igor',\n    ));\n\n    $app->get('/hello', function (Request $request) use ($app) {\n        $name = $request->get('name');\n\n        return $app['hello']($name);\n    });\n\nIn this example we are getting the ``name`` parameter from the query string,\nso the request path would have to be ``/hello?name=Fabien``.\n\n.. _controller-providers:\n\nController Providers\n--------------------\n\nLoading providers\n~~~~~~~~~~~~~~~~~\n\nIn order to load and use a controller provider, you must \"mount\" its\ncontrollers under a path::\n\n    $app = new Silex\\Application();\n\n    $app->mount('/blog', new Acme\\BlogControllerProvider());\n\nAll controllers defined by the provider will now be available under the\n``/blog`` path.\n\nCreating a provider\n~~~~~~~~~~~~~~~~~~~\n\nProviders must implement the ``Silex\\Api\\ControllerProviderInterface``::\n\n    interface ControllerProviderInterface\n    {\n        public function connect(Application $app);\n    }\n\nHere is an example of such a provider::\n\n    namespace Acme;\n\n    use Silex\\Application;\n    use Silex\\Api\\ControllerProviderInterface;\n\n    class HelloControllerProvider implements ControllerProviderInterface\n    {\n        public function connect(Application $app)\n        {\n            // creates a new controller based on the default route\n            $controllers = $app['controllers_factory'];\n\n            $controllers->get('/', function (Application $app) {\n                return $app->redirect('/hello');\n            });\n\n            return $controllers;\n        }\n    }\n\nThe ``connect`` method must return an instance of ``ControllerCollection``.\n``ControllerCollection`` is the class where all controller related methods are\ndefined (like ``get``, ``post``, ``match``, ...).\n\n.. tip::\n\n    The ``Application`` class acts in fact as a proxy for these methods.\n\nYou can use this provider as follows::\n\n    $app = new Silex\\Application();\n\n    $app->mount('/blog', new Acme\\HelloControllerProvider());\n\nIn this example, the ``/blog/`` path now references the controller defined in\nthe provider.\n\n.. tip::\n\n    You can also define a provider that implements both the service and the\n    controller provider interface and package in the same class the services\n    needed to make your controllers work.\n"
  },
  {
    "path": "doc/services.rst",
    "content": "Services\n========\n\nSilex is not only a framework, it is also a service container. It does this by\nextending `Pimple <http://pimple.sensiolabs.org>`_ which provides a very simple\nservice container.\n\nDependency Injection\n--------------------\n\n.. note::\n\n    You can skip this if you already know what Dependency Injection is.\n\nDependency Injection is a design pattern where you pass dependencies to\nservices instead of creating them from within the service or relying on\nglobals. This generally leads to code that is decoupled, re-usable, flexible\nand testable.\n\nHere is an example of a class that takes a ``User`` object and stores it as a\nfile in JSON format::\n\n    class JsonUserPersister\n    {\n        private $basePath;\n\n        public function __construct($basePath)\n        {\n            $this->basePath = $basePath;\n        }\n\n        public function persist(User $user)\n        {\n            $data = $user->getAttributes();\n            $json = json_encode($data);\n            $filename = $this->basePath.'/'.$user->id.'.json';\n            file_put_contents($filename, $json, LOCK_EX);\n        }\n    }\n\nIn this simple example the dependency is the ``basePath`` property. It is\npassed to the constructor. This means you can create several independent\ninstances with different base paths. Of course dependencies do not have to be\nsimple strings. More often they are in fact other services.\n\nA service container is responsible for creating and storing services. It can\nrecursively create dependencies of the requested services and inject them. It\ndoes so lazily, which means a service is only created when you actually need it.\n\nPimple\n------\n\nPimple makes strong use of closures and implements the ArrayAccess interface.\n\nWe will start off by creating a new instance of Pimple -- and because\n``Silex\\Application`` extends ``Pimple\\Container`` all of this applies to Silex\nas well::\n\n    $container = new Pimple\\Container();\n\nor::\n\n    $app = new Silex\\Application();\n\nParameters\n~~~~~~~~~~\n\nYou can set parameters (which are usually strings) by setting an array key on\nthe container::\n\n    $app['some_parameter'] = 'value';\n\nThe array key can be any value. By convention dots are used for namespacing::\n\n    $app['asset.host'] = 'http://cdn.mysite.com/';\n\nReading parameter values is possible with the same syntax::\n\n    echo $app['some_parameter'];\n\nService definitions\n~~~~~~~~~~~~~~~~~~~\n\nDefining services is no different than defining parameters. You just set an\narray key on the container to be a closure. However, when you retrieve the\nservice, the closure is executed. This allows for lazy service creation::\n\n    $app['some_service'] = function () {\n        return new Service();\n    };\n\nAnd to retrieve the service, use::\n\n    $service = $app['some_service'];\n\nOn first invocation, this will create the service; the same instance will then\nbe returned on any subsequent access.\n\nFactory services\n~~~~~~~~~~~~~~~~\n\nIf you want a different instance to be returned for each service access, wrap\nthe service definition with the ``factory()`` method::\n\n    $app['some_service'] = $app->factory(function () {\n        return new Service();\n    });\n\nEvery time you call ``$app['some_service']``, a new instance of the service is\ncreated.\n\nAccess container from closure\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nIn many cases you will want to access the service container from within a\nservice definition closure. For example when fetching services the current\nservice depends on.\n\nBecause of this, the container is passed to the closure as an argument::\n\n    $app['some_service'] = function ($app) {\n        return new Service($app['some_other_service'], $app['some_service.config']);\n    };\n\nHere you can see an example of Dependency Injection. ``some_service`` depends\non ``some_other_service`` and takes ``some_service.config`` as configuration\noptions. The dependency is only created when ``some_service`` is accessed, and\nit is possible to replace either of the dependencies by simply overriding\nthose definitions.\n\nGoing back to our initial example, here's how we could use the container\nto manage its dependencies::\n\n    $app['user.persist_path'] = '/tmp/users';\n    $app['user.persister'] = function ($app) {\n        return new JsonUserPersister($app['user.persist_path']);\n    };\n\n\nProtected closures\n~~~~~~~~~~~~~~~~~~\n\nBecause the container sees closures as factories for services, it will always\nexecute them when reading them.\n\nIn some cases you will however want to store a closure as a parameter, so that\nyou can fetch it and execute it yourself -- with your own arguments.\n\nThis is why Pimple allows you to protect your closures from being executed, by\nusing the ``protect`` method::\n\n    $app['closure_parameter'] = $app->protect(function ($a, $b) {\n        return $a + $b;\n    });\n\n    // will not execute the closure\n    $add = $app['closure_parameter'];\n\n    // calling it now\n    echo $add(2, 3);\n\nNote that protected closures do not get access to the container.\n\nCore services\n-------------\n\nSilex defines a range of services.\n\n* **request_stack**: Controls the lifecycle of requests, an instance of\n  `RequestStack <http://api.symfony.com/master/Symfony/Component/HttpFoundation/RequestStack.html>` _.\n  It gives you access to ``GET``, ``POST`` parameters and lots more!\n\n  Example usage::\n\n    $id = $app['request_stack']->getCurrentRequest()->get('id');\n\n  A request is only available when a request is being served; you can only\n  access it from within a controller, an application before/after middlewares,\n  or an error handler.\n\n* **routes**: The `RouteCollection\n  <http://api.symfony.com/master/Symfony/Component/Routing/RouteCollection.html>`_\n  that is used internally. You can add, modify, read routes.\n\n* **url_generator**: An instance of `UrlGenerator\n  <http://api.symfony.com/master/Symfony/Component/Routing/Generator/UrlGenerator.html>`_,\n  using the `RouteCollection\n  <http://api.symfony.com/master/Symfony/Component/Routing/RouteCollection.html>`_\n  that is provided through the ``routes`` service. It has a ``generate``\n  method, which takes the route name as an argument, followed by an array of\n  route parameters.\n\n* **controllers**: The ``Silex\\ControllerCollection`` that is used internally.\n  Check the :doc:`Internals chapter <internals>` for more information.\n\n* **dispatcher**: The `EventDispatcher\n  <http://api.symfony.com/master/Symfony/Component/EventDispatcher/EventDispatcher.html>`_\n  that is used internally. It is the core of the Symfony system and is used\n  quite a bit by Silex.\n\n* **resolver**: The `ControllerResolver\n  <http://api.symfony.com/master/Symfony/Component/HttpKernel/Controller/ControllerResolver.html>`_\n  that is used internally. It takes care of executing the controller with the\n  right arguments.\n\n* **kernel**: The `HttpKernel\n  <http://api.symfony.com/master/Symfony/Component/HttpKernel/HttpKernel.html>`_\n  that is used internally. The HttpKernel is the heart of Symfony, it takes a\n  Request as input and returns a Response as output.\n\n* **request_context**: The request context is a simplified representation of\n  the request that is used by the router and the URL generator.\n\n* **exception_handler**: The Exception handler is the default handler that is\n  used when you don't register one via the ``error()`` method or if your\n  handler does not return a Response. Disable it with\n  ``unset($app['exception_handler'])``.\n\n* **logger**: A `LoggerInterface <https://github.com/php-fig/log/blob/master/Psr/Log/LoggerInterface.php>`_ instance. By default, logging is\n  disabled as the value is set to ``null``. To enable logging you can either use\n  the :doc:`MonologServiceProvider <providers/monolog>` or define your own ``logger`` service that\n  conforms to the PSR logger interface.\n\nCore traits\n-----------\n\n* ``Silex\\Application\\UrlGeneratorTrait`` adds the following shortcuts:\n\n  * **path**: Generates a path.\n\n  * **url**: Generates an absolute URL.\n\n  .. code-block:: php\n\n      $app->path('homepage');\n      $app->url('homepage');\n\nCore parameters\n---------------\n\n* **request.http_port** (optional): Allows you to override the default port\n  for non-HTTPS URLs. If the current request is HTTP, it will always use the\n  current port.\n\n  Defaults to 80.\n\n  This parameter can be used when generating URLs.\n\n* **request.https_port** (optional): Allows you to override the default port\n  for HTTPS URLs. If the current request is HTTPS, it will always use the\n  current port.\n\n  Defaults to 443.\n\n  This parameter can be used when generating URLs.\n\n* **debug** (optional): Returns whether or not the application is running in\n  debug mode.\n\n  Defaults to false.\n\n* **charset** (optional): The charset to use for Responses.\n\n  Defaults to UTF-8.\n"
  },
  {
    "path": "doc/testing.rst",
    "content": "Testing\n=======\n\nBecause Silex is built on top of Symfony, it is very easy to write functional\ntests for your application. Functional tests are automated software tests that\nensure that your code is working correctly. They go through the user interface,\nusing a fake browser, and mimic the actions a user would do.\n\nWhy\n---\n\nIf you are not familiar with software tests, you may be wondering why you would\nneed this. Every time you make a change to your application, you have to test\nit. This means going through all the pages and making sure they are still\nworking. Functional tests save you a lot of time, because they enable you to\ntest your application in usually under a second by running a single command.\n\nFor more information on functional testing, unit testing, and automated\nsoftware tests in general, check out `PHPUnit\n<https://github.com/sebastianbergmann/phpunit>`_ and `Bulat Shakirzyanov's talk\non Clean Code <http://www.slideshare.net/avalanche123/clean-code-5609451>`_.\n\nPHPUnit\n-------\n\n`PHPUnit <https://github.com/sebastianbergmann/phpunit>`_ is the de-facto\nstandard testing framework for PHP. It was built for writing unit tests, but it\ncan be used for functional tests too. You write tests by creating a new class,\nthat extends the ``PHPUnit_Framework_TestCase``. Your test cases are methods\nprefixed with ``test``::\n\n    class ContactFormTest extends \\PHPUnit_Framework_TestCase\n    {\n        public function testInitialPage()\n        {\n            ...\n        }\n    }\n\nIn your test cases, you do assertions on the state of what you are testing. In\nthis case we are testing a contact form, so we would want to assert that the\npage loaded correctly and contains our form::\n\n        public function testInitialPage()\n        {\n            $statusCode = ...\n            $pageContent = ...\n\n            $this->assertEquals(200, $statusCode);\n            $this->assertContains('Contact us', $pageContent);\n            $this->assertContains('<form', $pageContent);\n        }\n\nHere you see some of the available assertions. There is a full list available\nin the `Writing Tests for PHPUnit\n<https://phpunit.de/manual/current/en/writing-tests-for-phpunit.html>`_\nsection of the PHPUnit documentation.\n\nWebTestCase\n-----------\n\nSymfony provides a WebTestCase class that can be used to write functional\ntests. The Silex version of this class is ``Silex\\WebTestCase``, and you can\nuse it by making your test extend it::\n\n    use Silex\\WebTestCase;\n\n    class ContactFormTest extends WebTestCase\n    {\n        ...\n    }\n\n.. caution::\n\n    If you need to override the ``setUp()`` method, don't forget to call the\n    parent (``parent::setUp()``) to call the Silex default setup.\n\n.. note::\n\n    If you want to use the Symfony ``WebTestCase`` class you will need to\n    explicitly install its dependencies for your project:\n\n    .. code-block:: bash\n\n        composer require --dev symfony/browser-kit symfony/css-selector\n\nFor your WebTestCase, you will have to implement a ``createApplication``\nmethod, which returns your application instance::\n\n        public function createApplication()\n        {\n            // app.php must return an Application instance\n            return require __DIR__.'/path/to/app.php';\n        }\n\nMake sure you do **not** use ``require_once`` here, as this method will be\nexecuted before every test.\n\n.. tip::\n\n    By default, the application behaves in the same way as when using it from a\n    browser. But when an error occurs, it is sometimes easier to get raw\n    exceptions instead of HTML pages. It is rather simple if you tweak the\n    application configuration in the ``createApplication()`` method like\n    follows::\n\n        public function createApplication()\n        {\n            $app = require __DIR__.'/path/to/app.php';\n            $app['debug'] = true;\n            unset($app['exception_handler']);\n\n            return $app;\n        }\n\n.. tip::\n\n    If your application use sessions, set ``session.test`` to ``true`` to\n    simulate sessions::\n\n        public function createApplication()\n        {\n            // ...\n\n            $app['session.test'] = true;\n\n            // ...\n        }\n\nThe WebTestCase provides a ``createClient`` method. A client acts as a browser,\nand allows you to interact with your application. Here's how it works::\n\n        public function testInitialPage()\n        {\n            $client = $this->createClient();\n            $crawler = $client->request('GET', '/');\n\n            $this->assertTrue($client->getResponse()->isOk());\n            $this->assertCount(1, $crawler->filter('h1:contains(\"Contact us\")'));\n            $this->assertCount(1, $crawler->filter('form'));\n            ...\n        }\n\nThere are several things going on here. You have both a ``Client`` and a\n``Crawler``.\n\nYou can also access the application through ``$this->app``.\n\nClient\n~~~~~~\n\nThe client represents a browser. It holds your browsing history, cookies and\nmore. The ``request`` method allows you to make a request to a page on your\napplication.\n\n.. note::\n\n    You can find some documentation for it in `the client section of the\n    testing chapter of the Symfony documentation\n    <http://symfony.com/doc/current/book/testing.html#the-test-client>`_.\n\nCrawler\n~~~~~~~\n\nThe crawler allows you to inspect the content of a page. You can filter it\nusing CSS expressions and lots more.\n\n.. note::\n\n    You can find some documentation for it in `the crawler section of the testing\n    chapter of the Symfony documentation\n    <http://symfony.com/doc/current/book/testing.html#the-test-client>`_.\n\nConfiguration\n-------------\n\nThe suggested way to configure PHPUnit is to create a ``phpunit.xml.dist``\nfile, a ``tests`` folder and your tests in\n``tests/YourApp/Tests/YourTest.php``. The ``phpunit.xml.dist`` file should\nlook like this:\n\n.. code-block:: xml\n\n    <?xml version=\"1.0\" encoding=\"UTF-8\"?>\n    <phpunit bootstrap=\"./vendor/autoload.php\"\n             backupGlobals=\"false\"\n             backupStaticAttributes=\"false\"\n             colors=\"true\"\n             convertErrorsToExceptions=\"true\"\n             convertNoticesToExceptions=\"true\"\n             convertWarningsToExceptions=\"true\"\n             processIsolation=\"false\"\n             stopOnFailure=\"false\"\n             syntaxCheck=\"false\"\n    >\n        <testsuites>\n            <testsuite name=\"YourApp Test Suite\">\n                <directory>./tests/</directory>\n            </testsuite>\n        </testsuites>\n    </phpunit>\n\nYour ``tests/YourApp/Tests/YourTest.php`` should look like this::\n\n    namespace YourApp\\Tests;\n\n    use Silex\\WebTestCase;\n\n    class YourTest extends WebTestCase\n    {\n        public function createApplication()\n        {\n            return require __DIR__.'/../../../app.php';\n        }\n\n        public function testFooBar()\n        {\n            ...\n        }\n    }\n\nNow, when running ``phpunit`` on the command line, tests should run.\n"
  },
  {
    "path": "doc/usage.rst",
    "content": "Usage\n=====\n\nInstallation\n------------\n\nIf you want to get started fast, `download`_ Silex as an archive and extract\nit, you should have the following directory structure:\n\n.. code-block:: text\n\n    ├── composer.json\n    ├── composer.lock\n    ├── vendor\n    │   └── ...\n    └── web\n        └── index.php\n\nIf you want more flexibility, use Composer_ instead:\n\n.. code-block:: bash\n\n    composer require silex/silex:~2.0\n\nWeb Server\n----------\n\nAll examples in the documentation rely on a well-configured web server; read\nthe :doc:`webserver documentation<web_servers>` to check yours.\n\nBootstrap\n---------\n\nTo bootstrap Silex, all you need to do is require the ``vendor/autoload.php``\nfile and create an instance of ``Silex\\Application``. After your controller\ndefinitions, call the ``run`` method on your application::\n\n    // web/index.php\n    require_once __DIR__.'/../vendor/autoload.php';\n\n    $app = new Silex\\Application();\n\n    // ... definitions\n\n    $app->run();\n\n.. tip::\n\n    When developing a website, you might want to turn on the debug mode to\n    ease debugging::\n\n        $app['debug'] = true;\n\n.. tip::\n\n    If your application is hosted behind a reverse proxy at address ``$ip``,\n    and you want Silex to trust the ``X-Forwarded-For*`` headers, you will\n    need to run your application like this::\n\n        use Symfony\\Component\\HttpFoundation\\Request;\n\n        Request::setTrustedProxies(array($ip));\n        $app->run();\n\nRouting\n-------\n\nIn Silex you define a route and the controller that is called when that\nroute is matched. A route pattern consists of:\n\n* *Pattern*: The route pattern defines a path that points to a resource. The\n  pattern can include variable parts and you are able to set RegExp\n  requirements for them.\n\n* *Method*: One of the following HTTP methods: ``GET``, ``POST``, ``PUT``,\n  ``DELETE``, ``PATCH``, or ``OPTIONS``. This describes the interaction with\n  the resource.\n\nThe controller is defined using a closure like this::\n\n    function () {\n        // ... do something\n    }\n\nThe return value of the closure becomes the content of the page.\n\nExample GET Route\n~~~~~~~~~~~~~~~~~\n\nHere is an example definition of a ``GET`` route::\n\n    $blogPosts = array(\n        1 => array(\n            'date'      => '2011-03-29',\n            'author'    => 'igorw',\n            'title'     => 'Using Silex',\n            'body'      => '...',\n        ),\n    );\n\n    $app->get('/blog', function () use ($blogPosts) {\n        $output = '';\n        foreach ($blogPosts as $post) {\n            $output .= $post['title'];\n            $output .= '<br />';\n        }\n\n        return $output;\n    });\n\nVisiting ``/blog`` will return a list of blog post titles. The ``use``\nstatement means something different in this context. It tells the closure to\nimport the ``$blogPosts`` variable from the outer scope. This allows you to use\nit from within the closure.\n\nDynamic Routing\n~~~~~~~~~~~~~~~\n\nNow, you can create another controller for viewing individual blog posts::\n\n    $app->get('/blog/{id}', function (Silex\\Application $app, $id) use ($blogPosts) {\n        if (!isset($blogPosts[$id])) {\n            $app->abort(404, \"Post $id does not exist.\");\n        }\n\n        $post = $blogPosts[$id];\n\n        return  \"<h1>{$post['title']}</h1>\".\n                \"<p>{$post['body']}</p>\";\n    });\n\nThis route definition has a variable ``{id}`` part which is passed to the\nclosure.\n\nThe current ``Application`` is automatically injected by Silex to the Closure\nthanks to the type hinting.\n\nWhen the post does not exist, you are using ``abort()`` to stop the request\nearly. It actually throws an exception, which you will see how to handle later\non.\n\nExample POST Route\n~~~~~~~~~~~~~~~~~~\n\nPOST routes signify the creation of a resource. An example for this is a\nfeedback form. You will use the ``mail`` function to send an e-mail::\n\n    use Symfony\\Component\\HttpFoundation\\Request;\n    use Symfony\\Component\\HttpFoundation\\Response;\n\n    $app->post('/feedback', function (Request $request) {\n        $message = $request->get('message');\n        mail('feedback@yoursite.com', '[YourSite] Feedback', $message);\n\n        return new Response('Thank you for your feedback!', 201);\n    });\n\nIt is pretty straightforward.\n\n.. note::\n\n    There is a :doc:`SwiftmailerServiceProvider <providers/swiftmailer>`\n    included that you can use instead of ``mail()``.\n\nThe current ``request`` is automatically injected by Silex to the Closure\nthanks to the type hinting. It is an instance of\nRequest_, so you can fetch variables using the request ``get`` method.\n\nInstead of returning a string you are returning an instance of Response_.\nThis allows setting an HTTP status code, in this case it is set to\n``201 Created``.\n\n.. note::\n\n    Silex always uses a ``Response`` internally, it converts strings to\n    responses with status code ``200``.\n\nOther methods\n~~~~~~~~~~~~~\n\nYou can create controllers for most HTTP methods. Just call one of these\nmethods on your application: ``get``, ``post``, ``put``, ``delete``, ``patch``, ``options``::\n\n    $app->put('/blog/{id}', function ($id) {\n        // ...\n    });\n\n    $app->delete('/blog/{id}', function ($id) {\n        // ...\n    });\n\n    $app->patch('/blog/{id}', function ($id) {\n        // ...\n    });\n\n.. tip::\n\n    Forms in most web browsers do not directly support the use of other HTTP\n    methods. To use methods other than GET and POST you can utilize a special\n    form field with a name of ``_method``. The form's ``method`` attribute must\n    be set to POST when using this field:\n\n    .. code-block:: html\n\n        <form action=\"/my/target/route/\" method=\"post\">\n            <!-- ... -->\n            <input type=\"hidden\" id=\"_method\" name=\"_method\" value=\"PUT\" />\n        </form>\n\n    You need to explicitly enable this method override::\n\n        use Symfony\\Component\\HttpFoundation\\Request;\n\n        Request::enableHttpMethodParameterOverride();\n        $app->run();\n\nYou can also call ``match``, which will match all methods. This can be\nrestricted via the ``method`` method::\n\n    $app->match('/blog', function () {\n        // ...\n    });\n\n    $app->match('/blog', function () {\n        // ...\n    })\n    ->method('PATCH');\n\n    $app->match('/blog', function () {\n        // ...\n    })\n    ->method('PUT|POST');\n\n.. note::\n\n    The order in which the routes are defined is significant. The first\n    matching route will be used, so place more generic routes at the bottom.\n\nRoute Variables\n~~~~~~~~~~~~~~~\n\nAs it has been shown before you can define variable parts in a route like\nthis::\n\n    $app->get('/blog/{id}', function ($id) {\n        // ...\n    });\n\nIt is also possible to have more than one variable part, just make sure the\nclosure arguments match the names of the variable parts::\n\n    $app->get('/blog/{postId}/{commentId}', function ($postId, $commentId) {\n        // ...\n    });\n\nWhile it's not recommended, you could also do this (note the switched\narguments)::\n\n    $app->get('/blog/{postId}/{commentId}', function ($commentId, $postId) {\n        // ...\n    });\n\nYou can also ask for the current Request and Application objects::\n\n    $app->get('/blog/{id}', function (Application $app, Request $request, $id) {\n        // ...\n    });\n\n.. note::\n\n    Note for the Application and Request objects, Silex does the injection\n    based on the type hinting and not on the variable name::\n\n        $app->get('/blog/{id}', function (Application $foo, Request $bar, $id) {\n            // ...\n        });\n\nRoute Variable Converters\n~~~~~~~~~~~~~~~~~~~~~~~~~\n\nBefore injecting the route variables into the controller, you can apply some\nconverters::\n\n    $app->get('/user/{id}', function ($id) {\n        // ...\n    })->convert('id', function ($id) { return (int) $id; });\n\nThis is useful when you want to convert route variables to objects as it\nallows to reuse the conversion code across different controllers::\n\n    $userProvider = function ($id) {\n        return new User($id);\n    };\n\n    $app->get('/user/{user}', function (User $user) {\n        // ...\n    })->convert('user', $userProvider);\n\n    $app->get('/user/{user}/edit', function (User $user) {\n        // ...\n    })->convert('user', $userProvider);\n\nThe converter callback also receives the ``Request`` as its second argument::\n\n    $callback = function ($post, Request $request) {\n        return new Post($request->attributes->get('slug'));\n    };\n\n    $app->get('/blog/{id}/{slug}', function (Post $post) {\n        // ...\n    })->convert('post', $callback);\n\nA converter can also be defined as a service. For example, here is a user\nconverter based on Doctrine ObjectManager::\n\n    use Doctrine\\Common\\Persistence\\ObjectManager;\n    use Symfony\\Component\\HttpKernel\\Exception\\NotFoundHttpException;\n\n    class UserConverter\n    {\n        private $om;\n\n        public function __construct(ObjectManager $om)\n        {\n            $this->om = $om;\n        }\n\n        public function convert($id)\n        {\n            if (null === $user = $this->om->find('User', (int) $id)) {\n                throw new NotFoundHttpException(sprintf('User %d does not exist', $id));\n            }\n\n            return $user;\n        }\n    }\n\nThe service will now be registered in the application, and the\n``convert()`` method will be used as converter (using the syntax\n``service_name:method_name``)::\n\n    $app['converter.user'] = function () {\n        return new UserConverter();\n    };\n\n    $app->get('/user/{user}', function (User $user) {\n        // ...\n    })->convert('user', 'converter.user:convert');\n\nRequirements\n~~~~~~~~~~~~\n\nIn some cases you may want to only match certain expressions. You can define\nrequirements using regular expressions by calling ``assert`` on the\n``Controller`` object, which is returned by the routing methods.\n\nThe following will make sure the ``id`` argument is a positive integer, since\n``\\d+`` matches any amount of digits::\n\n    $app->get('/blog/{id}', function ($id) {\n        // ...\n    })\n    ->assert('id', '\\d+');\n\nYou can also chain these calls::\n\n    $app->get('/blog/{postId}/{commentId}', function ($postId, $commentId) {\n        // ...\n    })\n    ->assert('postId', '\\d+')\n    ->assert('commentId', '\\d+');\n\nConditions\n~~~~~~~~~~\n\nBesides restricting route matching based on the HTTP method or parameter\nrequirements, you can set conditions on any part of the request by calling\n``when`` on the ``Controller`` object, which is returned by the routing\nmethods::\n\n    $app->get('/blog/{id}', function ($id) {\n        // ...\n    })\n    ->when(\"request.headers.get('User-Agent') matches '/firefox/i'\");\n\nThe ``when`` argument is a Symfony Expression_ , which means that you need to\nadd ``symfony/expression-language`` as a dependency of your project.\n\nDefault Values\n~~~~~~~~~~~~~~\n\nYou can define a default value for any route variable by calling ``value`` on\nthe ``Controller`` object::\n\n    $app->get('/{pageName}', function ($pageName) {\n        // ...\n    })\n    ->value('pageName', 'index');\n\nThis will allow matching ``/``, in which case the ``pageName`` variable will\nhave the value ``index``.\n\nNamed Routes\n~~~~~~~~~~~~\n\nSome providers can make use of named routes. By default Silex will generate an\ninternal route name for you but you can give an explicit route name by calling\n``bind``::\n\n    $app->get('/', function () {\n        // ...\n    })\n    ->bind('homepage');\n\n    $app->get('/blog/{id}', function ($id) {\n        // ...\n    })\n    ->bind('blog_post');\n\nControllers as Classes\n~~~~~~~~~~~~~~~~~~~~~~\n\nInstead of anonymous functions, you can also define your controllers as\nmethods. By using the ``ControllerClass::methodName`` syntax, you can tell\nSilex to lazily create the controller object for you::\n\n    $app->get('/', 'Acme\\\\Foo::bar');\n\n    use Silex\\Application;\n    use Symfony\\Component\\HttpFoundation\\Request;\n\n    namespace Acme\n    {\n        class Foo\n        {\n            public function bar(Request $request, Application $app)\n            {\n                // ...\n            }\n        }\n    }\n\nThis will load the ``Acme\\Foo`` class on demand, create an instance and call\nthe ``bar`` method to get the response. You can use ``Request`` and\n``Silex\\Application`` type hints to get ``$request`` and ``$app`` injected.\n\nIt is also possible to :doc:`define your controllers as services\n<providers/service_controller>`.\n\nGlobal Configuration\n--------------------\n\nIf a controller setting must be applied to **all** controllers (a converter, a\nmiddleware, a requirement, or a default value), configure it on\n``$app['controllers']``, which holds all application controllers::\n\n    $app['controllers']\n        ->value('id', '1')\n        ->assert('id', '\\d+')\n        ->requireHttps()\n        ->method('get')\n        ->convert('id', function () { /* ... */ })\n        ->before(function () { /* ... */ })\n        ->when('request.isSecure() == true')\n    ;\n\nThese settings are applied to already registered controllers and they become\nthe defaults for new controllers.\n\n.. note::\n\n    The global configuration does not apply to controller providers you might\n    mount as they have their own global configuration (read the\n    :doc:`dedicated chapter<organizing_controllers>` for more information).\n\nError Handlers\n--------------\n\nWhen an exception is thrown, error handlers allow you to display a custom\nerror page to the user. They can also be used to do additional things, such as\nlogging.\n\nTo register an error handler, pass a closure to the ``error`` method which\ntakes an ``Exception`` argument and returns a response::\n\n    use Symfony\\Component\\HttpFoundation\\Response;\n    use Symfony\\Component\\HttpFoundation\\Request;\n\n    $app->error(function (\\Exception $e, Request $request, $code) {\n        return new Response('We are sorry, but something went terribly wrong.');\n    });\n\nYou can also check for specific errors by using the ``$code`` argument, and\nhandle them differently::\n\n    use Symfony\\Component\\HttpFoundation\\Response;\n    use Symfony\\Component\\HttpFoundation\\Request;\n\n    $app->error(function (\\Exception $e, Request $request, $code) {\n        switch ($code) {\n            case 404:\n                $message = 'The requested page could not be found.';\n                break;\n            default:\n                $message = 'We are sorry, but something went terribly wrong.';\n        }\n\n        return new Response($message);\n    });\n\nYou can restrict an error handler to only handle some Exception classes by\nsetting a more specific type hint for the Closure argument::\n\n    use Symfony\\Component\\HttpFoundation\\Request;\n\n    $app->error(function (\\LogicException $e, Request $request, $code) {\n        // this handler will only handle \\LogicException exceptions\n        // and exceptions that extend \\LogicException\n    });\n\n.. note::\n\n    As Silex ensures that the Response status code is set to the most\n    appropriate one depending on the exception, setting the status on the\n    response won't work. If you want to overwrite the status code, set the\n    ``X-Status-Code`` header::\n\n        return new Response('Error', 404 /* ignored */, array('X-Status-Code' => 200));\n\nIf you want to use a separate error handler for logging, make sure you register\nit with a higher priority than response error handlers, because once a response\nis returned, the following handlers are ignored.\n\n.. note::\n\n    Silex ships with a provider for Monolog_ which handles logging of errors.\n    Check out the *Providers* :doc:`chapter <providers/monolog>` for details.\n\n.. tip::\n\n    Silex comes with a default error handler that displays a detailed error\n    message with the stack trace when **debug** is true, and a simple error\n    message otherwise. Error handlers registered via the ``error()`` method\n    always take precedence but you can keep the nice error messages when debug\n    is turned on like this::\n\n        use Symfony\\Component\\HttpFoundation\\Response;\n        use Symfony\\Component\\HttpFoundation\\Request;\n\n        $app->error(function (\\Exception $e, Request $request, $code) use ($app) {\n            if ($app['debug']) {\n                return;\n            }\n\n            // ... logic to handle the error and return a Response\n        });\n\nThe error handlers are also called when you use ``abort`` to abort a request\nearly::\n\n    $app->get('/blog/{id}', function (Silex\\Application $app, $id) use ($blogPosts) {\n        if (!isset($blogPosts[$id])) {\n            $app->abort(404, \"Post $id does not exist.\");\n        }\n\n        return new Response(...);\n    });\n\nYou can convert errors to ``Exceptions``, check out the cookbook :doc:`chapter <cookbook/error_handler>` for details.\n\nView Handlers\n-------------\n\nView Handlers allow you to intercept a controller result that is not a\n``Response`` and transform it before it gets returned to the kernel.\n\nTo register a view handler, pass a callable (or string that can be resolved to a\ncallable) to the ``view()`` method. The callable should accept some sort of result\nfrom the controller::\n\n    $app->view(function (array $controllerResult) use ($app) {\n        return $app->json($controllerResult);\n    });\n\nView Handlers also receive the ``Request`` as their second argument,\nmaking them a good candidate for basic content negotiation::\n\n    $app->view(function (array $controllerResult, Request $request) use ($app) {\n        $acceptHeader = $request->headers->get('Accept');\n        $bestFormat = $app['negotiator']->getBestFormat($acceptHeader, array('json', 'xml'));\n\n        if ('json' === $bestFormat) {\n            return new JsonResponse($controllerResult);\n        }\n\n        if ('xml' === $bestFormat) {\n            return $app['serializer.xml']->renderResponse($controllerResult);\n        }\n\n        return $controllerResult;\n    });\n\nView Handlers will be examined in the order they are added to the application\nand Silex will use type hints to determine if a view handler should be used for\nthe current result, continuously using the return value of the last view handler\nas the input for the next.\n\n.. note::\n\n    You must ensure that Silex receives a ``Response`` or a string as the result of\n    the last view handler (or controller) to be run.\n\nRedirects\n---------\n\nYou can redirect to another page by returning a ``RedirectResponse`` response,\nwhich you can create by calling the ``redirect`` method::\n\n    $app->get('/', function () use ($app) {\n        return $app->redirect('/hello');\n    });\n\nThis will redirect from ``/`` to ``/hello``.\n\nForwards\n--------\n\nWhen you want to delegate the rendering to another controller, without a\nround-trip to the browser (as for a redirect), use an internal sub-request::\n\n    use Symfony\\Component\\HttpFoundation\\Request;\n    use Symfony\\Component\\HttpKernel\\HttpKernelInterface;\n\n    $app->get('/', function () use ($app) {\n        // forward to /hello\n        $subRequest = Request::create('/hello', 'GET');\n\n        return $app->handle($subRequest, HttpKernelInterface::SUB_REQUEST);\n    });\n\n.. tip::\n\n    You can also generate the URI via the built-in URL generator::\n\n        $request = Request::create($app['url_generator']->generate('hello'), 'GET');\n\nThere's some more things that you need to keep in mind though. In most cases you\nwill want to forward some parts of the current master request to the sub-request.\nThat includes: Cookies, server information, session.\nRead more on :doc:`how to make sub-requests <cookbook/sub_requests>`.\n\nJSON\n----\n\nIf you want to return JSON data, you can use the ``json`` helper method.\nSimply pass it your data, status code and headers, and it will create a JSON\nresponse for you::\n\n    $app->get('/users/{id}', function ($id) use ($app) {\n        $user = getUser($id);\n\n        if (!$user) {\n            $error = array('message' => 'The user was not found.');\n\n            return $app->json($error, 404);\n        }\n\n        return $app->json($user);\n    });\n\nStreaming\n---------\n\nIt's possible to stream a response, which is important in cases when you don't\nwant to buffer the data being sent::\n\n    $app->get('/images/{file}', function ($file) use ($app) {\n        if (!file_exists(__DIR__.'/images/'.$file)) {\n            return $app->abort(404, 'The image was not found.');\n        }\n\n        $stream = function () use ($file) {\n            readfile($file);\n        };\n\n        return $app->stream($stream, 200, array('Content-Type' => 'image/png'));\n    });\n\nIf you need to send chunks, make sure you call ``ob_flush`` and ``flush``\nafter every chunk::\n\n    $stream = function () {\n        $fh = fopen('http://www.example.com/', 'rb');\n        while (!feof($fh)) {\n            echo fread($fh, 1024);\n            ob_flush();\n            flush();\n        }\n        fclose($fh);\n    };\n\nSending a file\n--------------\n\nIf you want to return a file, you can use the ``sendFile`` helper method.\nIt eases returning files that would otherwise not be publicly available. Simply\npass it your file path, status code, headers and the content disposition and it\nwill create a ``BinaryFileResponse`` response for you::\n\n    $app->get('/files/{path}', function ($path) use ($app) {\n        if (!file_exists('/base/path/' . $path)) {\n            $app->abort(404);\n        }\n\n        return $app->sendFile('/base/path/' . $path);\n    });\n\nTo further customize the response before returning it, check the API doc for\n`Symfony\\Component\\HttpFoundation\\BinaryFileResponse\n<http://api.symfony.com/master/Symfony/Component/HttpFoundation/BinaryFileResponse.html>`_::\n\n    return $app\n        ->sendFile('/base/path/' . $path)\n        ->setContentDisposition(ResponseHeaderBag::DISPOSITION_ATTACHMENT, 'pic.jpg')\n    ;\n\nTraits\n------\n\nSilex comes with PHP traits that define shortcut methods.\n\nAlmost all built-in service providers have some corresponding PHP traits. To\nuse them, define your own Application class and include the traits you want::\n\n    use Silex\\Application;\n\n    class MyApplication extends Application\n    {\n        use Application\\TwigTrait;\n        use Application\\SecurityTrait;\n        use Application\\FormTrait;\n        use Application\\UrlGeneratorTrait;\n        use Application\\SwiftmailerTrait;\n        use Application\\MonologTrait;\n        use Application\\TranslationTrait;\n    }\n\nYou can also define your own Route class and use some traits::\n\n    use Silex\\Route;\n\n    class MyRoute extends Route\n    {\n        use Route\\SecurityTrait;\n    }\n\nTo use your newly defined route, override the ``$app['route_class']``\nsetting::\n\n    $app['route_class'] = 'MyRoute';\n\nRead each provider chapter to learn more about the added methods.\n\nSecurity\n--------\n\nMake sure to protect your application against attacks.\n\nEscaping\n~~~~~~~~\n\nWhen outputting any user input, make sure to escape it correctly to prevent\nCross-Site-Scripting attacks.\n\n* **Escaping HTML**: PHP provides the ``htmlspecialchars`` function for this.\n  Silex provides a shortcut ``escape`` method::\n\n      use Symfony\\Component\\HttpFoundation\\Request;\n\n      $app->get('/name', function (Request $request, Silex\\Application $app) {\n          $name = $request->get('name');\n\n          return \"You provided the name {$app->escape($name)}.\";\n      });\n\n  If you use the Twig template engine, you should use its escaping or even\n  auto-escaping mechanisms. Check out the *Providers* :doc:`chapter <providers/twig>` for details.\n\n* **Escaping JSON**: If you want to provide data in JSON format you should\n  use the Silex ``json`` function::\n\n      use Symfony\\Component\\HttpFoundation\\Request;\n\n      $app->get('/name.json', function (Request $request, Silex\\Application $app) {\n          $name = $request->get('name');\n\n          return $app->json(array('name' => $name));\n      });\n\n.. _download: http://silex.sensiolabs.org/download\n.. _Composer: http://getcomposer.org/\n.. _Request: http://api.symfony.com/master/Symfony/Component/HttpFoundation/Request.html\n.. _Response: http://api.symfony.com/master/Symfony/Component/HttpFoundation/Response.html\n.. _Monolog: https://github.com/Seldaek/monolog\n.. _Expression: https://symfony.com/doc/current/book/routing.html#completely-customized-route-matching-with-conditions\n"
  },
  {
    "path": "doc/web_servers.rst",
    "content": "Webserver Configuration\n=======================\n\nApache\n------\n\nIf you are using Apache, make sure ``mod_rewrite`` is enabled and use the\nfollowing ``.htaccess`` file:\n\n.. code-block:: apache\n\n    <IfModule mod_rewrite.c>\n        Options -MultiViews\n\n        RewriteEngine On\n        #RewriteBase /path/to/app\n        RewriteCond %{REQUEST_FILENAME} !-d\n        RewriteCond %{REQUEST_FILENAME} !-f\n        RewriteRule ^ index.php [QSA,L]\n    </IfModule>\n\n.. note::\n\n    If your site is not at the webroot level you will have to uncomment the\n    ``RewriteBase`` statement and adjust the path to point to your directory,\n    relative from the webroot.\n\nAlternatively, if you use Apache 2.2.16 or higher, you can use the\n`FallbackResource directive`_ to make your .htaccess even easier:\n\n.. code-block:: apache\n\n    FallbackResource index.php\n\n.. note::\n\n    If your site is not at the webroot level you will have to adjust the path to\n    point to your directory, relative from the webroot.\n\nnginx\n-----\n\nThe **minimum configuration** to get your application running under Nginx is:\n\n.. code-block:: nginx\n\n    server {\n        server_name domain.tld www.domain.tld;\n        root /var/www/project/web;\n    \n        location / {\n            # try to serve file directly, fallback to front controller\n            try_files $uri /index.php$is_args$args;\n        }\n    \n        # If you have 2 front controllers for dev|prod use the following line instead\n        # location ~ ^/(index|index_dev)\\.php(/|$) {\n        location ~ ^/index\\.php(/|$) {\n            # the ubuntu default\n            fastcgi_pass   unix:/var/run/php/phpX.X-fpm.sock;\n            # for running on centos\n            #fastcgi_pass   unix:/var/run/php-fpm/www.sock;\n    \n            fastcgi_split_path_info ^(.+\\.php)(/.*)$;\n            include fastcgi_params;\n            fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;\n            fastcgi_param HTTPS off;\n        \n            # Prevents URIs that include the front controller. This will 404:\n            # http://domain.tld/index.php/some-path\n            # Enable the internal directive to disable URIs like this\n            # internal;\n        }\n\n        #return 404 for all php files as we do have a front controller\n        location ~ \\.php$ {\n            return 404;\n        }\n    \n        error_log /var/log/nginx/project_error.log;\n        access_log /var/log/nginx/project_access.log;\n    }\n\nIIS\n---\n\nIf you are using the Internet Information Services from Windows, you can use\nthis sample ``web.config`` file:\n\n.. code-block:: xml\n\n    <?xml version=\"1.0\"?>\n    <configuration>\n        <system.webServer>\n            <defaultDocument>\n                <files>\n                    <clear />\n                    <add value=\"index.php\" />\n                </files>\n            </defaultDocument>\n            <rewrite>\n                <rules>\n                    <rule name=\"Silex Front Controller\" stopProcessing=\"true\">\n                        <match url=\"^(.*)$\" ignoreCase=\"false\" />\n                        <conditions logicalGrouping=\"MatchAll\">\n                            <add input=\"{REQUEST_FILENAME}\" matchType=\"IsFile\" ignoreCase=\"false\" negate=\"true\" />\n                        </conditions>\n                        <action type=\"Rewrite\" url=\"index.php\" appendQueryString=\"true\" />\n                    </rule>\n                </rules>\n            </rewrite>\n        </system.webServer>\n    </configuration>\n\nLighttpd\n--------\n\nIf you are using lighttpd, use this sample ``simple-vhost`` as a starting\npoint:\n\n.. code-block:: lighttpd\n\n    server.document-root = \"/path/to/app\"\n\n    url.rewrite-once = (\n        # configure some static files\n        \"^/assets/.+\" => \"$0\",\n        \"^/favicon\\.ico$\" => \"$0\",\n\n        \"^(/[^\\?]*)(\\?.*)?\" => \"/index.php$1$2\"\n    )\n\n.. _FallbackResource directive: http://www.adayinthelifeof.nl/2012/01/21/apaches-fallbackresource-your-new-htaccess-command/\n\nPHP\n---\n\nPHP ships with a built-in webserver for development. This server allows you to\nrun silex without any configuration. However, in order to serve static files,\nyou'll have to make sure your front controller returns false in that case::\n\n    // web/index.php\n\n    $filename = __DIR__.preg_replace('#(\\?.*)$#', '', $_SERVER['REQUEST_URI']);\n    if (php_sapi_name() === 'cli-server' && is_file($filename)) {\n        return false;\n    }\n\n    $app = require __DIR__.'/../src/app.php';\n    $app->run();\n\n\nAssuming your front controller is at ``web/index.php``, you can start the\nserver from the command-line with this command:\n\n.. code-block:: text\n\n    $ php -S localhost:8080 -t web web/index.php\n\nNow the application should be running at ``http://localhost:8080``.\n\n.. note::\n\n    This server is for development only. It is **not** recommended to use it\n    in production.\n"
  },
  {
    "path": "phpunit.xml.dist",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\n<phpunit backupGlobals=\"false\"\n         backupStaticAttributes=\"false\"\n         colors=\"true\"\n         convertErrorsToExceptions=\"true\"\n         convertNoticesToExceptions=\"true\"\n         convertWarningsToExceptions=\"true\"\n         processIsolation=\"false\"\n         stopOnFailure=\"false\"\n         syntaxCheck=\"false\"\n         bootstrap=\"vendor/autoload.php\"\n>\n    <testsuites>\n        <testsuite name=\"Silex Test Suite\">\n            <directory>./tests/Silex/</directory>\n        </testsuite>\n    </testsuites>\n    <filter>\n        <whitelist>\n            <directory>./src</directory>\n        </whitelist>\n    </filter>\n</phpunit>\n"
  },
  {
    "path": "src/Silex/Api/BootableProviderInterface.php",
    "content": "<?php\n\n/*\n * This file is part of the Silex framework.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Silex\\Api;\n\nuse Silex\\Application;\n\n/**\n * Interface for bootable service providers.\n *\n * @author Fabien Potencier <fabien@symfony.com>\n */\ninterface BootableProviderInterface\n{\n    /**\n     * Bootstraps the application.\n     *\n     * This method is called after all services are registered\n     * and should be used for \"dynamic\" configuration (whenever\n     * a service must be requested).\n     *\n     * @param Application $app\n     */\n    public function boot(Application $app);\n}\n"
  },
  {
    "path": "src/Silex/Api/ControllerProviderInterface.php",
    "content": "<?php\n\n/*\n * This file is part of the Silex framework.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Silex\\Api;\n\nuse Silex\\Application;\nuse Silex\\ControllerCollection;\n\n/**\n * Interface for controller providers.\n *\n * @author Fabien Potencier <fabien@symfony.com>\n */\ninterface ControllerProviderInterface\n{\n    /**\n     * Returns routes to connect to the given application.\n     *\n     * @param Application $app An Application instance\n     *\n     * @return ControllerCollection A ControllerCollection instance\n     */\n    public function connect(Application $app);\n}\n"
  },
  {
    "path": "src/Silex/Api/EventListenerProviderInterface.php",
    "content": "<?php\n\n/*\n * This file is part of the Silex framework.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Silex\\Api;\n\nuse Symfony\\Component\\EventDispatcher\\EventDispatcherInterface;\nuse Pimple\\Container;\n\n/**\n * Interface for event listener providers.\n *\n * @author Fabien Potencier <fabien@symfony.com>\n */\ninterface EventListenerProviderInterface\n{\n    public function subscribe(Container $app, EventDispatcherInterface $dispatcher);\n}\n"
  },
  {
    "path": "src/Silex/Api/LICENSE",
    "content": "Copyright (c) 2010-2015 Fabien Potencier\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is furnished\nto do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n"
  },
  {
    "path": "src/Silex/Api/composer.json",
    "content": "{\n    \"minimum-stability\": \"dev\",\n    \"name\": \"silex/api\",\n    \"description\": \"The Silex interfaces\",\n    \"keywords\": [\"microframework\"],\n    \"homepage\": \"http://silex.sensiolabs.org\",\n    \"license\": \"MIT\",\n    \"authors\": [\n        {\n            \"name\": \"Fabien Potencier\",\n            \"email\": \"fabien@symfony.com\"\n        },\n        {\n            \"name\": \"Igor Wiedler\",\n            \"email\": \"igor@wiedler.ch\"\n        }\n    ],\n    \"require\": {\n        \"php\": \">=5.5.9\",\n        \"pimple/pimple\": \"~3.0\"\n    },\n    \"suggest\": {\n        \"symfony/event-dispatcher\": \"For EventListenerProviderInterface\",\n        \"silex/silex\": \"For BootableProviderInterface and ControllerProviderInterface\"\n    },\n    \"autoload\": {\n        \"psr-4\": { \"Silex\\\\Api\\\\\": \"\" }\n    },\n    \"extra\": {\n        \"branch-alias\": {\n            \"dev-master\": \"2.0.x-dev\"\n        }\n    }\n}\n"
  },
  {
    "path": "src/Silex/AppArgumentValueResolver.php",
    "content": "<?php\n\n/*\n * This file is part of the Silex framework.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Silex;\n\nuse Symfony\\Component\\HttpFoundation\\Request;\nuse Symfony\\Component\\HttpKernel\\Controller\\ArgumentValueResolverInterface;\nuse Symfony\\Component\\HttpKernel\\ControllerMetadata\\ArgumentMetadata;\n\n/**\n * HttpKernel Argument Resolver for Silex.\n *\n * @author Romain Neutron <imprec@gmail.com>\n */\nclass AppArgumentValueResolver implements ArgumentValueResolverInterface\n{\n    private $app;\n\n    public function __construct(Application $app)\n    {\n        $this->app = $app;\n    }\n\n    /**\n     * {@inheritdoc}\n     */\n    public function supports(Request $request, ArgumentMetadata $argument)\n    {\n        return null !== $argument->getType() && ($argument->getType() === Application::class || is_subclass_of($argument->getType(), Application::class));\n    }\n\n    /**\n     * {@inheritdoc}\n     */\n    public function resolve(Request $request, ArgumentMetadata $argument)\n    {\n        yield $this->app;\n    }\n}\n"
  },
  {
    "path": "src/Silex/Application/FormTrait.php",
    "content": "<?php\n\n/*\n * This file is part of the Silex framework.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Silex\\Application;\n\nuse Symfony\\Component\\Form;\nuse Symfony\\Component\\Form\\Extension\\Core\\Type\\FormType;\nuse Symfony\\Component\\Form\\FormBuilder;\nuse Symfony\\Component\\OptionsResolver\\OptionsResolver\\FormTypeInterface;\n\n/**\n * Form trait.\n *\n * @author Fabien Potencier <fabien@symfony.com>\n * @author David Berlioz <berliozdavid@gmail.com>\n */\ntrait FormTrait\n{\n    /**\n     * Creates and returns a form builder instance.\n     *\n     * @param mixed                    $data    The initial data for the form\n     * @param array                    $options Options for the form\n     * @param string|FormTypeInterface $type    Type of the form\n     *\n     * @return FormBuilder\n     */\n    public function form($data = null, array $options = array(), $type = null)\n    {\n        return $this['form.factory']->createBuilder($type ?: FormType::class, $data, $options);\n    }\n\n    /**\n     * Creates and returns a named form builder instance.\n     *\n     * @param string                   $name\n     * @param mixed                    $data    The initial data for the form\n     * @param array                    $options Options for the form\n     * @param string|FormTypeInterface $type    Type of the form\n     *\n     * @return FormBuilder\n     */\n    public function namedForm($name, $data = null, array $options = array(), $type = null)\n    {\n        return $this['form.factory']->createNamedBuilder($name, $type ?: FormType::class, $data, $options);\n    }\n}\n"
  },
  {
    "path": "src/Silex/Application/MonologTrait.php",
    "content": "<?php\n\n/*\n * This file is part of the Silex framework.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Silex\\Application;\n\nuse Monolog\\Logger;\n\n/**\n * Monolog trait.\n *\n * @author Fabien Potencier <fabien@symfony.com>\n */\ntrait MonologTrait\n{\n    /**\n     * Adds a log record.\n     *\n     * @param string $message The log message\n     * @param array  $context The log context\n     * @param int    $level   The logging level\n     *\n     * @return bool Whether the record has been processed\n     */\n    public function log($message, array $context = array(), $level = Logger::INFO)\n    {\n        return $this['monolog']->addRecord($level, $message, $context);\n    }\n}\n"
  },
  {
    "path": "src/Silex/Application/SecurityTrait.php",
    "content": "<?php\n\n/*\n * This file is part of the Silex framework.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Silex\\Application;\n\nuse Symfony\\Component\\Security\\Core\\Exception\\AuthenticationCredentialsNotFoundException;\nuse Symfony\\Component\\Security\\Core\\User\\UserInterface;\n\n/**\n * Security trait.\n *\n * @author Fabien Potencier <fabien@symfony.com>\n */\ntrait SecurityTrait\n{\n    /**\n     * Encodes the raw password.\n     *\n     * @param UserInterface $user     A UserInterface instance\n     * @param string        $password The password to encode\n     *\n     * @return string The encoded password\n     *\n     * @throws \\RuntimeException when no password encoder could be found for the user\n     */\n    public function encodePassword(UserInterface $user, $password)\n    {\n        return $this['security.encoder_factory']->getEncoder($user)->encodePassword($password, $user->getSalt());\n    }\n\n    /**\n     * Checks if the attributes are granted against the current authentication token and optionally supplied object.\n     *\n     * @param mixed $attributes\n     * @param mixed $object\n     *\n     * @return bool\n     *\n     * @throws AuthenticationCredentialsNotFoundException when the token storage has no authentication token.\n     */\n    public function isGranted($attributes, $object = null)\n    {\n        return $this['security.authorization_checker']->isGranted($attributes, $object);\n    }\n}\n"
  },
  {
    "path": "src/Silex/Application/SwiftmailerTrait.php",
    "content": "<?php\n\n/*\n * This file is part of the Silex framework.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Silex\\Application;\n\n/**\n * Swiftmailer trait.\n *\n * @author Fabien Potencier <fabien@symfony.com>\n */\ntrait SwiftmailerTrait\n{\n    /**\n     * Sends an email.\n     *\n     * @param \\Swift_Message $message          A \\Swift_Message instance\n     * @param array          $failedRecipients An array of failures by-reference\n     *\n     * @return int The number of sent messages\n     */\n    public function mail(\\Swift_Message $message, &$failedRecipients = null)\n    {\n        return $this['mailer']->send($message, $failedRecipients);\n    }\n}\n"
  },
  {
    "path": "src/Silex/Application/TranslationTrait.php",
    "content": "<?php\n\n/*\n * This file is part of the Silex framework.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Silex\\Application;\n\n/**\n * Translation trait.\n *\n * @author Fabien Potencier <fabien@symfony.com>\n */\ntrait TranslationTrait\n{\n    /**\n     * Translates the given message.\n     *\n     * @param string $id         The message id\n     * @param array  $parameters An array of parameters for the message\n     * @param string $domain     The domain for the message\n     * @param string $locale     The locale\n     *\n     * @return string The translated string\n     */\n    public function trans($id, array $parameters = array(), $domain = 'messages', $locale = null)\n    {\n        return $this['translator']->trans($id, $parameters, $domain, $locale);\n    }\n\n    /**\n     * Translates the given choice message by choosing a translation according to a number.\n     *\n     * @param string $id         The message id\n     * @param int    $number     The number to use to find the indice of the message\n     * @param array  $parameters An array of parameters for the message\n     * @param string $domain     The domain for the message\n     * @param string $locale     The locale\n     *\n     * @return string The translated string\n     */\n    public function transChoice($id, $number, array $parameters = array(), $domain = 'messages', $locale = null)\n    {\n        return $this['translator']->transChoice($id, $number, $parameters, $domain, $locale);\n    }\n}\n"
  },
  {
    "path": "src/Silex/Application/TwigTrait.php",
    "content": "<?php\n\n/*\n * This file is part of the Silex framework.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Silex\\Application;\n\nuse Symfony\\Component\\HttpFoundation\\Response;\nuse Symfony\\Component\\HttpFoundation\\StreamedResponse;\n\n/**\n * Twig trait.\n *\n * @author Fabien Potencier <fabien@symfony.com>\n */\ntrait TwigTrait\n{\n    /**\n     * Renders a view and returns a Response.\n     *\n     * To stream a view, pass an instance of StreamedResponse as a third argument.\n     *\n     * @param string   $view       The view name\n     * @param array    $parameters An array of parameters to pass to the view\n     * @param Response $response   A Response instance\n     *\n     * @return Response A Response instance\n     */\n    public function render($view, array $parameters = array(), Response $response = null)\n    {\n        $twig = $this['twig'];\n\n        if ($response instanceof StreamedResponse) {\n            $response->setCallback(function () use ($twig, $view, $parameters) {\n                $twig->display($view, $parameters);\n            });\n        } else {\n            if (null === $response) {\n                $response = new Response();\n            }\n            $response->setContent($twig->render($view, $parameters));\n        }\n\n        return $response;\n    }\n\n    /**\n     * Renders a view.\n     *\n     * @param string $view       The view name\n     * @param array  $parameters An array of parameters to pass to the view\n     *\n     * @return string The rendered view\n     */\n    public function renderView($view, array $parameters = array())\n    {\n        return $this['twig']->render($view, $parameters);\n    }\n}\n"
  },
  {
    "path": "src/Silex/Application/UrlGeneratorTrait.php",
    "content": "<?php\n\n/*\n * This file is part of the Silex framework.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Silex\\Application;\n\nuse Symfony\\Component\\Routing\\Generator\\UrlGeneratorInterface;\n\n/**\n * UrlGenerator trait.\n *\n * @author Fabien Potencier <fabien@symfony.com>\n */\ntrait UrlGeneratorTrait\n{\n    /**\n     * Generates a path from the given parameters.\n     *\n     * @param string $route      The name of the route\n     * @param mixed  $parameters An array of parameters\n     *\n     * @return string The generated path\n     */\n    public function path($route, $parameters = array())\n    {\n        return $this['url_generator']->generate($route, $parameters, UrlGeneratorInterface::ABSOLUTE_PATH);\n    }\n\n    /**\n     * Generates an absolute URL from the given parameters.\n     *\n     * @param string $route      The name of the route\n     * @param mixed  $parameters An array of parameters\n     *\n     * @return string The generated URL\n     */\n    public function url($route, $parameters = array())\n    {\n        return $this['url_generator']->generate($route, $parameters, UrlGeneratorInterface::ABSOLUTE_URL);\n    }\n}\n"
  },
  {
    "path": "src/Silex/Application.php",
    "content": "<?php\n\n/*\n * This file is part of the Silex framework.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Silex;\n\nuse Pimple\\Container;\nuse Pimple\\ServiceProviderInterface;\nuse Symfony\\Component\\EventDispatcher\\EventDispatcherInterface;\nuse Symfony\\Component\\HttpFoundation\\BinaryFileResponse;\nuse Symfony\\Component\\HttpKernel\\HttpKernelInterface;\nuse Symfony\\Component\\HttpKernel\\TerminableInterface;\nuse Symfony\\Component\\HttpKernel\\Event\\FilterResponseEvent;\nuse Symfony\\Component\\HttpKernel\\Event\\GetResponseEvent;\nuse Symfony\\Component\\HttpKernel\\Event\\PostResponseEvent;\nuse Symfony\\Component\\HttpKernel\\Exception\\HttpException;\nuse Symfony\\Component\\HttpKernel\\KernelEvents;\nuse Symfony\\Component\\HttpFoundation\\Request;\nuse Symfony\\Component\\HttpFoundation\\Response;\nuse Symfony\\Component\\HttpFoundation\\RedirectResponse;\nuse Symfony\\Component\\HttpFoundation\\StreamedResponse;\nuse Symfony\\Component\\HttpFoundation\\JsonResponse;\nuse Silex\\Api\\BootableProviderInterface;\nuse Silex\\Api\\EventListenerProviderInterface;\nuse Silex\\Api\\ControllerProviderInterface;\nuse Silex\\Provider\\ExceptionHandlerServiceProvider;\nuse Silex\\Provider\\RoutingServiceProvider;\nuse Silex\\Provider\\HttpKernelServiceProvider;\n\n/**\n * The Silex framework class.\n *\n * @author Fabien Potencier <fabien@symfony.com>\n */\nclass Application extends Container implements HttpKernelInterface, TerminableInterface\n{\n    const VERSION = '2.0.4-DEV';\n\n    const EARLY_EVENT = 512;\n    const LATE_EVENT = -512;\n\n    protected $providers = array();\n    protected $booted = false;\n\n    /**\n     * Instantiate a new Application.\n     *\n     * Objects and parameters can be passed as argument to the constructor.\n     *\n     * @param array $values The parameters or objects.\n     */\n    public function __construct(array $values = array())\n    {\n        parent::__construct();\n\n        $this['request.http_port'] = 80;\n        $this['request.https_port'] = 443;\n        $this['debug'] = false;\n        $this['charset'] = 'UTF-8';\n        $this['logger'] = null;\n\n        $this->register(new HttpKernelServiceProvider());\n        $this->register(new RoutingServiceProvider());\n        $this->register(new ExceptionHandlerServiceProvider());\n\n        foreach ($values as $key => $value) {\n            $this[$key] = $value;\n        }\n    }\n\n    /**\n     * Registers a service provider.\n     *\n     * @param ServiceProviderInterface $provider A ServiceProviderInterface instance\n     * @param array                    $values   An array of values that customizes the provider\n     *\n     * @return Application\n     */\n    public function register(ServiceProviderInterface $provider, array $values = array())\n    {\n        $this->providers[] = $provider;\n\n        parent::register($provider, $values);\n\n        return $this;\n    }\n\n    /**\n     * Boots all service providers.\n     *\n     * This method is automatically called by handle(), but you can use it\n     * to boot all service providers when not handling a request.\n     */\n    public function boot()\n    {\n        if ($this->booted) {\n            return;\n        }\n\n        $this->booted = true;\n\n        foreach ($this->providers as $provider) {\n            if ($provider instanceof EventListenerProviderInterface) {\n                $provider->subscribe($this, $this['dispatcher']);\n            }\n\n            if ($provider instanceof BootableProviderInterface) {\n                $provider->boot($this);\n            }\n        }\n    }\n\n    /**\n     * Maps a pattern to a callable.\n     *\n     * You can optionally specify HTTP methods that should be matched.\n     *\n     * @param string $pattern Matched route pattern\n     * @param mixed  $to      Callback that returns the response when matched\n     *\n     * @return Controller\n     */\n    public function match($pattern, $to = null)\n    {\n        return $this['controllers']->match($pattern, $to);\n    }\n\n    /**\n     * Maps a GET request to a callable.\n     *\n     * @param string $pattern Matched route pattern\n     * @param mixed  $to      Callback that returns the response when matched\n     *\n     * @return Controller\n     */\n    public function get($pattern, $to = null)\n    {\n        return $this['controllers']->get($pattern, $to);\n    }\n\n    /**\n     * Maps a POST request to a callable.\n     *\n     * @param string $pattern Matched route pattern\n     * @param mixed  $to      Callback that returns the response when matched\n     *\n     * @return Controller\n     */\n    public function post($pattern, $to = null)\n    {\n        return $this['controllers']->post($pattern, $to);\n    }\n\n    /**\n     * Maps a PUT request to a callable.\n     *\n     * @param string $pattern Matched route pattern\n     * @param mixed  $to      Callback that returns the response when matched\n     *\n     * @return Controller\n     */\n    public function put($pattern, $to = null)\n    {\n        return $this['controllers']->put($pattern, $to);\n    }\n\n    /**\n     * Maps a DELETE request to a callable.\n     *\n     * @param string $pattern Matched route pattern\n     * @param mixed  $to      Callback that returns the response when matched\n     *\n     * @return Controller\n     */\n    public function delete($pattern, $to = null)\n    {\n        return $this['controllers']->delete($pattern, $to);\n    }\n\n    /**\n     * Maps an OPTIONS request to a callable.\n     *\n     * @param string $pattern Matched route pattern\n     * @param mixed  $to      Callback that returns the response when matched\n     *\n     * @return Controller\n     */\n    public function options($pattern, $to = null)\n    {\n        return $this['controllers']->options($pattern, $to);\n    }\n\n    /**\n     * Maps a PATCH request to a callable.\n     *\n     * @param string $pattern Matched route pattern\n     * @param mixed  $to      Callback that returns the response when matched\n     *\n     * @return Controller\n     */\n    public function patch($pattern, $to = null)\n    {\n        return $this['controllers']->patch($pattern, $to);\n    }\n\n    /**\n     * Adds an event listener that listens on the specified events.\n     *\n     * @param string   $eventName The event to listen on\n     * @param callable $callback  The listener\n     * @param int      $priority  The higher this value, the earlier an event\n     *                            listener will be triggered in the chain (defaults to 0)\n     */\n    public function on($eventName, $callback, $priority = 0)\n    {\n        if ($this->booted) {\n            $this['dispatcher']->addListener($eventName, $this['callback_resolver']->resolveCallback($callback), $priority);\n\n            return;\n        }\n\n        $this->extend('dispatcher', function (EventDispatcherInterface $dispatcher, $app) use ($callback, $priority, $eventName) {\n            $dispatcher->addListener($eventName, $app['callback_resolver']->resolveCallback($callback), $priority);\n\n            return $dispatcher;\n        });\n    }\n\n    /**\n     * Registers a before filter.\n     *\n     * Before filters are run before any route has been matched.\n     *\n     * @param mixed $callback Before filter callback\n     * @param int   $priority The higher this value, the earlier an event\n     *                        listener will be triggered in the chain (defaults to 0)\n     */\n    public function before($callback, $priority = 0)\n    {\n        $app = $this;\n\n        $this->on(KernelEvents::REQUEST, function (GetResponseEvent $event) use ($callback, $app) {\n            if (!$event->isMasterRequest()) {\n                return;\n            }\n\n            $ret = call_user_func($app['callback_resolver']->resolveCallback($callback), $event->getRequest(), $app);\n\n            if ($ret instanceof Response) {\n                $event->setResponse($ret);\n            }\n        }, $priority);\n    }\n\n    /**\n     * Registers an after filter.\n     *\n     * After filters are run after the controller has been executed.\n     *\n     * @param mixed $callback After filter callback\n     * @param int   $priority The higher this value, the earlier an event\n     *                        listener will be triggered in the chain (defaults to 0)\n     */\n    public function after($callback, $priority = 0)\n    {\n        $app = $this;\n\n        $this->on(KernelEvents::RESPONSE, function (FilterResponseEvent $event) use ($callback, $app) {\n            if (!$event->isMasterRequest()) {\n                return;\n            }\n\n            $response = call_user_func($app['callback_resolver']->resolveCallback($callback), $event->getRequest(), $event->getResponse(), $app);\n            if ($response instanceof Response) {\n                $event->setResponse($response);\n            } elseif (null !== $response) {\n                throw new \\RuntimeException('An after middleware returned an invalid response value. Must return null or an instance of Response.');\n            }\n        }, $priority);\n    }\n\n    /**\n     * Registers a finish filter.\n     *\n     * Finish filters are run after the response has been sent.\n     *\n     * @param mixed $callback Finish filter callback\n     * @param int   $priority The higher this value, the earlier an event\n     *                        listener will be triggered in the chain (defaults to 0)\n     */\n    public function finish($callback, $priority = 0)\n    {\n        $app = $this;\n\n        $this->on(KernelEvents::TERMINATE, function (PostResponseEvent $event) use ($callback, $app) {\n            call_user_func($app['callback_resolver']->resolveCallback($callback), $event->getRequest(), $event->getResponse(), $app);\n        }, $priority);\n    }\n\n    /**\n     * Aborts the current request by sending a proper HTTP error.\n     *\n     * @param int    $statusCode The HTTP status code\n     * @param string $message    The status message\n     * @param array  $headers    An array of HTTP headers\n     */\n    public function abort($statusCode, $message = '', array $headers = array())\n    {\n        throw new HttpException($statusCode, $message, null, $headers);\n    }\n\n    /**\n     * Registers an error handler.\n     *\n     * Error handlers are simple callables which take a single Exception\n     * as an argument. If a controller throws an exception, an error handler\n     * can return a specific response.\n     *\n     * When an exception occurs, all handlers will be called, until one returns\n     * something (a string or a Response object), at which point that will be\n     * returned to the client.\n     *\n     * For this reason you should add logging handlers before output handlers.\n     *\n     * @param mixed $callback Error handler callback, takes an Exception argument\n     * @param int   $priority The higher this value, the earlier an event\n     *                        listener will be triggered in the chain (defaults to -8)\n     */\n    public function error($callback, $priority = -8)\n    {\n        $this->on(KernelEvents::EXCEPTION, new ExceptionListenerWrapper($this, $callback), $priority);\n    }\n\n    /**\n     * Registers a view handler.\n     *\n     * View handlers are simple callables which take a controller result and the\n     * request as arguments, whenever a controller returns a value that is not\n     * an instance of Response. When this occurs, all suitable handlers will be\n     * called, until one returns a Response object.\n     *\n     * @param mixed $callback View handler callback\n     * @param int   $priority The higher this value, the earlier an event\n     *                        listener will be triggered in the chain (defaults to 0)\n     */\n    public function view($callback, $priority = 0)\n    {\n        $this->on(KernelEvents::VIEW, new ViewListenerWrapper($this, $callback), $priority);\n    }\n\n    /**\n     * Flushes the controller collection.\n     */\n    public function flush()\n    {\n        $this['routes']->addCollection($this['controllers']->flush());\n    }\n\n    /**\n     * Redirects the user to another URL.\n     *\n     * @param string $url    The URL to redirect to\n     * @param int    $status The status code (302 by default)\n     *\n     * @return RedirectResponse\n     */\n    public function redirect($url, $status = 302)\n    {\n        return new RedirectResponse($url, $status);\n    }\n\n    /**\n     * Creates a streaming response.\n     *\n     * @param mixed $callback A valid PHP callback\n     * @param int   $status   The response status code\n     * @param array $headers  An array of response headers\n     *\n     * @return StreamedResponse\n     */\n    public function stream($callback = null, $status = 200, array $headers = array())\n    {\n        return new StreamedResponse($callback, $status, $headers);\n    }\n\n    /**\n     * Escapes a text for HTML.\n     *\n     * @param string $text         The input text to be escaped\n     * @param int    $flags        The flags (@see htmlspecialchars)\n     * @param string $charset      The charset\n     * @param bool   $doubleEncode Whether to try to avoid double escaping or not\n     *\n     * @return string Escaped text\n     */\n    public function escape($text, $flags = ENT_COMPAT, $charset = null, $doubleEncode = true)\n    {\n        return htmlspecialchars($text, $flags, $charset ?: $this['charset'], $doubleEncode);\n    }\n\n    /**\n     * Convert some data into a JSON response.\n     *\n     * @param mixed $data    The response data\n     * @param int   $status  The response status code\n     * @param array $headers An array of response headers\n     *\n     * @return JsonResponse\n     */\n    public function json($data = array(), $status = 200, array $headers = array())\n    {\n        return new JsonResponse($data, $status, $headers);\n    }\n\n    /**\n     * Sends a file.\n     *\n     * @param \\SplFileInfo|string $file               The file to stream\n     * @param int                 $status             The response status code\n     * @param array               $headers            An array of response headers\n     * @param null|string         $contentDisposition The type of Content-Disposition to set automatically with the filename\n     *\n     * @return BinaryFileResponse\n     */\n    public function sendFile($file, $status = 200, array $headers = array(), $contentDisposition = null)\n    {\n        return new BinaryFileResponse($file, $status, $headers, true, $contentDisposition);\n    }\n\n    /**\n     * Mounts controllers under the given route prefix.\n     *\n     * @param string                                                    $prefix      The route prefix\n     * @param ControllerCollection|callable|ControllerProviderInterface $controllers A ControllerCollection, a callable, or a ControllerProviderInterface instance\n     *\n     * @return Application\n     *\n     * @throws \\LogicException\n     */\n    public function mount($prefix, $controllers)\n    {\n        if ($controllers instanceof ControllerProviderInterface) {\n            $connectedControllers = $controllers->connect($this);\n\n            if (!$connectedControllers instanceof ControllerCollection) {\n                throw new \\LogicException(sprintf('The method \"%s::connect\" must return a \"ControllerCollection\" instance. Got: \"%s\"', get_class($controllers), is_object($connectedControllers) ? get_class($connectedControllers) : gettype($connectedControllers)));\n            }\n\n            $controllers = $connectedControllers;\n        } elseif (!$controllers instanceof ControllerCollection && !is_callable($controllers)) {\n            throw new \\LogicException('The \"mount\" method takes either a \"ControllerCollection\" instance, \"ControllerProviderInterface\" instance, or a callable.');\n        }\n\n        $this['controllers']->mount($prefix, $controllers);\n\n        return $this;\n    }\n\n    /**\n     * Handles the request and delivers the response.\n     *\n     * @param Request|null $request Request to process\n     */\n    public function run(Request $request = null)\n    {\n        if (null === $request) {\n            $request = Request::createFromGlobals();\n        }\n\n        $response = $this->handle($request);\n        $response->send();\n        $this->terminate($request, $response);\n    }\n\n    /**\n     * {@inheritdoc}\n     *\n     * If you call this method directly instead of run(), you must call the\n     * terminate() method yourself if you want the finish filters to be run.\n     */\n    public function handle(Request $request, $type = HttpKernelInterface::MASTER_REQUEST, $catch = true)\n    {\n        if (!$this->booted) {\n            $this->boot();\n        }\n\n        $this->flush();\n\n        return $this['kernel']->handle($request, $type, $catch);\n    }\n\n    /**\n     * {@inheritdoc}\n     */\n    public function terminate(Request $request, Response $response)\n    {\n        $this['kernel']->terminate($request, $response);\n    }\n}\n"
  },
  {
    "path": "src/Silex/CallbackResolver.php",
    "content": "<?php\n\n/*\n * This file is part of the Silex framework.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Silex;\n\nuse Pimple\\Container;\n\nclass CallbackResolver\n{\n    const SERVICE_PATTERN = \"/[A-Za-z0-9\\._\\-]+:[a-zA-Z_\\x7f-\\xff][a-zA-Z0-9_\\x7f-\\xff]*/\";\n\n    private $app;\n\n    public function __construct(Container $app)\n    {\n        $this->app = $app;\n    }\n\n    /**\n     * Returns true if the string is a valid service method representation.\n     *\n     * @param string $name\n     *\n     * @return bool\n     */\n    public function isValid($name)\n    {\n        return is_string($name) && (preg_match(static::SERVICE_PATTERN, $name) || isset($this->app[$name]));\n    }\n\n    /**\n     * Returns a callable given its string representation.\n     *\n     * @param string $name\n     *\n     * @return callable\n     *\n     * @throws \\InvalidArgumentException In case the method does not exist.\n     */\n    public function convertCallback($name)\n    {\n        if (preg_match(static::SERVICE_PATTERN, $name)) {\n            list($service, $method) = explode(':', $name, 2);\n            $callback = array($this->app[$service], $method);\n        } else {\n            $service = $name;\n            $callback = $this->app[$name];\n        }\n\n        if (!is_callable($callback)) {\n            throw new \\InvalidArgumentException(sprintf('Service \"%s\" is not callable.', $service));\n        }\n\n        return $callback;\n    }\n\n    /**\n     * Returns a callable given its string representation if it is a valid service method.\n     *\n     * @param string $name\n     *\n     * @return string|callable A callable value or the string passed in\n     *\n     * @throws \\InvalidArgumentException In case the method does not exist.\n     */\n    public function resolveCallback($name)\n    {\n        return $this->isValid($name) ? $this->convertCallback($name) : $name;\n    }\n}\n"
  },
  {
    "path": "src/Silex/Controller.php",
    "content": "<?php\n\n/*\n * This file is part of the Silex framework.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Silex;\n\nuse Silex\\Exception\\ControllerFrozenException;\n\n/**\n * A wrapper for a controller, mapped to a route.\n *\n * __call() forwards method-calls to Route, but returns instance of Controller\n * listing Route's methods below, so that IDEs know they are valid\n *\n * @method Controller assert(string $variable, string $regexp)\n * @method Controller value(string $variable, mixed $default)\n * @method Controller convert(string $variable, mixed $callback)\n * @method Controller method(string $method)\n * @method Controller requireHttp()\n * @method Controller requireHttps()\n * @method Controller before(mixed $callback)\n * @method Controller after(mixed $callback)\n * @method Controller when(string $condition)\n *\n * @author Igor Wiedler <igor@wiedler.ch>\n */\nclass Controller\n{\n    private $route;\n    private $routeName;\n    private $isFrozen = false;\n\n    /**\n     * Constructor.\n     *\n     * @param Route $route\n     */\n    public function __construct(Route $route)\n    {\n        $this->route = $route;\n    }\n\n    /**\n     * Gets the controller's route.\n     *\n     * @return Route\n     */\n    public function getRoute()\n    {\n        return $this->route;\n    }\n\n    /**\n     * Gets the controller's route name.\n     *\n     * @return string\n     */\n    public function getRouteName()\n    {\n        return $this->routeName;\n    }\n\n    /**\n     * Sets the controller's route.\n     *\n     * @param string $routeName\n     *\n     * @return Controller $this The current Controller instance\n     */\n    public function bind($routeName)\n    {\n        if ($this->isFrozen) {\n            throw new ControllerFrozenException(sprintf('Calling %s on frozen %s instance.', __METHOD__, __CLASS__));\n        }\n\n        $this->routeName = $routeName;\n\n        return $this;\n    }\n\n    public function __call($method, $arguments)\n    {\n        if (!method_exists($this->route, $method)) {\n            throw new \\BadMethodCallException(sprintf('Method \"%s::%s\" does not exist.', get_class($this->route), $method));\n        }\n\n        call_user_func_array(array($this->route, $method), $arguments);\n\n        return $this;\n    }\n\n    /**\n     * Freezes the controller.\n     *\n     * Once the controller is frozen, you can no longer change the route name\n     */\n    public function freeze()\n    {\n        $this->isFrozen = true;\n    }\n\n    public function generateRouteName($prefix)\n    {\n        $methods = implode('_', $this->route->getMethods()).'_';\n\n        $routeName = $methods.$prefix.$this->route->getPath();\n        $routeName = str_replace(array('/', ':', '|', '-'), '_', $routeName);\n        $routeName = preg_replace('/[^a-z0-9A-Z_.]+/', '', $routeName);\n\n        // Collapse consecutive underscores down into a single underscore.\n        $routeName = preg_replace('/_+/', '_', $routeName);\n\n        return $routeName;\n    }\n}\n"
  },
  {
    "path": "src/Silex/ControllerCollection.php",
    "content": "<?php\n\n/*\n * This file is part of the Silex framework.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Silex;\n\nuse Symfony\\Component\\Routing\\RouteCollection;\nuse Symfony\\Component\\HttpFoundation\\Request;\n\n/**\n * Builds Silex controllers.\n *\n * It acts as a staging area for routes. You are able to set the route name\n * until flush() is called, at which point all controllers are frozen and\n * converted to a RouteCollection.\n *\n * __call() forwards method-calls to Route, but returns instance of ControllerCollection\n * listing Route's methods below, so that IDEs know they are valid\n *\n * @method ControllerCollection assert(string $variable, string $regexp)\n * @method ControllerCollection value(string $variable, mixed $default)\n * @method ControllerCollection convert(string $variable, mixed $callback)\n * @method ControllerCollection method(string $method)\n * @method ControllerCollection requireHttp()\n * @method ControllerCollection requireHttps()\n * @method ControllerCollection before(mixed $callback)\n * @method ControllerCollection after(mixed $callback)\n * @method ControllerCollection when(string $condition)\n *\n * @author Igor Wiedler <igor@wiedler.ch>\n * @author Fabien Potencier <fabien@symfony.com>\n */\nclass ControllerCollection\n{\n    protected $controllers = array();\n    protected $defaultRoute;\n    protected $defaultController;\n    protected $prefix;\n    protected $routesFactory;\n    protected $controllersFactory;\n\n    public function __construct(Route $defaultRoute, RouteCollection $routesFactory = null, $controllersFactory = null)\n    {\n        $this->defaultRoute = $defaultRoute;\n        $this->routesFactory = $routesFactory;\n        $this->controllersFactory = $controllersFactory;\n        $this->defaultController = function (Request $request) {\n            throw new \\LogicException(sprintf('The \"%s\" route must have code to run when it matches.', $request->attributes->get('_route')));\n        };\n    }\n\n    /**\n     * Mounts controllers under the given route prefix.\n     *\n     * @param string                        $prefix      The route prefix\n     * @param ControllerCollection|callable $controllers A ControllerCollection instance or a callable for defining routes\n     *\n     * @throws \\LogicException\n     */\n    public function mount($prefix, $controllers)\n    {\n        if (is_callable($controllers)) {\n            $collection = $this->controllersFactory ? call_user_func($this->controllersFactory) : new static(new Route(), new RouteCollection());\n            call_user_func($controllers, $collection);\n            $controllers = $collection;\n        } elseif (!$controllers instanceof self) {\n            throw new \\LogicException('The \"mount\" method takes either a \"ControllerCollection\" instance or callable.');\n        }\n\n        $controllers->prefix = $prefix;\n\n        $this->controllers[] = $controllers;\n    }\n\n    /**\n     * Maps a pattern to a callable.\n     *\n     * You can optionally specify HTTP methods that should be matched.\n     *\n     * @param string $pattern Matched route pattern\n     * @param mixed  $to      Callback that returns the response when matched\n     *\n     * @return Controller\n     */\n    public function match($pattern, $to = null)\n    {\n        $route = clone $this->defaultRoute;\n        $route->setPath($pattern);\n        $this->controllers[] = $controller = new Controller($route);\n        $route->setDefault('_controller', null === $to ? $this->defaultController : $to);\n\n        return $controller;\n    }\n\n    /**\n     * Maps a GET request to a callable.\n     *\n     * @param string $pattern Matched route pattern\n     * @param mixed  $to      Callback that returns the response when matched\n     *\n     * @return Controller\n     */\n    public function get($pattern, $to = null)\n    {\n        return $this->match($pattern, $to)->method('GET');\n    }\n\n    /**\n     * Maps a POST request to a callable.\n     *\n     * @param string $pattern Matched route pattern\n     * @param mixed  $to      Callback that returns the response when matched\n     *\n     * @return Controller\n     */\n    public function post($pattern, $to = null)\n    {\n        return $this->match($pattern, $to)->method('POST');\n    }\n\n    /**\n     * Maps a PUT request to a callable.\n     *\n     * @param string $pattern Matched route pattern\n     * @param mixed  $to      Callback that returns the response when matched\n     *\n     * @return Controller\n     */\n    public function put($pattern, $to = null)\n    {\n        return $this->match($pattern, $to)->method('PUT');\n    }\n\n    /**\n     * Maps a DELETE request to a callable.\n     *\n     * @param string $pattern Matched route pattern\n     * @param mixed  $to      Callback that returns the response when matched\n     *\n     * @return Controller\n     */\n    public function delete($pattern, $to = null)\n    {\n        return $this->match($pattern, $to)->method('DELETE');\n    }\n\n    /**\n     * Maps an OPTIONS request to a callable.\n     *\n     * @param string $pattern Matched route pattern\n     * @param mixed  $to      Callback that returns the response when matched\n     *\n     * @return Controller\n     */\n    public function options($pattern, $to = null)\n    {\n        return $this->match($pattern, $to)->method('OPTIONS');\n    }\n\n    /**\n     * Maps a PATCH request to a callable.\n     *\n     * @param string $pattern Matched route pattern\n     * @param mixed  $to      Callback that returns the response when matched\n     *\n     * @return Controller\n     */\n    public function patch($pattern, $to = null)\n    {\n        return $this->match($pattern, $to)->method('PATCH');\n    }\n\n    public function __call($method, $arguments)\n    {\n        if (!method_exists($this->defaultRoute, $method)) {\n            throw new \\BadMethodCallException(sprintf('Method \"%s::%s\" does not exist.', get_class($this->defaultRoute), $method));\n        }\n\n        call_user_func_array(array($this->defaultRoute, $method), $arguments);\n\n        foreach ($this->controllers as $controller) {\n            call_user_func_array(array($controller, $method), $arguments);\n        }\n\n        return $this;\n    }\n\n    /**\n     * Persists and freezes staged controllers.\n     *\n     * @return RouteCollection A RouteCollection instance\n     */\n    public function flush()\n    {\n        if (null === $this->routesFactory) {\n            $routes = new RouteCollection();\n        } else {\n            $routes = $this->routesFactory;\n        }\n\n        return $this->doFlush('', $routes);\n    }\n\n    private function doFlush($prefix, RouteCollection $routes)\n    {\n        if ($prefix !== '') {\n            $prefix = '/'.trim(trim($prefix), '/');\n        }\n\n        foreach ($this->controllers as $controller) {\n            if ($controller instanceof Controller) {\n                $controller->getRoute()->setPath($prefix.$controller->getRoute()->getPath());\n                if (!$name = $controller->getRouteName()) {\n                    $name = $base = $controller->generateRouteName('');\n                    $i = 0;\n                    while ($routes->get($name)) {\n                        $name = $base.'_'.++$i;\n                    }\n                    $controller->bind($name);\n                }\n                $routes->add($name, $controller->getRoute());\n                $controller->freeze();\n            } else {\n                $controller->doFlush($prefix.$controller->prefix, $routes);\n            }\n        }\n\n        $this->controllers = array();\n\n        return $routes;\n    }\n}\n"
  },
  {
    "path": "src/Silex/ControllerResolver.php",
    "content": "<?php\n\n/*\n * This file is part of the Silex framework.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Silex;\n\nuse Psr\\Log\\LoggerInterface;\nuse Symfony\\Component\\HttpKernel\\Controller\\ControllerResolver as BaseControllerResolver;\nuse Symfony\\Component\\HttpFoundation\\Request;\n\n/**\n * Adds Application as a valid argument for controllers.\n *\n * @author Fabien Potencier <fabien@symfony.com>\n *\n * @deprecated This class can be dropped once Symfony 3.0 is not supported anymore.\n */\nclass ControllerResolver extends BaseControllerResolver\n{\n    protected $app;\n\n    /**\n     * Constructor.\n     *\n     * @param Application     $app    An Application instance\n     * @param LoggerInterface $logger A LoggerInterface instance\n     */\n    public function __construct(Application $app, LoggerInterface $logger = null)\n    {\n        $this->app = $app;\n\n        parent::__construct($logger);\n    }\n\n    protected function doGetArguments(Request $request, $controller, array $parameters)\n    {\n        foreach ($parameters as $param) {\n            if ($param->getClass() && $param->getClass()->isInstance($this->app)) {\n                $request->attributes->set($param->getName(), $this->app);\n\n                break;\n            }\n        }\n\n        return parent::doGetArguments($request, $controller, $parameters);\n    }\n}\n"
  },
  {
    "path": "src/Silex/EventListener/ConverterListener.php",
    "content": "<?php\n\n/*\n * This file is part of the Silex framework.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Silex\\EventListener;\n\nuse Silex\\CallbackResolver;\nuse Symfony\\Component\\HttpKernel\\KernelEvents;\nuse Symfony\\Component\\HttpKernel\\Event\\FilterControllerEvent;\nuse Symfony\\Component\\EventDispatcher\\EventSubscriberInterface;\nuse Symfony\\Component\\Routing\\RouteCollection;\n\n/**\n * Handles converters.\n *\n * @author Fabien Potencier <fabien@symfony.com>\n */\nclass ConverterListener implements EventSubscriberInterface\n{\n    protected $routes;\n    protected $callbackResolver;\n\n    /**\n     * Constructor.\n     *\n     * @param RouteCollection  $routes           A RouteCollection instance\n     * @param CallbackResolver $callbackResolver A CallbackResolver instance\n     */\n    public function __construct(RouteCollection $routes, CallbackResolver $callbackResolver)\n    {\n        $this->routes = $routes;\n        $this->callbackResolver = $callbackResolver;\n    }\n\n    /**\n     * Handles converters.\n     *\n     * @param FilterControllerEvent $event The event to handle\n     */\n    public function onKernelController(FilterControllerEvent $event)\n    {\n        $request = $event->getRequest();\n        $route = $this->routes->get($request->attributes->get('_route'));\n        if ($route && $converters = $route->getOption('_converters')) {\n            foreach ($converters as $name => $callback) {\n                $callback = $this->callbackResolver->resolveCallback($callback);\n\n                $request->attributes->set($name, call_user_func($callback, $request->attributes->get($name), $request));\n            }\n        }\n    }\n\n    public static function getSubscribedEvents()\n    {\n        return array(\n            KernelEvents::CONTROLLER => 'onKernelController',\n        );\n    }\n}\n"
  },
  {
    "path": "src/Silex/EventListener/LogListener.php",
    "content": "<?php\n\n/*\n * This file is part of the Silex framework.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Silex\\EventListener;\n\nuse Psr\\Log\\LoggerInterface;\nuse Psr\\Log\\LogLevel;\nuse Symfony\\Component\\EventDispatcher\\EventSubscriberInterface;\nuse Symfony\\Component\\HttpKernel\\Event\\GetResponseEvent;\nuse Symfony\\Component\\HttpKernel\\Event\\FilterResponseEvent;\nuse Symfony\\Component\\HttpKernel\\Event\\GetResponseForExceptionEvent;\nuse Symfony\\Component\\HttpKernel\\KernelEvents;\nuse Symfony\\Component\\HttpKernel\\Exception\\HttpExceptionInterface;\nuse Symfony\\Component\\HttpFoundation\\Request;\nuse Symfony\\Component\\HttpFoundation\\Response;\nuse Symfony\\Component\\HttpFoundation\\RedirectResponse;\n\n/**\n * Logs request, response, and exceptions.\n */\nclass LogListener implements EventSubscriberInterface\n{\n    protected $logger;\n    protected $exceptionLogFilter;\n\n    public function __construct(LoggerInterface $logger, $exceptionLogFilter = null)\n    {\n        $this->logger = $logger;\n        if (null === $exceptionLogFilter) {\n            $exceptionLogFilter = function (\\Exception $e) {\n                if ($e instanceof HttpExceptionInterface && $e->getStatusCode() < 500) {\n                    return LogLevel::ERROR;\n                }\n\n                return LogLevel::CRITICAL;\n            };\n        }\n\n        $this->exceptionLogFilter = $exceptionLogFilter;\n    }\n\n    /**\n     * Logs master requests on event KernelEvents::REQUEST.\n     *\n     * @param GetResponseEvent $event\n     */\n    public function onKernelRequest(GetResponseEvent $event)\n    {\n        if (!$event->isMasterRequest()) {\n            return;\n        }\n\n        $this->logRequest($event->getRequest());\n    }\n\n    /**\n     * Logs master response on event KernelEvents::RESPONSE.\n     *\n     * @param FilterResponseEvent $event\n     */\n    public function onKernelResponse(FilterResponseEvent $event)\n    {\n        if (!$event->isMasterRequest()) {\n            return;\n        }\n\n        $this->logResponse($event->getResponse());\n    }\n\n    /**\n     * Logs uncaught exceptions on event KernelEvents::EXCEPTION.\n     *\n     * @param GetResponseForExceptionEvent $event\n     */\n    public function onKernelException(GetResponseForExceptionEvent $event)\n    {\n        $this->logException($event->getException());\n    }\n\n    /**\n     * Logs a request.\n     *\n     * @param Request $request\n     */\n    protected function logRequest(Request $request)\n    {\n        $this->logger->log(LogLevel::DEBUG, '> '.$request->getMethod().' '.$request->getRequestUri());\n    }\n\n    /**\n     * Logs a response.\n     *\n     * @param Response $response\n     */\n    protected function logResponse(Response $response)\n    {\n        $message = '< '.$response->getStatusCode();\n\n        if ($response instanceof RedirectResponse) {\n            $message .= ' '.$response->getTargetUrl();\n        }\n\n        $this->logger->log(LogLevel::DEBUG, $message);\n    }\n\n    /**\n     * Logs an exception.\n     */\n    protected function logException(\\Exception $e)\n    {\n        $this->logger->log(call_user_func($this->exceptionLogFilter, $e), sprintf('%s: %s (uncaught exception) at %s line %s', get_class($e), $e->getMessage(), $e->getFile(), $e->getLine()), array('exception' => $e));\n    }\n\n    public static function getSubscribedEvents()\n    {\n        return array(\n            KernelEvents::REQUEST => array('onKernelRequest', 0),\n            KernelEvents::RESPONSE => array('onKernelResponse', 0),\n            /*\n             * Priority -4 is used to come after those from SecurityServiceProvider (0)\n             * but before the error handlers added with Silex\\Application::error (defaults to -8)\n             */\n            KernelEvents::EXCEPTION => array('onKernelException', -4),\n        );\n    }\n}\n"
  },
  {
    "path": "src/Silex/EventListener/MiddlewareListener.php",
    "content": "<?php\n\n/*\n * This file is part of the Silex framework.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Silex\\EventListener;\n\nuse Symfony\\Component\\HttpKernel\\KernelEvents;\nuse Symfony\\Component\\HttpKernel\\Event\\GetResponseEvent;\nuse Symfony\\Component\\HttpKernel\\Event\\FilterResponseEvent;\nuse Symfony\\Component\\HttpFoundation\\Response;\nuse Symfony\\Component\\EventDispatcher\\EventSubscriberInterface;\nuse Silex\\Application;\n\n/**\n * Manages the route middlewares.\n *\n * @author Fabien Potencier <fabien@symfony.com>\n */\nclass MiddlewareListener implements EventSubscriberInterface\n{\n    protected $app;\n\n    /**\n     * Constructor.\n     *\n     * @param Application $app An Application instance\n     */\n    public function __construct(Application $app)\n    {\n        $this->app = $app;\n    }\n\n    /**\n     * Runs before filters.\n     *\n     * @param GetResponseEvent $event The event to handle\n     */\n    public function onKernelRequest(GetResponseEvent $event)\n    {\n        $request = $event->getRequest();\n        $routeName = $request->attributes->get('_route');\n        if (!$route = $this->app['routes']->get($routeName)) {\n            return;\n        }\n\n        foreach ((array) $route->getOption('_before_middlewares') as $callback) {\n            $ret = call_user_func($this->app['callback_resolver']->resolveCallback($callback), $request, $this->app);\n            if ($ret instanceof Response) {\n                $event->setResponse($ret);\n\n                return;\n            } elseif (null !== $ret) {\n                throw new \\RuntimeException(sprintf('A before middleware for route \"%s\" returned an invalid response value. Must return null or an instance of Response.', $routeName));\n            }\n        }\n    }\n\n    /**\n     * Runs after filters.\n     *\n     * @param FilterResponseEvent $event The event to handle\n     */\n    public function onKernelResponse(FilterResponseEvent $event)\n    {\n        $request = $event->getRequest();\n        $routeName = $request->attributes->get('_route');\n        if (!$route = $this->app['routes']->get($routeName)) {\n            return;\n        }\n\n        foreach ((array) $route->getOption('_after_middlewares') as $callback) {\n            $response = call_user_func($this->app['callback_resolver']->resolveCallback($callback), $request, $event->getResponse(), $this->app);\n            if ($response instanceof Response) {\n                $event->setResponse($response);\n            } elseif (null !== $response) {\n                throw new \\RuntimeException(sprintf('An after middleware for route \"%s\" returned an invalid response value. Must return null or an instance of Response.', $routeName));\n            }\n        }\n    }\n\n    public static function getSubscribedEvents()\n    {\n        return array(\n            // this must be executed after the late events defined with before() (and their priority is -512)\n            KernelEvents::REQUEST => array('onKernelRequest', -1024),\n            KernelEvents::RESPONSE => array('onKernelResponse', 128),\n        );\n    }\n}\n"
  },
  {
    "path": "src/Silex/EventListener/StringToResponseListener.php",
    "content": "<?php\n\n/*\n * This file is part of the Silex framework.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Silex\\EventListener;\n\nuse Symfony\\Component\\HttpKernel\\KernelEvents;\nuse Symfony\\Component\\HttpKernel\\Event\\GetResponseForControllerResultEvent;\nuse Symfony\\Component\\EventDispatcher\\EventSubscriberInterface;\nuse Symfony\\Component\\HttpFoundation\\Response;\n\n/**\n * Converts string responses to proper Response instances.\n *\n * @author Fabien Potencier <fabien@symfony.com>\n */\nclass StringToResponseListener implements EventSubscriberInterface\n{\n    /**\n     * Handles string responses.\n     *\n     * @param GetResponseForControllerResultEvent $event The event to handle\n     */\n    public function onKernelView(GetResponseForControllerResultEvent $event)\n    {\n        $response = $event->getControllerResult();\n\n        if (!(\n            null === $response\n            || is_array($response)\n            || $response instanceof Response\n            || (is_object($response) && !method_exists($response, '__toString'))\n        )) {\n            $event->setResponse(new Response((string) $response));\n        }\n    }\n\n    public static function getSubscribedEvents()\n    {\n        return array(\n            KernelEvents::VIEW => array('onKernelView', -10),\n        );\n    }\n}\n"
  },
  {
    "path": "src/Silex/Exception/ControllerFrozenException.php",
    "content": "<?php\n\n/*\n * This file is part of the Silex framework.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Silex\\Exception;\n\n/**\n * Exception, is thrown when a frozen controller is modified.\n *\n * @author Igor Wiedler <igor@wiedler.ch>\n */\nclass ControllerFrozenException extends \\RuntimeException\n{\n}\n"
  },
  {
    "path": "src/Silex/ExceptionHandler.php",
    "content": "<?php\n\n/*\n * This file is part of the Silex framework.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Silex;\n\nuse Symfony\\Component\\Debug\\ExceptionHandler as DebugExceptionHandler;\nuse Symfony\\Component\\Debug\\Exception\\FlattenException;\nuse Symfony\\Component\\EventDispatcher\\EventSubscriberInterface;\nuse Symfony\\Component\\HttpFoundation\\Response;\nuse Symfony\\Component\\HttpKernel\\Event\\GetResponseForExceptionEvent;\nuse Symfony\\Component\\HttpKernel\\KernelEvents;\n\n/**\n * Default exception handler.\n *\n * @author Fabien Potencier <fabien@symfony.com>\n */\nclass ExceptionHandler implements EventSubscriberInterface\n{\n    protected $debug;\n\n    public function __construct($debug)\n    {\n        $this->debug = $debug;\n    }\n\n    public function onSilexError(GetResponseForExceptionEvent $event)\n    {\n        $handler = new DebugExceptionHandler($this->debug);\n\n        $exception = $event->getException();\n        if (!$exception instanceof FlattenException) {\n            $exception = FlattenException::create($exception);\n        }\n\n        $response = Response::create($handler->getHtml($exception), $exception->getStatusCode(), $exception->getHeaders())->setCharset(ini_get('default_charset'));\n\n        $event->setResponse($response);\n    }\n\n    /**\n     * {@inheritdoc}\n     */\n    public static function getSubscribedEvents()\n    {\n        return array(KernelEvents::EXCEPTION => array('onSilexError', -255));\n    }\n}\n"
  },
  {
    "path": "src/Silex/ExceptionListenerWrapper.php",
    "content": "<?php\n\n/*\n * This file is part of the Silex framework.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Silex;\n\nuse Symfony\\Component\\HttpFoundation\\Response;\nuse Symfony\\Component\\HttpKernel\\Exception\\HttpExceptionInterface;\nuse Symfony\\Component\\HttpKernel\\KernelEvents;\nuse Symfony\\Component\\HttpKernel\\Event\\GetResponseForExceptionEvent;\nuse Symfony\\Component\\HttpKernel\\Event\\GetResponseForControllerResultEvent;\n\n/**\n * Wraps exception listeners.\n *\n * @author Fabien Potencier <fabien@symfony.com>\n */\nclass ExceptionListenerWrapper\n{\n    protected $app;\n    protected $callback;\n\n    /**\n     * Constructor.\n     *\n     * @param Application $app      An Application instance\n     * @param callable    $callback\n     */\n    public function __construct(Application $app, $callback)\n    {\n        $this->app = $app;\n        $this->callback = $callback;\n    }\n\n    public function __invoke(GetResponseForExceptionEvent $event)\n    {\n        $exception = $event->getException();\n        $this->callback = $this->app['callback_resolver']->resolveCallback($this->callback);\n\n        if (!$this->shouldRun($exception)) {\n            return;\n        }\n\n        $code = $exception instanceof HttpExceptionInterface ? $exception->getStatusCode() : 500;\n\n        $response = call_user_func($this->callback, $exception, $event->getRequest(), $code);\n\n        $this->ensureResponse($response, $event);\n    }\n\n    protected function shouldRun(\\Exception $exception)\n    {\n        if (is_array($this->callback)) {\n            $callbackReflection = new \\ReflectionMethod($this->callback[0], $this->callback[1]);\n        } elseif (is_object($this->callback) && !$this->callback instanceof \\Closure) {\n            $callbackReflection = new \\ReflectionObject($this->callback);\n            $callbackReflection = $callbackReflection->getMethod('__invoke');\n        } else {\n            $callbackReflection = new \\ReflectionFunction($this->callback);\n        }\n\n        if ($callbackReflection->getNumberOfParameters() > 0) {\n            $parameters = $callbackReflection->getParameters();\n            $expectedException = $parameters[0];\n            if ($expectedException->getClass() && !$expectedException->getClass()->isInstance($exception)) {\n                return false;\n            }\n        }\n\n        return true;\n    }\n\n    protected function ensureResponse($response, GetResponseForExceptionEvent $event)\n    {\n        if ($response instanceof Response) {\n            $event->setResponse($response);\n        } else {\n            $viewEvent = new GetResponseForControllerResultEvent($this->app['kernel'], $event->getRequest(), $event->getRequestType(), $response);\n            $this->app['dispatcher']->dispatch(KernelEvents::VIEW, $viewEvent);\n\n            if ($viewEvent->hasResponse()) {\n                $event->setResponse($viewEvent->getResponse());\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "src/Silex/Provider/AssetServiceProvider.php",
    "content": "<?php\n\n/*\n * This file is part of the Silex framework.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Silex\\Provider;\n\nuse Pimple\\Container;\nuse Pimple\\ServiceProviderInterface;\nuse Symfony\\Component\\Asset\\Packages;\nuse Symfony\\Component\\Asset\\Package;\nuse Symfony\\Component\\Asset\\PathPackage;\nuse Symfony\\Component\\Asset\\UrlPackage;\nuse Symfony\\Component\\Asset\\Context\\RequestStackContext;\nuse Symfony\\Component\\Asset\\VersionStrategy\\EmptyVersionStrategy;\nuse Symfony\\Component\\Asset\\VersionStrategy\\StaticVersionStrategy;\n\n/**\n * Symfony Asset component Provider.\n *\n * @author Fabien Potencier <fabien@symfony.com>\n */\nclass AssetServiceProvider implements ServiceProviderInterface\n{\n    public function register(Container $app)\n    {\n        $app['assets.packages'] = function ($app) {\n            $packages = array();\n            foreach ($app['assets.named_packages'] as $name => $package) {\n                $version = $app['assets.strategy_factory'](isset($package['version']) ? $package['version'] : '', isset($package['version_format']) ? $package['version_format'] : null);\n\n                $packages[$name] = $app['assets.package_factory'](isset($package['base_path']) ? $package['base_path'] : '', isset($package['base_urls']) ? $package['base_urls'] : array(), $version, $name);\n            }\n\n            return new Packages($app['assets.default_package'], $packages);\n        };\n\n        $app['assets.default_package'] = function ($app) {\n            $version = $app['assets.strategy_factory']($app['assets.version'], $app['assets.version_format']);\n\n            return $app['assets.package_factory']($app['assets.base_path'], $app['assets.base_urls'], $version, 'default');\n        };\n\n        $app['assets.context'] = function ($app) {\n            return new RequestStackContext($app['request_stack']);\n        };\n\n        $app['assets.base_path'] = '';\n        $app['assets.base_urls'] = array();\n        $app['assets.version'] = null;\n        $app['assets.version_format'] = null;\n\n        $app['assets.named_packages'] = array();\n\n        // prototypes\n\n        $app['assets.strategy_factory'] = $app->protect(function ($version, $format) use ($app) {\n            if (!$version) {\n                return new EmptyVersionStrategy();\n            }\n\n            return new StaticVersionStrategy($version, $format);\n        });\n\n        $app['assets.package_factory'] = $app->protect(function ($basePath, $baseUrls, $version, $name) use ($app) {\n            if ($basePath && $baseUrls) {\n                throw new \\LogicException(sprintf('Asset package \"%s\" cannot have base URLs and base paths.', $name));\n            }\n\n            if (!$baseUrls) {\n                return new PathPackage($basePath, $version, $app['assets.context']);\n            }\n\n            return new UrlPackage($baseUrls, $version, $app['assets.context']);\n        });\n    }\n}\n"
  },
  {
    "path": "src/Silex/Provider/CsrfServiceProvider.php",
    "content": "<?php\n\n/*\n * This file is part of the Silex framework.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Silex\\Provider;\n\nuse Pimple\\Container;\nuse Pimple\\ServiceProviderInterface;\nuse Symfony\\Component\\Security\\Csrf\\CsrfTokenManager;\nuse Symfony\\Component\\Security\\Csrf\\TokenGenerator\\UriSafeTokenGenerator;\nuse Symfony\\Component\\Security\\Csrf\\TokenStorage\\SessionTokenStorage;\nuse Symfony\\Component\\Security\\Csrf\\TokenStorage\\NativeSessionTokenStorage;\n\n/**\n * Symfony CSRF Security component Provider.\n *\n * @author Fabien Potencier <fabien@symfony.com>\n */\nclass CsrfServiceProvider implements ServiceProviderInterface\n{\n    public function register(Container $app)\n    {\n        $app['csrf.token_manager'] = function ($app) {\n            return new CsrfTokenManager($app['csrf.token_generator'], $app['csrf.token_storage']);\n        };\n\n        $app['csrf.token_storage'] = function ($app) {\n            if (isset($app['session'])) {\n                return new SessionTokenStorage($app['session'], $app['csrf.session_namespace']);\n            }\n\n            return new NativeSessionTokenStorage($app['csrf.session_namespace']);\n        };\n\n        $app['csrf.token_generator'] = function ($app) {\n            return new UriSafeTokenGenerator();\n        };\n\n        $app['csrf.session_namespace'] = '_csrf';\n    }\n}\n"
  },
  {
    "path": "src/Silex/Provider/DoctrineServiceProvider.php",
    "content": "<?php\n\n/*\n * This file is part of the Silex framework.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Silex\\Provider;\n\nuse Pimple\\Container;\nuse Pimple\\ServiceProviderInterface;\nuse Doctrine\\DBAL\\DriverManager;\nuse Doctrine\\DBAL\\Configuration;\nuse Doctrine\\Common\\EventManager;\nuse Symfony\\Bridge\\Doctrine\\Logger\\DbalLogger;\n\n/**\n * Doctrine DBAL Provider.\n *\n * @author Fabien Potencier <fabien@symfony.com>\n */\nclass DoctrineServiceProvider implements ServiceProviderInterface\n{\n    public function register(Container $app)\n    {\n        $app['db.default_options'] = array(\n            'driver' => 'pdo_mysql',\n            'dbname' => null,\n            'host' => 'localhost',\n            'user' => 'root',\n            'password' => null,\n        );\n\n        $app['dbs.options.initializer'] = $app->protect(function () use ($app) {\n            static $initialized = false;\n\n            if ($initialized) {\n                return;\n            }\n\n            $initialized = true;\n\n            if (!isset($app['dbs.options'])) {\n                $app['dbs.options'] = array('default' => isset($app['db.options']) ? $app['db.options'] : array());\n            }\n\n            $tmp = $app['dbs.options'];\n            foreach ($tmp as $name => &$options) {\n                $options = array_replace($app['db.default_options'], $options);\n\n                if (!isset($app['dbs.default'])) {\n                    $app['dbs.default'] = $name;\n                }\n            }\n            $app['dbs.options'] = $tmp;\n        });\n\n        $app['dbs'] = function ($app) {\n            $app['dbs.options.initializer']();\n\n            $dbs = new Container();\n            foreach ($app['dbs.options'] as $name => $options) {\n                if ($app['dbs.default'] === $name) {\n                    // we use shortcuts here in case the default has been overridden\n                    $config = $app['db.config'];\n                    $manager = $app['db.event_manager'];\n                } else {\n                    $config = $app['dbs.config'][$name];\n                    $manager = $app['dbs.event_manager'][$name];\n                }\n\n                $dbs[$name] = function ($dbs) use ($options, $config, $manager) {\n                    return DriverManager::getConnection($options, $config, $manager);\n                };\n            }\n\n            return $dbs;\n        };\n\n        $app['dbs.config'] = function ($app) {\n            $app['dbs.options.initializer']();\n\n            $configs = new Container();\n            $addLogger = isset($app['logger']) && null !== $app['logger'] && class_exists('Symfony\\Bridge\\Doctrine\\Logger\\DbalLogger');\n            foreach ($app['dbs.options'] as $name => $options) {\n                $configs[$name] = new Configuration();\n                if ($addLogger) {\n                    $configs[$name]->setSQLLogger(new DbalLogger($app['logger'], isset($app['stopwatch']) ? $app['stopwatch'] : null));\n                }\n            }\n\n            return $configs;\n        };\n\n        $app['dbs.event_manager'] = function ($app) {\n            $app['dbs.options.initializer']();\n\n            $managers = new Container();\n            foreach ($app['dbs.options'] as $name => $options) {\n                $managers[$name] = new EventManager();\n            }\n\n            return $managers;\n        };\n\n        // shortcuts for the \"first\" DB\n        $app['db'] = function ($app) {\n            $dbs = $app['dbs'];\n\n            return $dbs[$app['dbs.default']];\n        };\n\n        $app['db.config'] = function ($app) {\n            $dbs = $app['dbs.config'];\n\n            return $dbs[$app['dbs.default']];\n        };\n\n        $app['db.event_manager'] = function ($app) {\n            $dbs = $app['dbs.event_manager'];\n\n            return $dbs[$app['dbs.default']];\n        };\n    }\n}\n"
  },
  {
    "path": "src/Silex/Provider/ExceptionHandlerServiceProvider.php",
    "content": "<?php\n\nnamespace Silex\\Provider;\n\nuse Pimple\\Container;\nuse Pimple\\ServiceProviderInterface;\nuse Silex\\Api\\EventListenerProviderInterface;\nuse Silex\\ExceptionHandler;\nuse Symfony\\Component\\EventDispatcher\\EventDispatcherInterface;\n\nclass ExceptionHandlerServiceProvider implements ServiceProviderInterface, EventListenerProviderInterface\n{\n    /**\n     * {@inheritdoc}\n     */\n    public function register(Container $app)\n    {\n        $app['exception_handler'] = function ($app) {\n            return new ExceptionHandler($app['debug']);\n        };\n    }\n\n    /**\n     * {@inheritdoc}\n     */\n    public function subscribe(Container $app, EventDispatcherInterface $dispatcher)\n    {\n        if (isset($app['exception_handler'])) {\n            $dispatcher->addSubscriber($app['exception_handler']);\n        }\n    }\n}\n"
  },
  {
    "path": "src/Silex/Provider/Form/SilexFormExtension.php",
    "content": "<?php\n\n/*\n * This file is part of the Silex framework.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Silex\\Provider\\Form;\n\nuse Pimple\\Container;\nuse Symfony\\Component\\Form\\Exception\\InvalidArgumentException;\nuse Symfony\\Component\\Form\\FormExtensionInterface;\nuse Symfony\\Component\\Form\\FormTypeGuesserChain;\n\nclass SilexFormExtension implements FormExtensionInterface\n{\n    private $app;\n    private $types;\n    private $typeExtensions;\n    private $guessers;\n    private $guesserLoaded = false;\n    private $guesser;\n\n    public function __construct(Container $app, array $types, array $typeExtensions, array $guessers)\n    {\n        $this->app = $app;\n        $this->setTypes($types);\n        $this->setTypeExtensions($typeExtensions);\n        $this->setGuessers($guessers);\n    }\n\n    public function getType($name)\n    {\n        if (!isset($this->types[$name])) {\n            throw new InvalidArgumentException(sprintf('The type \"%s\" is not the name of a registered form type.', $name));\n        }\n        if (!is_object($this->types[$name])) {\n            $this->types[$name] = $this->app[$this->types[$name]];\n        }\n\n        return $this->types[$name];\n    }\n\n    public function hasType($name)\n    {\n        return isset($this->types[$name]);\n    }\n\n    public function getTypeExtensions($name)\n    {\n        return isset($this->typeExtensions[$name]) ? $this->typeExtensions[$name] : [];\n    }\n\n    public function hasTypeExtensions($name)\n    {\n        return isset($this->typeExtensions[$name]);\n    }\n\n    public function getTypeGuesser()\n    {\n        if (!$this->guesserLoaded) {\n            $this->guesserLoaded = true;\n\n            if ($this->guessers) {\n                $guessers = [];\n                foreach ($this->guessers as $guesser) {\n                    if (!is_object($guesser)) {\n                        $guesser = $this->app[$guesser];\n                    }\n                    $guessers[] = $guesser;\n                }\n                $this->guesser = new FormTypeGuesserChain($guessers);\n            }\n        }\n\n        return $this->guesser;\n    }\n\n    private function setTypes(array $types)\n    {\n        $this->types = [];\n        foreach ($types as $type) {\n            if (!is_object($type)) {\n                if (!isset($this->app[$type])) {\n                    throw new InvalidArgumentException(sprintf('Invalid form type. The silex service \"%s\" does not exist.', $type));\n                }\n                $this->types[$type] = $type;\n            } else {\n                $this->types[get_class($type)] = $type;\n            }\n        }\n    }\n\n    private function setTypeExtensions(array $typeExtensions)\n    {\n        $this->typeExtensions = [];\n        foreach ($typeExtensions as $extension) {\n            if (!is_object($extension)) {\n                if (!isset($this->app[$extension])) {\n                    throw new InvalidArgumentException(sprintf('Invalid form type extension. The silex service \"%s\" does not exist.', $extension));\n                }\n                $extension = $this->app[$extension];\n            }\n            $this->typeExtensions[$extension->getExtendedType()][] = $extension;\n        }\n    }\n\n    private function setGuessers(array $guessers)\n    {\n        $this->guessers = [];\n        foreach ($guessers as $guesser) {\n            if (!is_object($guesser) && !isset($this->app[$guesser])) {\n                throw new InvalidArgumentException(sprintf('Invalid form type guesser. The silex service \"%s\" does not exist.', $guesser));\n            }\n            $this->guessers[] = $guesser;\n        }\n    }\n}\n"
  },
  {
    "path": "src/Silex/Provider/FormServiceProvider.php",
    "content": "<?php\n\n/*\n * This file is part of the Silex framework.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Silex\\Provider;\n\nuse Pimple\\Container;\nuse Pimple\\ServiceProviderInterface;\nuse Symfony\\Component\\Form\\Extension\\Csrf\\CsrfExtension;\nuse Symfony\\Component\\Form\\Extension\\HttpFoundation\\HttpFoundationExtension;\nuse Symfony\\Component\\Form\\Extension\\Validator\\ValidatorExtension as FormValidatorExtension;\nuse Symfony\\Component\\Form\\Forms;\nuse Symfony\\Component\\Form\\ResolvedFormTypeFactory;\n\n/**\n * Symfony Form component Provider.\n *\n * @author Fabien Potencier <fabien@symfony.com>\n */\nclass FormServiceProvider implements ServiceProviderInterface\n{\n    public function register(Container $app)\n    {\n        if (!class_exists('Locale')) {\n            throw new \\RuntimeException('You must either install the PHP intl extension or the Symfony Intl Component to use the Form extension.');\n        }\n\n        $app['form.types'] = function ($app) {\n            return array();\n        };\n\n        $app['form.type.extensions'] = function ($app) {\n            return array();\n        };\n\n        $app['form.type.guessers'] = function ($app) {\n            return array();\n        };\n\n        $app['form.extension.csrf'] = function ($app) {\n            if (isset($app['translator'])) {\n                return new CsrfExtension($app['csrf.token_manager'], $app['translator']);\n            }\n\n            return new CsrfExtension($app['csrf.token_manager']);\n        };\n\n        $app['form.extension.silex'] = function ($app) {\n            return new Form\\SilexFormExtension($app, $app['form.types'], $app['form.type.extensions'], $app['form.type.guessers']);\n        };\n\n        $app['form.extensions'] = function ($app) {\n            $extensions = array(\n                new HttpFoundationExtension(),\n            );\n\n            if (isset($app['csrf.token_manager'])) {\n                $extensions[] = $app['form.extension.csrf'];\n            }\n\n            if (isset($app['validator'])) {\n                $extensions[] = new FormValidatorExtension($app['validator']);\n            }\n            $extensions[] = $app['form.extension.silex'];\n\n            return $extensions;\n        };\n\n        $app['form.factory'] = function ($app) {\n            return Forms::createFormFactoryBuilder()\n                ->addExtensions($app['form.extensions'])\n                ->setResolvedTypeFactory($app['form.resolved_type_factory'])\n                ->getFormFactory()\n            ;\n        };\n\n        $app['form.resolved_type_factory'] = function ($app) {\n            return new ResolvedFormTypeFactory();\n        };\n    }\n}\n"
  },
  {
    "path": "src/Silex/Provider/HttpCache/HttpCache.php",
    "content": "<?php\n\n/*\n * This file is part of the Silex framework.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Silex\\Provider\\HttpCache;\n\nuse Symfony\\Component\\HttpKernel\\HttpCache\\HttpCache as BaseHttpCache;\nuse Symfony\\Component\\HttpFoundation\\Request;\n\n/**\n * HTTP Cache extension to allow using the run() shortcut.\n *\n * @author Fabien Potencier <fabien@symfony.com>\n */\nclass HttpCache extends BaseHttpCache\n{\n    /**\n     * Handles the Request and delivers the Response.\n     *\n     * @param Request $request The Request object\n     */\n    public function run(Request $request = null)\n    {\n        if (null === $request) {\n            $request = Request::createFromGlobals();\n        }\n\n        $response = $this->handle($request);\n        $response->send();\n        $this->terminate($request, $response);\n    }\n}\n"
  },
  {
    "path": "src/Silex/Provider/HttpCacheServiceProvider.php",
    "content": "<?php\n\n/*\n * This file is part of the Silex framework.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Silex\\Provider;\n\nuse Pimple\\Container;\nuse Pimple\\ServiceProviderInterface;\nuse Silex\\Provider\\HttpCache\\HttpCache;\nuse Silex\\Api\\EventListenerProviderInterface;\nuse Symfony\\Component\\EventDispatcher\\EventDispatcherInterface;\nuse Symfony\\Component\\HttpKernel\\HttpCache\\Esi;\nuse Symfony\\Component\\HttpKernel\\HttpCache\\Store;\nuse Symfony\\Component\\HttpKernel\\EventListener\\SurrogateListener;\n\n/**\n * Symfony HttpKernel component Provider for HTTP cache.\n *\n * @author Fabien Potencier <fabien@symfony.com>\n */\nclass HttpCacheServiceProvider implements ServiceProviderInterface, EventListenerProviderInterface\n{\n    public function register(Container $app)\n    {\n        $app['http_cache'] = function ($app) {\n            $app['http_cache.options'] = array_replace(\n                array(\n                    'debug' => $app['debug'],\n                ), $app['http_cache.options']\n            );\n\n            return new HttpCache($app, $app['http_cache.store'], $app['http_cache.esi'], $app['http_cache.options']);\n        };\n\n        $app['http_cache.esi'] = function ($app) {\n            return new Esi();\n        };\n\n        $app['http_cache.store'] = function ($app) {\n            return new Store($app['http_cache.cache_dir']);\n        };\n\n        $app['http_cache.esi_listener'] = function ($app) {\n            return new SurrogateListener($app['http_cache.esi']);\n        };\n\n        $app['http_cache.options'] = array();\n    }\n\n    public function subscribe(Container $app, EventDispatcherInterface $dispatcher)\n    {\n        $dispatcher->addSubscriber($app['http_cache.esi_listener']);\n    }\n}\n"
  },
  {
    "path": "src/Silex/Provider/HttpFragmentServiceProvider.php",
    "content": "<?php\n\n/*\n * This file is part of the Silex framework.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Silex\\Provider;\n\nuse Pimple\\Container;\nuse Pimple\\ServiceProviderInterface;\nuse Silex\\Api\\EventListenerProviderInterface;\nuse Symfony\\Component\\EventDispatcher\\EventDispatcherInterface;\nuse Symfony\\Component\\HttpKernel\\Fragment\\FragmentHandler;\nuse Symfony\\Component\\HttpKernel\\Fragment\\InlineFragmentRenderer;\nuse Symfony\\Component\\HttpKernel\\Fragment\\EsiFragmentRenderer;\nuse Symfony\\Component\\HttpKernel\\Fragment\\HIncludeFragmentRenderer;\nuse Symfony\\Component\\HttpKernel\\EventListener\\FragmentListener;\nuse Symfony\\Component\\HttpKernel\\Kernel;\nuse Symfony\\Component\\HttpKernel\\UriSigner;\n\n/**\n * HttpKernel Fragment integration for Silex.\n *\n * @author Fabien Potencier <fabien@symfony.com>\n */\nclass HttpFragmentServiceProvider implements ServiceProviderInterface, EventListenerProviderInterface\n{\n    public function register(Container $app)\n    {\n        $app['fragment.handler'] = function ($app) {\n            return new FragmentHandler($app['request_stack'], $app['fragment.renderers'], $app['debug']);\n        };\n\n        $app['fragment.renderer.inline'] = function ($app) {\n            $renderer = new InlineFragmentRenderer($app['kernel'], $app['dispatcher']);\n            $renderer->setFragmentPath($app['fragment.path']);\n\n            return $renderer;\n        };\n\n        $app['fragment.renderer.hinclude'] = function ($app) {\n            $renderer = new HIncludeFragmentRenderer(null, $app['uri_signer'], $app['fragment.renderer.hinclude.global_template'], $app['charset']);\n            $renderer->setFragmentPath($app['fragment.path']);\n\n            return $renderer;\n        };\n\n        $app['fragment.renderer.esi'] = function ($app) {\n            $renderer = new EsiFragmentRenderer($app['http_cache.esi'], $app['fragment.renderer.inline']);\n            $renderer->setFragmentPath($app['fragment.path']);\n\n            return $renderer;\n        };\n\n        $app['fragment.listener'] = function ($app) {\n            return new FragmentListener($app['uri_signer'], $app['fragment.path']);\n        };\n\n        $app['uri_signer'] = function ($app) {\n            return new UriSigner($app['uri_signer.secret']);\n        };\n\n        $app['uri_signer.secret'] = md5(__DIR__);\n        $app['fragment.path'] = '/_fragment';\n        $app['fragment.renderer.hinclude.global_template'] = null;\n        $app['fragment.renderers'] = function ($app) {\n            $renderers = array($app['fragment.renderer.inline'], $app['fragment.renderer.hinclude']);\n\n            if (isset($app['http_cache.esi'])) {\n                $renderers[] = $app['fragment.renderer.esi'];\n            }\n\n            return $renderers;\n        };\n    }\n\n    public function subscribe(Container $app, EventDispatcherInterface $dispatcher)\n    {\n        $dispatcher->addSubscriber($app['fragment.listener']);\n    }\n}\n"
  },
  {
    "path": "src/Silex/Provider/HttpKernelServiceProvider.php",
    "content": "<?php\n\nnamespace Silex\\Provider;\n\nuse Pimple\\Container;\nuse Pimple\\ServiceProviderInterface;\nuse Silex\\Api\\EventListenerProviderInterface;\nuse Silex\\AppArgumentValueResolver;\nuse Silex\\CallbackResolver;\nuse Silex\\ControllerResolver;\nuse Silex\\EventListener\\ConverterListener;\nuse Silex\\EventListener\\MiddlewareListener;\nuse Silex\\EventListener\\StringToResponseListener;\nuse Symfony\\Component\\EventDispatcher\\EventDispatcher;\nuse Symfony\\Component\\EventDispatcher\\EventDispatcherInterface;\nuse Symfony\\Component\\HttpKernel\\Controller\\ArgumentResolver;\nuse Symfony\\Component\\HttpKernel\\Controller\\ArgumentResolver\\RequestAttributeValueResolver;\nuse Symfony\\Component\\HttpKernel\\Controller\\ArgumentResolver\\RequestValueResolver;\nuse Symfony\\Component\\HttpKernel\\Controller\\ArgumentResolver\\DefaultValueResolver;\nuse Symfony\\Component\\HttpKernel\\Controller\\ArgumentResolver\\VariadicValueResolver;\nuse Symfony\\Component\\HttpKernel\\Controller\\ControllerResolver as SfControllerResolver;\nuse Symfony\\Component\\HttpFoundation\\RequestStack;\nuse Symfony\\Component\\HttpKernel\\ControllerMetadata\\ArgumentMetadataFactory;\nuse Symfony\\Component\\HttpKernel\\EventListener\\ResponseListener;\nuse Symfony\\Component\\HttpKernel\\HttpKernel;\nuse Symfony\\Component\\HttpKernel\\Kernel;\n\nclass HttpKernelServiceProvider implements ServiceProviderInterface, EventListenerProviderInterface\n{\n    /**\n     * {@inheritdoc}\n     */\n    public function register(Container $app)\n    {\n        $app['resolver'] = function ($app) {\n            if (Kernel::VERSION_ID >= 30100) {\n                return new SfControllerResolver($app['logger']);\n            }\n\n            return new ControllerResolver($app, $app['logger']);\n        };\n\n        if (Kernel::VERSION_ID >= 30100) {\n            $app['argument_metadata_factory'] = function ($app) {\n                return new ArgumentMetadataFactory();\n            };\n            $app['argument_value_resolvers'] = function ($app) {\n                if (Kernel::VERSION_ID < 30200) {\n                    return array(\n                        new AppArgumentValueResolver($app),\n                        new RequestAttributeValueResolver(),\n                        new RequestValueResolver(),\n                        new DefaultValueResolver(),\n                        new VariadicValueResolver(),\n                    );\n                }\n\n                return array_merge(array(new AppArgumentValueResolver($app)), ArgumentResolver::getDefaultArgumentValueResolvers());\n            };\n        }\n\n        $app['argument_resolver'] = function ($app) {\n            if (Kernel::VERSION_ID >= 30100) {\n                return new ArgumentResolver($app['argument_metadata_factory'], $app['argument_value_resolvers']);\n            }\n        };\n\n        $app['kernel'] = function ($app) {\n            return new HttpKernel($app['dispatcher'], $app['resolver'], $app['request_stack'], $app['argument_resolver']);\n        };\n\n        $app['request_stack'] = function () {\n            return new RequestStack();\n        };\n\n        $app['dispatcher'] = function () {\n            return new EventDispatcher();\n        };\n\n        $app['callback_resolver'] = function ($app) {\n            return new CallbackResolver($app);\n        };\n    }\n\n    /**\n     * {@inheritdoc}\n     */\n    public function subscribe(Container $app, EventDispatcherInterface $dispatcher)\n    {\n        $dispatcher->addSubscriber(new ResponseListener($app['charset']));\n        $dispatcher->addSubscriber(new MiddlewareListener($app));\n        $dispatcher->addSubscriber(new ConverterListener($app['routes'], $app['callback_resolver']));\n        $dispatcher->addSubscriber(new StringToResponseListener());\n    }\n}\n"
  },
  {
    "path": "src/Silex/Provider/LICENSE",
    "content": "Copyright (c) 2010-2015 Fabien Potencier\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is furnished\nto do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n"
  },
  {
    "path": "src/Silex/Provider/Locale/LocaleListener.php",
    "content": "<?php\n\n/*\n * This file is part of the Silex framework.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Silex\\Provider\\Locale;\n\nuse Pimple\\Container;\nuse Symfony\\Component\\HttpKernel\\Event\\GetResponseEvent;\nuse Symfony\\Component\\HttpKernel\\Event\\FinishRequestEvent;\nuse Symfony\\Component\\HttpKernel\\KernelEvents;\nuse Symfony\\Component\\HttpFoundation\\Request;\nuse Symfony\\Component\\HttpFoundation\\RequestStack;\nuse Symfony\\Component\\Routing\\RequestContext;\nuse Symfony\\Component\\EventDispatcher\\EventSubscriberInterface;\n\n/**\n * Initializes the locale based on the current request.\n *\n * @author Fabien Potencier <fabien@symfony.com>\n * @author Jérôme Tamarelle <jerome@tamarelle.net>\n */\nclass LocaleListener implements EventSubscriberInterface\n{\n    private $app;\n    private $defaultLocale;\n    private $requestStack;\n    private $requestContext;\n\n    public function __construct(Container $app, $defaultLocale = 'en', RequestStack $requestStack, RequestContext $requestContext = null)\n    {\n        $this->app = $app;\n        $this->defaultLocale = $defaultLocale;\n        $this->requestStack = $requestStack;\n        $this->requestContext = $requestContext;\n    }\n\n    public function onKernelRequest(GetResponseEvent $event)\n    {\n        $request = $event->getRequest();\n        $request->setDefaultLocale($this->defaultLocale);\n\n        $this->setLocale($request);\n        $this->setRouterContext($request);\n\n        $this->app['locale'] = $request->getLocale();\n    }\n\n    public function onKernelFinishRequest(FinishRequestEvent $event)\n    {\n        if (null !== $parentRequest = $this->requestStack->getParentRequest()) {\n            $this->setRouterContext($parentRequest);\n        }\n    }\n\n    private function setLocale(Request $request)\n    {\n        if ($locale = $request->attributes->get('_locale')) {\n            $request->setLocale($locale);\n        }\n    }\n\n    private function setRouterContext(Request $request)\n    {\n        if (null !== $this->requestContext) {\n            $this->requestContext->setParameter('_locale', $request->getLocale());\n        }\n    }\n\n    public static function getSubscribedEvents()\n    {\n        return array(\n            // must be registered after the Router to have access to the _locale\n            KernelEvents::REQUEST => array(array('onKernelRequest', 16)),\n            KernelEvents::FINISH_REQUEST => array(array('onKernelFinishRequest', 0)),\n        );\n    }\n}\n"
  },
  {
    "path": "src/Silex/Provider/LocaleServiceProvider.php",
    "content": "<?php\n\n/*\n * This file is part of the Silex framework.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Silex\\Provider;\n\nuse Pimple\\Container;\nuse Pimple\\ServiceProviderInterface;\nuse Silex\\Api\\EventListenerProviderInterface;\nuse Silex\\Provider\\Locale\\LocaleListener;\nuse Symfony\\Component\\EventDispatcher\\EventDispatcherInterface;\n\n/**\n * Locale Provider.\n *\n * @author Fabien Potencier <fabien@symfony.com>\n */\nclass LocaleServiceProvider implements ServiceProviderInterface, EventListenerProviderInterface\n{\n    public function register(Container $app)\n    {\n        $app['locale.listener'] = function ($app) {\n            return new LocaleListener($app, $app['locale'], $app['request_stack'], isset($app['request_context']) ? $app['request_context'] : null);\n        };\n\n        $app['locale'] = 'en';\n    }\n\n    public function subscribe(Container $app, EventDispatcherInterface $dispatcher)\n    {\n        $dispatcher->addSubscriber($app['locale.listener']);\n    }\n}\n"
  },
  {
    "path": "src/Silex/Provider/MonologServiceProvider.php",
    "content": "<?php\n\n/*\n * This file is part of the Silex framework.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Silex\\Provider;\n\nuse Pimple\\Container;\nuse Pimple\\ServiceProviderInterface;\nuse Monolog\\Formatter\\LineFormatter;\nuse Monolog\\Logger;\nuse Monolog\\Handler;\nuse Monolog\\ErrorHandler;\nuse Silex\\Application;\nuse Silex\\Api\\BootableProviderInterface;\nuse Symfony\\Bridge\\Monolog\\Handler\\DebugHandler;\nuse Symfony\\Bridge\\Monolog\\Handler\\FingersCrossed\\NotFoundActivationStrategy;\nuse Silex\\EventListener\\LogListener;\n\n/**\n * Monolog Provider.\n *\n * @author Fabien Potencier <fabien@symfony.com>\n */\nclass MonologServiceProvider implements ServiceProviderInterface, BootableProviderInterface\n{\n    public function register(Container $app)\n    {\n        $app['logger'] = function () use ($app) {\n            return $app['monolog'];\n        };\n\n        if ($bridge = class_exists('Symfony\\Bridge\\Monolog\\Logger')) {\n            $app['monolog.handler.debug'] = function () use ($app) {\n                $level = MonologServiceProvider::translateLevel($app['monolog.level']);\n\n                return new DebugHandler($level);\n            };\n\n            if (isset($app['request_stack'])) {\n                $app['monolog.not_found_activation_strategy'] = function () use ($app) {\n                    return new NotFoundActivationStrategy($app['request_stack'], array('^/'), $app['monolog.level']);\n                };\n            }\n        }\n\n        $app['monolog.logger.class'] = $bridge ? 'Symfony\\Bridge\\Monolog\\Logger' : 'Monolog\\Logger';\n\n        $app['monolog'] = function ($app) {\n            $log = new $app['monolog.logger.class']($app['monolog.name']);\n\n            $handler = new Handler\\GroupHandler($app['monolog.handlers']);\n            if (isset($app['monolog.not_found_activation_strategy'])) {\n                $handler = new Handler\\FingersCrossedHandler($handler, $app['monolog.not_found_activation_strategy']);\n            }\n\n            $log->pushHandler($handler);\n\n            if ($app['debug'] && isset($app['monolog.handler.debug'])) {\n                $log->pushHandler($app['monolog.handler.debug']);\n            }\n\n            return $log;\n        };\n\n        $app['monolog.formatter'] = function () {\n            return new LineFormatter();\n        };\n\n        $app['monolog.handler'] = $defaultHandler = function () use ($app) {\n            $level = MonologServiceProvider::translateLevel($app['monolog.level']);\n\n            $handler = new Handler\\StreamHandler($app['monolog.logfile'], $level, $app['monolog.bubble'], $app['monolog.permission']);\n            $handler->setFormatter($app['monolog.formatter']);\n\n            return $handler;\n        };\n\n        $app['monolog.handlers'] = function () use ($app, $defaultHandler) {\n            $handlers = array();\n\n            // enables the default handler if a logfile was set or the monolog.handler service was redefined\n            if ($app['monolog.logfile'] || $defaultHandler !== $app->raw('monolog.handler')) {\n                $handlers[] = $app['monolog.handler'];\n            }\n\n            return $handlers;\n        };\n\n        $app['monolog.level'] = function () {\n            return Logger::DEBUG;\n        };\n\n        $app['monolog.listener'] = function () use ($app) {\n            return new LogListener($app['logger'], $app['monolog.exception.logger_filter']);\n        };\n\n        $app['monolog.name'] = 'app';\n        $app['monolog.bubble'] = true;\n        $app['monolog.permission'] = null;\n        $app['monolog.exception.logger_filter'] = null;\n        $app['monolog.logfile'] = null;\n        $app['monolog.use_error_handler'] = function ($app) {\n            return !$app['debug'];\n        };\n    }\n\n    public function boot(Application $app)\n    {\n        if ($app['monolog.use_error_handler']) {\n            ErrorHandler::register($app['monolog']);\n        }\n\n        if (isset($app['monolog.listener'])) {\n            $app['dispatcher']->addSubscriber($app['monolog.listener']);\n        }\n    }\n\n    public static function translateLevel($name)\n    {\n        // level is already translated to logger constant, return as-is\n        if (is_int($name)) {\n            return $name;\n        }\n\n        $levels = Logger::getLevels();\n        $upper = strtoupper($name);\n\n        if (!isset($levels[$upper])) {\n            throw new \\InvalidArgumentException(\"Provided logging level '$name' does not exist. Must be a valid monolog logging level.\");\n        }\n\n        return $levels[$upper];\n    }\n}\n"
  },
  {
    "path": "src/Silex/Provider/RememberMeServiceProvider.php",
    "content": "<?php\n\n/*\n * This file is part of the Silex framework.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Silex\\Provider;\n\nuse Pimple\\Container;\nuse Pimple\\ServiceProviderInterface;\nuse Silex\\Api\\EventListenerProviderInterface;\nuse Symfony\\Component\\EventDispatcher\\EventDispatcherInterface;\nuse Symfony\\Component\\Security\\Core\\Authentication\\Provider\\RememberMeAuthenticationProvider;\nuse Symfony\\Component\\Security\\Http\\Firewall\\RememberMeListener;\nuse Symfony\\Component\\Security\\Http\\RememberMe\\TokenBasedRememberMeServices;\nuse Symfony\\Component\\Security\\Http\\RememberMe\\ResponseListener;\n\n/**\n * Remember-me authentication for the SecurityServiceProvider.\n *\n * @author Jérôme Tamarelle <jerome@tamarelle.net>\n */\nclass RememberMeServiceProvider implements ServiceProviderInterface, EventListenerProviderInterface\n{\n    public function register(Container $app)\n    {\n        $app['security.remember_me.response_listener'] = function ($app) {\n            if (!isset($app['security.token_storage'])) {\n                throw new \\LogicException('You must register the SecurityServiceProvider to use the RememberMeServiceProvider');\n            }\n\n            return new ResponseListener();\n        };\n\n        $app['security.authentication_listener.factory.remember_me'] = $app->protect(function ($name, $options) use ($app) {\n            if (empty($options['key'])) {\n                $options['key'] = $name;\n            }\n\n            if (!isset($app['security.remember_me.service.'.$name])) {\n                $app['security.remember_me.service.'.$name] = $app['security.remember_me.service._proto']($name, $options);\n            }\n\n            if (!isset($app['security.authentication_listener.'.$name.'.remember_me'])) {\n                $app['security.authentication_listener.'.$name.'.remember_me'] = $app['security.authentication_listener.remember_me._proto']($name, $options);\n            }\n\n            if (!isset($app['security.authentication_provider.'.$name.'.remember_me'])) {\n                $app['security.authentication_provider.'.$name.'.remember_me'] = $app['security.authentication_provider.remember_me._proto']($name, $options);\n            }\n\n            return array(\n                'security.authentication_provider.'.$name.'.remember_me',\n                'security.authentication_listener.'.$name.'.remember_me',\n                null, // entry point\n                'remember_me',\n            );\n        });\n\n        $app['security.remember_me.service._proto'] = $app->protect(function ($providerKey, $options) use ($app) {\n            return function () use ($providerKey, $options, $app) {\n                $options = array_replace(array(\n                    'name' => 'REMEMBERME',\n                    'lifetime' => 31536000,\n                    'path' => '/',\n                    'domain' => null,\n                    'secure' => false,\n                    'httponly' => true,\n                    'always_remember_me' => false,\n                    'remember_me_parameter' => '_remember_me',\n                ), $options);\n\n                return new TokenBasedRememberMeServices(array($app['security.user_provider.'.$providerKey]), $options['key'], $providerKey, $options, $app['logger']);\n            };\n        });\n\n        $app['security.authentication_listener.remember_me._proto'] = $app->protect(function ($providerKey) use ($app) {\n            return function () use ($app, $providerKey) {\n                $listener = new RememberMeListener(\n                    $app['security.token_storage'],\n                    $app['security.remember_me.service.'.$providerKey],\n                    $app['security.authentication_manager'],\n                    $app['logger'],\n                    $app['dispatcher']\n                );\n\n                return $listener;\n            };\n        });\n\n        $app['security.authentication_provider.remember_me._proto'] = $app->protect(function ($name, $options) use ($app) {\n            return function () use ($app, $name, $options) {\n                return new RememberMeAuthenticationProvider($app['security.user_checker'], $options['key'], $name);\n            };\n        });\n    }\n\n    public function subscribe(Container $app, EventDispatcherInterface $dispatcher)\n    {\n        $dispatcher->addSubscriber($app['security.remember_me.response_listener']);\n    }\n}\n"
  },
  {
    "path": "src/Silex/Provider/Routing/LazyRequestMatcher.php",
    "content": "<?php\n\n/*\n * This file is part of the Silex framework.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Silex\\Provider\\Routing;\n\nuse Symfony\\Component\\HttpFoundation\\Request;\nuse Symfony\\Component\\Routing\\Matcher\\RequestMatcherInterface;\nuse Symfony\\Component\\Routing\\Matcher\\UrlMatcherInterface;\n\n/**\n * Implements a lazy UrlMatcher.\n *\n * @author Igor Wiedler <igor@wiedler.ch>\n * @author Jérôme Tamarelle <jerome@tamarelle.net>\n */\nclass LazyRequestMatcher implements RequestMatcherInterface\n{\n    private $factory;\n\n    public function __construct(\\Closure $factory)\n    {\n        $this->factory = $factory;\n    }\n\n    /**\n     * Returns the corresponding RequestMatcherInterface instance.\n     *\n     * @return UrlMatcherInterface\n     */\n    public function getRequestMatcher()\n    {\n        $matcher = call_user_func($this->factory);\n        if (!$matcher instanceof RequestMatcherInterface) {\n            throw new \\LogicException(\"Factory supplied to LazyRequestMatcher must return implementation of Symfony\\Component\\Routing\\RequestMatcherInterface.\");\n        }\n\n        return $matcher;\n    }\n\n    /**\n     * {@inheritdoc}\n     */\n    public function matchRequest(Request $request)\n    {\n        return $this->getRequestMatcher()->matchRequest($request);\n    }\n}\n"
  },
  {
    "path": "src/Silex/Provider/Routing/RedirectableUrlMatcher.php",
    "content": "<?php\n\n/*\n * This file is part of the Silex framework.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Silex\\Provider\\Routing;\n\nuse Symfony\\Component\\HttpFoundation\\RedirectResponse;\nuse Symfony\\Component\\Routing\\Matcher\\RedirectableUrlMatcher as BaseRedirectableUrlMatcher;\n\n/**\n * Implements the RedirectableUrlMatcherInterface for Silex.\n *\n * @author Fabien Potencier <fabien@symfony.com>\n */\nclass RedirectableUrlMatcher extends BaseRedirectableUrlMatcher\n{\n    /**\n     * {@inheritdoc}\n     */\n    public function redirect($path, $route, $scheme = null)\n    {\n        $url = $this->context->getBaseUrl().$path;\n        $query = $this->context->getQueryString() ?: '';\n\n        if ($query !== '') {\n            $url .= '?'.$query;\n        }\n\n        if ($this->context->getHost()) {\n            if ($scheme) {\n                $port = '';\n                if ('http' === $scheme && 80 != $this->context->getHttpPort()) {\n                    $port = ':'.$this->context->getHttpPort();\n                } elseif ('https' === $scheme && 443 != $this->context->getHttpsPort()) {\n                    $port = ':'.$this->context->getHttpsPort();\n                }\n\n                $url = $scheme.'://'.$this->context->getHost().$port.$url;\n            }\n        }\n\n        return array(\n            '_controller' => function ($url) { return new RedirectResponse($url, 301); },\n            'url' => $url,\n        );\n    }\n}\n"
  },
  {
    "path": "src/Silex/Provider/RoutingServiceProvider.php",
    "content": "<?php\n\n/*\n * This file is part of the Silex framework.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Silex\\Provider;\n\nuse Pimple\\Container;\nuse Pimple\\ServiceProviderInterface;\nuse Silex\\ControllerCollection;\nuse Silex\\Api\\EventListenerProviderInterface;\nuse Silex\\Provider\\Routing\\RedirectableUrlMatcher;\nuse Silex\\Provider\\Routing\\LazyRequestMatcher;\nuse Symfony\\Component\\Routing\\RouteCollection;\nuse Symfony\\Component\\Routing\\Generator\\UrlGenerator;\nuse Symfony\\Component\\Routing\\RequestContext;\nuse Symfony\\Component\\HttpKernel\\EventListener\\RouterListener;\nuse Symfony\\Component\\EventDispatcher\\EventDispatcherInterface;\n\n/**\n * Symfony Routing component Provider.\n *\n * @author Fabien Potencier <fabien@symfony.com>\n */\nclass RoutingServiceProvider implements ServiceProviderInterface, EventListenerProviderInterface\n{\n    public function register(Container $app)\n    {\n        $app['route_class'] = 'Silex\\\\Route';\n\n        $app['route_factory'] = $app->factory(function ($app) {\n            return new $app['route_class']();\n        });\n\n        $app['routes_factory'] = $app->factory(function () {\n            return new RouteCollection();\n        });\n\n        $app['routes'] = function ($app) {\n            return $app['routes_factory'];\n        };\n        $app['url_generator'] = function ($app) {\n            return new UrlGenerator($app['routes'], $app['request_context']);\n        };\n\n        $app['request_matcher'] = function ($app) {\n            return new RedirectableUrlMatcher($app['routes'], $app['request_context']);\n        };\n\n        $app['request_context'] = function ($app) {\n            $context = new RequestContext();\n\n            $context->setHttpPort(isset($app['request.http_port']) ? $app['request.http_port'] : 80);\n            $context->setHttpsPort(isset($app['request.https_port']) ? $app['request.https_port'] : 443);\n\n            return $context;\n        };\n\n        $app['controllers'] = function ($app) {\n            return $app['controllers_factory'];\n        };\n\n        $controllers_factory = function () use ($app, &$controllers_factory) {\n            return new ControllerCollection($app['route_factory'], $app['routes_factory'], $controllers_factory);\n        };\n        $app['controllers_factory'] = $app->factory($controllers_factory);\n\n        $app['routing.listener'] = function ($app) {\n            $urlMatcher = new LazyRequestMatcher(function () use ($app) {\n                return $app['request_matcher'];\n            });\n\n            return new RouterListener($urlMatcher, $app['request_stack'], $app['request_context'], $app['logger']);\n        };\n    }\n\n    public function subscribe(Container $app, EventDispatcherInterface $dispatcher)\n    {\n        $dispatcher->addSubscriber($app['routing.listener']);\n    }\n}\n"
  },
  {
    "path": "src/Silex/Provider/SecurityServiceProvider.php",
    "content": "<?php\n\n/*\n * This file is part of the Silex framework.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Silex\\Provider;\n\nuse Pimple\\Container;\nuse Pimple\\ServiceProviderInterface;\nuse Silex\\Application;\nuse Silex\\Api\\BootableProviderInterface;\nuse Silex\\Api\\ControllerProviderInterface;\nuse Silex\\Api\\EventListenerProviderInterface;\nuse Symfony\\Component\\EventDispatcher\\EventDispatcherInterface;\nuse Symfony\\Component\\HttpFoundation\\RequestMatcher;\nuse Symfony\\Component\\HttpFoundation\\Request;\nuse Symfony\\Component\\Security\\Core\\Security;\nuse Symfony\\Component\\Security\\Core\\User\\UserChecker;\nuse Symfony\\Component\\Security\\Core\\User\\InMemoryUserProvider;\nuse Symfony\\Component\\Security\\Core\\Encoder\\EncoderFactory;\nuse Symfony\\Component\\Security\\Core\\Encoder\\MessageDigestPasswordEncoder;\nuse Symfony\\Component\\Security\\Core\\Encoder\\BCryptPasswordEncoder;\nuse Symfony\\Component\\Security\\Core\\Encoder\\Pbkdf2PasswordEncoder;\nuse Symfony\\Component\\Security\\Core\\Authentication\\Provider\\DaoAuthenticationProvider;\nuse Symfony\\Component\\Security\\Core\\Authentication\\Provider\\AnonymousAuthenticationProvider;\nuse Symfony\\Component\\Security\\Core\\Authentication\\AuthenticationProviderManager;\nuse Symfony\\Component\\Security\\Core\\Authentication\\AuthenticationTrustResolver;\nuse Symfony\\Component\\Security\\Http\\Authentication\\DefaultAuthenticationSuccessHandler;\nuse Symfony\\Component\\Security\\Http\\Authentication\\DefaultAuthenticationFailureHandler;\nuse Symfony\\Component\\Security\\Core\\Authentication\\Token\\Storage\\TokenStorage;\nuse Symfony\\Component\\Security\\Core\\Authorization\\AuthorizationChecker;\nuse Symfony\\Component\\Security\\Core\\Authorization\\Voter\\RoleHierarchyVoter;\nuse Symfony\\Component\\Security\\Core\\Authorization\\Voter\\AuthenticatedVoter;\nuse Symfony\\Component\\Security\\Core\\Authorization\\AccessDecisionManager;\nuse Symfony\\Component\\Security\\Core\\Role\\RoleHierarchy;\nuse Symfony\\Component\\Security\\Core\\Validator\\Constraints\\UserPasswordValidator;\nuse Symfony\\Component\\Security\\Http\\Firewall;\nuse Symfony\\Component\\Security\\Http\\FirewallMap;\nuse Symfony\\Component\\Security\\Http\\Firewall\\AbstractAuthenticationListener;\nuse Symfony\\Component\\Security\\Http\\Firewall\\AccessListener;\nuse Symfony\\Component\\Security\\Http\\Firewall\\BasicAuthenticationListener;\nuse Symfony\\Component\\Security\\Http\\Firewall\\LogoutListener;\nuse Symfony\\Component\\Security\\Http\\Firewall\\SwitchUserListener;\nuse Symfony\\Component\\Security\\Http\\Firewall\\AnonymousAuthenticationListener;\nuse Symfony\\Component\\Security\\Http\\Firewall\\ContextListener;\nuse Symfony\\Component\\Security\\Http\\Firewall\\ExceptionListener;\nuse Symfony\\Component\\Security\\Http\\Firewall\\ChannelListener;\nuse Symfony\\Component\\Security\\Http\\EntryPoint\\FormAuthenticationEntryPoint;\nuse Symfony\\Component\\Security\\Http\\EntryPoint\\BasicAuthenticationEntryPoint;\nuse Symfony\\Component\\Security\\Http\\EntryPoint\\RetryAuthenticationEntryPoint;\nuse Symfony\\Component\\Security\\Http\\Session\\SessionAuthenticationStrategy;\nuse Symfony\\Component\\Security\\Http\\Logout\\SessionLogoutHandler;\nuse Symfony\\Component\\Security\\Http\\Logout\\DefaultLogoutSuccessHandler;\nuse Symfony\\Component\\Security\\Http\\AccessMap;\nuse Symfony\\Component\\Security\\Http\\HttpUtils;\nuse Symfony\\Component\\Security\\Guard\\GuardAuthenticatorHandler;\nuse Symfony\\Component\\Security\\Guard\\Firewall\\GuardAuthenticationListener;\nuse Symfony\\Component\\Security\\Guard\\Provider\\GuardAuthenticationProvider;\n\n/**\n * Symfony Security component Provider.\n *\n * @author Fabien Potencier <fabien@symfony.com>\n */\nclass SecurityServiceProvider implements ServiceProviderInterface, EventListenerProviderInterface, ControllerProviderInterface, BootableProviderInterface\n{\n    protected $fakeRoutes;\n\n    public function register(Container $app)\n    {\n        // used to register routes for login_check and logout\n        $this->fakeRoutes = array();\n\n        $that = $this;\n\n        $app['security.role_hierarchy'] = array();\n        $app['security.access_rules'] = array();\n        $app['security.hide_user_not_found'] = true;\n        $app['security.encoder.bcrypt.cost'] = 13;\n\n        $app['security.authorization_checker'] = function ($app) {\n            return new AuthorizationChecker($app['security.token_storage'], $app['security.authentication_manager'], $app['security.access_manager']);\n        };\n\n        $app['security.token_storage'] = function ($app) {\n            return new TokenStorage();\n        };\n\n        $app['user'] = $app->factory(function ($app) {\n            if (null === $token = $app['security.token_storage']->getToken()) {\n                return;\n            }\n\n            if (!is_object($user = $token->getUser())) {\n                return;\n            }\n\n            return $user;\n        });\n\n        $app['security.authentication_manager'] = function ($app) {\n            $manager = new AuthenticationProviderManager($app['security.authentication_providers']);\n            $manager->setEventDispatcher($app['dispatcher']);\n\n            return $manager;\n        };\n\n        // by default, all users use the digest encoder\n        $app['security.encoder_factory'] = function ($app) {\n            return new EncoderFactory(array(\n                'Symfony\\Component\\Security\\Core\\User\\UserInterface' => $app['security.default_encoder'],\n            ));\n        };\n\n        // by default, all users use the BCrypt encoder\n        $app['security.default_encoder'] = function ($app) {\n            return $app['security.encoder.bcrypt'];\n        };\n\n        $app['security.encoder.digest'] = function ($app) {\n            return new MessageDigestPasswordEncoder();\n        };\n\n        $app['security.encoder.bcrypt'] = function ($app) {\n            return new BCryptPasswordEncoder($app['security.encoder.bcrypt.cost']);\n        };\n\n        $app['security.encoder.pbkdf2'] = function ($app) {\n            return new Pbkdf2PasswordEncoder();\n        };\n\n        $app['security.user_checker'] = function ($app) {\n            return new UserChecker();\n        };\n\n        $app['security.access_manager'] = function ($app) {\n            return new AccessDecisionManager($app['security.voters']);\n        };\n\n        $app['security.voters'] = function ($app) {\n            return array(\n                new RoleHierarchyVoter(new RoleHierarchy($app['security.role_hierarchy'])),\n                new AuthenticatedVoter($app['security.trust_resolver']),\n            );\n        };\n\n        $app['security.firewall'] = function ($app) {\n            return new Firewall($app['security.firewall_map'], $app['dispatcher']);\n        };\n\n        $app['security.channel_listener'] = function ($app) {\n            return new ChannelListener(\n                $app['security.access_map'],\n                new RetryAuthenticationEntryPoint(\n                    isset($app['request.http_port']) ? $app['request.http_port'] : 80,\n                    isset($app['request.https_port']) ? $app['request.https_port'] : 443\n                ),\n                $app['logger']\n            );\n        };\n\n        // generate the build-in authentication factories\n        foreach (array('logout', 'pre_auth', 'guard', 'form', 'http', 'remember_me', 'anonymous') as $type) {\n            $entryPoint = null;\n            if ('http' === $type) {\n                $entryPoint = 'http';\n            } elseif ('form' === $type) {\n                $entryPoint = 'form';\n            } elseif ('guard' === $type) {\n                $entryPoint = 'guard';\n            }\n\n            $app['security.authentication_listener.factory.'.$type] = $app->protect(function ($name, $options) use ($type, $app, $entryPoint) {\n                if ($entryPoint && !isset($app['security.entry_point.'.$name.'.'.$entryPoint])) {\n                    $app['security.entry_point.'.$name.'.'.$entryPoint] = $app['security.entry_point.'.$entryPoint.'._proto']($name, $options);\n                }\n\n                if (!isset($app['security.authentication_listener.'.$name.'.'.$type])) {\n                    $app['security.authentication_listener.'.$name.'.'.$type] = $app['security.authentication_listener.'.$type.'._proto']($name, $options);\n                }\n\n                $provider = 'dao';\n                if ('anonymous' === $type) {\n                    $provider = 'anonymous';\n                } elseif ('guard' === $type) {\n                    $provider = 'guard';\n                }\n                if (!isset($app['security.authentication_provider.'.$name.'.'.$provider])) {\n                    $app['security.authentication_provider.'.$name.'.'.$provider] = $app['security.authentication_provider.'.$provider.'._proto']($name, $options);\n                }\n\n                return array(\n                    'security.authentication_provider.'.$name.'.'.$provider,\n                    'security.authentication_listener.'.$name.'.'.$type,\n                    $entryPoint ? 'security.entry_point.'.$name.'.'.$entryPoint : null,\n                    $type,\n                );\n            });\n        }\n\n        $app['security.firewall_map'] = function ($app) {\n            $positions = array('logout', 'pre_auth', 'guard', 'form', 'http', 'remember_me', 'anonymous');\n            $providers = array();\n            $configs = array();\n            foreach ($app['security.firewalls'] as $name => $firewall) {\n                $entryPoint = null;\n                $pattern = isset($firewall['pattern']) ? $firewall['pattern'] : null;\n                $users = isset($firewall['users']) ? $firewall['users'] : array();\n                $security = isset($firewall['security']) ? (bool) $firewall['security'] : true;\n                $stateless = isset($firewall['stateless']) ? (bool) $firewall['stateless'] : false;\n                $context = isset($firewall['context']) ? $firewall['context'] : $name;\n                unset($firewall['pattern'], $firewall['users'], $firewall['security'], $firewall['stateless'], $firewall['context']);\n\n                $protected = false === $security ? false : count($firewall);\n\n                $listeners = array('security.channel_listener');\n\n                if ($protected) {\n                    if (!isset($app['security.context_listener.'.$name])) {\n                        if (!isset($app['security.user_provider.'.$name])) {\n                            $app['security.user_provider.'.$name] = is_array($users) ? $app['security.user_provider.inmemory._proto']($users) : $users;\n                        }\n\n                        $app['security.context_listener.'.$name] = $app['security.context_listener._proto']($name, array($app['security.user_provider.'.$name]));\n                    }\n\n                    if (false === $stateless) {\n                        $listeners[] = 'security.context_listener.'.$context;\n                    }\n\n                    $factories = array();\n                    foreach ($positions as $position) {\n                        $factories[$position] = array();\n                    }\n\n                    foreach ($firewall as $type => $options) {\n                        if ('switch_user' === $type) {\n                            continue;\n                        }\n\n                        // normalize options\n                        if (!is_array($options)) {\n                            if (!$options) {\n                                continue;\n                            }\n\n                            $options = array();\n                        }\n\n                        if (!isset($app['security.authentication_listener.factory.'.$type])) {\n                            throw new \\LogicException(sprintf('The \"%s\" authentication entry is not registered.', $type));\n                        }\n\n                        $options['stateless'] = $stateless;\n\n                        list($providerId, $listenerId, $entryPointId, $position) = $app['security.authentication_listener.factory.'.$type]($name, $options);\n\n                        if (null !== $entryPointId) {\n                            $entryPoint = $entryPointId;\n                        }\n\n                        $factories[$position][] = $listenerId;\n                        $providers[] = $providerId;\n                    }\n\n                    foreach ($positions as $position) {\n                        foreach ($factories[$position] as $listener) {\n                            $listeners[] = $listener;\n                        }\n                    }\n\n                    $listeners[] = 'security.access_listener';\n\n                    if (isset($firewall['switch_user'])) {\n                        $app['security.switch_user.'.$name] = $app['security.authentication_listener.switch_user._proto']($name, $firewall['switch_user']);\n\n                        $listeners[] = 'security.switch_user.'.$name;\n                    }\n\n                    if (!isset($app['security.exception_listener.'.$name])) {\n                        if (null == $entryPoint) {\n                            $app[$entryPoint = 'security.entry_point.'.$name.'.form'] = $app['security.entry_point.form._proto']($name, array());\n                        }\n                        $accessDeniedHandler = null;\n                        if (isset($app['security.access_denied_handler.'.$name])) {\n                            $accessDeniedHandler = $app['security.access_denied_handler.'.$name];\n                        }\n                        $app['security.exception_listener.'.$name] = $app['security.exception_listener._proto']($entryPoint, $name, $accessDeniedHandler);\n                    }\n                }\n\n                $configs[$name] = array($pattern, $listeners, $protected);\n            }\n\n            $app['security.authentication_providers'] = array_map(function ($provider) use ($app) {\n                return $app[$provider];\n            }, array_unique($providers));\n\n            $map = new FirewallMap();\n            foreach ($configs as $name => $config) {\n                $map->add(\n                    is_string($config[0]) ? new RequestMatcher($config[0]) : $config[0],\n                    array_map(function ($listenerId) use ($app, $name) {\n                        $listener = $app[$listenerId];\n\n                        if (isset($app['security.remember_me.service.'.$name])) {\n                            if ($listener instanceof AbstractAuthenticationListener || $listener instanceof GuardAuthenticationListener) {\n                                $listener->setRememberMeServices($app['security.remember_me.service.'.$name]);\n                            }\n                            if ($listener instanceof LogoutListener) {\n                                $listener->addHandler($app['security.remember_me.service.'.$name]);\n                            }\n                        }\n\n                        return $listener;\n                    }, $config[1]),\n                    $config[2] ? $app['security.exception_listener.'.$name] : null\n                );\n            }\n\n            return $map;\n        };\n\n        $app['security.access_listener'] = function ($app) {\n            return new AccessListener(\n                $app['security.token_storage'],\n                $app['security.access_manager'],\n                $app['security.access_map'],\n                $app['security.authentication_manager'],\n                $app['logger']\n            );\n        };\n\n        $app['security.access_map'] = function ($app) {\n            $map = new AccessMap();\n\n            foreach ($app['security.access_rules'] as $rule) {\n                if (is_string($rule[0])) {\n                    $rule[0] = new RequestMatcher($rule[0]);\n                } elseif (is_array($rule[0])) {\n                    $rule[0] += [\n                        'path' => null,\n                        'host' => null,\n                        'methods' => null,\n                        'ips' => null,\n                        'attributes' => array(),\n                        'schemes' => null,\n                    ];\n                    $rule[0] = new RequestMatcher($rule[0]['path'], $rule[0]['host'], $rule[0]['methods'], $rule[0]['ips'], $rule[0]['attributes'], $rule[0]['schemes']);\n                }\n                $map->add($rule[0], (array) $rule[1], isset($rule[2]) ? $rule[2] : null);\n            }\n\n            return $map;\n        };\n\n        $app['security.trust_resolver'] = function ($app) {\n            return new AuthenticationTrustResolver('Symfony\\Component\\Security\\Core\\Authentication\\Token\\AnonymousToken', 'Symfony\\Component\\Security\\Core\\Authentication\\Token\\RememberMeToken');\n        };\n\n        $app['security.session_strategy'] = function ($app) {\n            return new SessionAuthenticationStrategy(SessionAuthenticationStrategy::MIGRATE);\n        };\n\n        $app['security.http_utils'] = function ($app) {\n            return new HttpUtils($app['url_generator'], $app['request_matcher']);\n        };\n\n        $app['security.last_error'] = $app->protect(function (Request $request) {\n            if ($request->attributes->has(Security::AUTHENTICATION_ERROR)) {\n                return $request->attributes->get(Security::AUTHENTICATION_ERROR)->getMessage();\n            }\n\n            $session = $request->getSession();\n            if ($session && $session->has(Security::AUTHENTICATION_ERROR)) {\n                $message = $session->get(Security::AUTHENTICATION_ERROR)->getMessage();\n                $session->remove(Security::AUTHENTICATION_ERROR);\n\n                return $message;\n            }\n        });\n\n        // prototypes (used by the Firewall Map)\n\n        $app['security.context_listener._proto'] = $app->protect(function ($providerKey, $userProviders) use ($app) {\n            return function () use ($app, $userProviders, $providerKey) {\n                return new ContextListener(\n                    $app['security.token_storage'],\n                    $userProviders,\n                    $providerKey,\n                    $app['logger'],\n                    $app['dispatcher']\n                );\n            };\n        });\n\n        $app['security.user_provider.inmemory._proto'] = $app->protect(function ($params) use ($app) {\n            return function () use ($app, $params) {\n                $users = array();\n                foreach ($params as $name => $user) {\n                    $users[$name] = array('roles' => (array) $user[0], 'password' => $user[1]);\n                }\n\n                return new InMemoryUserProvider($users);\n            };\n        });\n\n        $app['security.exception_listener._proto'] = $app->protect(function ($entryPoint, $name, $accessDeniedHandler = null) use ($app) {\n            return function () use ($app, $entryPoint, $name, $accessDeniedHandler) {\n                return new ExceptionListener(\n                    $app['security.token_storage'],\n                    $app['security.trust_resolver'],\n                    $app['security.http_utils'],\n                    $name,\n                    $app[$entryPoint],\n                    null, // errorPage\n                    $accessDeniedHandler,\n                    $app['logger']\n                );\n            };\n        });\n\n        $app['security.authentication.success_handler._proto'] = $app->protect(function ($name, $options) use ($app) {\n            return function () use ($name, $options, $app) {\n                $handler = new DefaultAuthenticationSuccessHandler(\n                    $app['security.http_utils'],\n                    $options\n                );\n                $handler->setProviderKey($name);\n\n                return $handler;\n            };\n        });\n\n        $app['security.authentication.failure_handler._proto'] = $app->protect(function ($name, $options) use ($app) {\n            return function () use ($name, $options, $app) {\n                return new DefaultAuthenticationFailureHandler(\n                    $app,\n                    $app['security.http_utils'],\n                    $options,\n                    $app['logger']\n                );\n            };\n        });\n\n        $app['security.authentication_listener.guard._proto'] = $app->protect(function ($providerKey, $options) use ($app, $that) {\n            return function () use ($app, $providerKey, $options, $that) {\n                if (!isset($app['security.authentication.guard_handler'])) {\n                    $app['security.authentication.guard_handler'] = new GuardAuthenticatorHandler($app['security.token_storage'], $app['dispatcher']);\n                }\n\n                $authenticators = array();\n                foreach ($options['authenticators'] as $authenticatorId) {\n                    $authenticators[] = $app[$authenticatorId];\n                }\n\n                return new GuardAuthenticationListener(\n                    $app['security.authentication.guard_handler'],\n                    $app['security.authentication_manager'],\n                    $providerKey,\n                    $authenticators,\n                    $app['logger']\n                );\n            };\n        });\n\n        $app['security.authentication_listener.form._proto'] = $app->protect(function ($name, $options) use ($app, $that) {\n            return function () use ($app, $name, $options, $that) {\n                $that->addFakeRoute(\n                    'match',\n                    $tmp = isset($options['check_path']) ? $options['check_path'] : '/login_check',\n                    str_replace('/', '_', ltrim($tmp, '/'))\n                );\n\n                $class = isset($options['listener_class']) ? $options['listener_class'] : 'Symfony\\\\Component\\\\Security\\\\Http\\\\Firewall\\\\UsernamePasswordFormAuthenticationListener';\n\n                if (!isset($app['security.authentication.success_handler.'.$name])) {\n                    $app['security.authentication.success_handler.'.$name] = $app['security.authentication.success_handler._proto']($name, $options);\n                }\n\n                if (!isset($app['security.authentication.failure_handler.'.$name])) {\n                    $app['security.authentication.failure_handler.'.$name] = $app['security.authentication.failure_handler._proto']($name, $options);\n                }\n\n                return new $class(\n                    $app['security.token_storage'],\n                    $app['security.authentication_manager'],\n                    isset($app['security.session_strategy.'.$name]) ? $app['security.session_strategy.'.$name] : $app['security.session_strategy'],\n                    $app['security.http_utils'],\n                    $name,\n                    $app['security.authentication.success_handler.'.$name],\n                    $app['security.authentication.failure_handler.'.$name],\n                    $options,\n                    $app['logger'],\n                    $app['dispatcher'],\n                    isset($options['with_csrf']) && $options['with_csrf'] && isset($app['csrf.token_manager']) ? $app['csrf.token_manager'] : null\n                );\n            };\n        });\n\n        $app['security.authentication_listener.http._proto'] = $app->protect(function ($providerKey, $options) use ($app) {\n            return function () use ($app, $providerKey, $options) {\n                return new BasicAuthenticationListener(\n                    $app['security.token_storage'],\n                    $app['security.authentication_manager'],\n                    $providerKey,\n                    $app['security.entry_point.'.$providerKey.'.http'],\n                    $app['logger']\n                );\n            };\n        });\n\n        $app['security.authentication_listener.anonymous._proto'] = $app->protect(function ($providerKey, $options) use ($app) {\n            return function () use ($app, $providerKey, $options) {\n                return new AnonymousAuthenticationListener(\n                    $app['security.token_storage'],\n                    $providerKey,\n                    $app['logger']\n                );\n            };\n        });\n\n        $app['security.authentication.logout_handler._proto'] = $app->protect(function ($name, $options) use ($app) {\n            return function () use ($name, $options, $app) {\n                return new DefaultLogoutSuccessHandler(\n                    $app['security.http_utils'],\n                    isset($options['target_url']) ? $options['target_url'] : '/'\n                );\n            };\n        });\n\n        $app['security.authentication_listener.logout._proto'] = $app->protect(function ($name, $options) use ($app, $that) {\n            return function () use ($app, $name, $options, $that) {\n                $that->addFakeRoute(\n                    'get',\n                    $tmp = isset($options['logout_path']) ? $options['logout_path'] : '/logout',\n                    str_replace('/', '_', ltrim($tmp, '/'))\n                );\n\n                if (!isset($app['security.authentication.logout_handler.'.$name])) {\n                    $app['security.authentication.logout_handler.'.$name] = $app['security.authentication.logout_handler._proto']($name, $options);\n                }\n\n                $listener = new LogoutListener(\n                    $app['security.token_storage'],\n                    $app['security.http_utils'],\n                    $app['security.authentication.logout_handler.'.$name],\n                    $options,\n                    isset($options['with_csrf']) && $options['with_csrf'] && isset($app['csrf.token_manager']) ? $app['csrf.token_manager'] : null\n                );\n\n                $invalidateSession = isset($options['invalidate_session']) ? $options['invalidate_session'] : true;\n                if (true === $invalidateSession && false === $options['stateless']) {\n                    $listener->addHandler(new SessionLogoutHandler());\n                }\n\n                return $listener;\n            };\n        });\n\n        $app['security.authentication_listener.switch_user._proto'] = $app->protect(function ($name, $options) use ($app, $that) {\n            return function () use ($app, $name, $options, $that) {\n                return new SwitchUserListener(\n                    $app['security.token_storage'],\n                    $app['security.user_provider.'.$name],\n                    $app['security.user_checker'],\n                    $name,\n                    $app['security.access_manager'],\n                    $app['logger'],\n                    isset($options['parameter']) ? $options['parameter'] : '_switch_user',\n                    isset($options['role']) ? $options['role'] : 'ROLE_ALLOWED_TO_SWITCH',\n                    $app['dispatcher']\n                );\n            };\n        });\n\n        $app['security.entry_point.form._proto'] = $app->protect(function ($name, array $options) use ($app) {\n            return function () use ($app, $options) {\n                $loginPath = isset($options['login_path']) ? $options['login_path'] : '/login';\n                $useForward = isset($options['use_forward']) ? $options['use_forward'] : false;\n\n                return new FormAuthenticationEntryPoint($app, $app['security.http_utils'], $loginPath, $useForward);\n            };\n        });\n\n        $app['security.entry_point.http._proto'] = $app->protect(function ($name, array $options) use ($app) {\n            return function () use ($app, $name, $options) {\n                return new BasicAuthenticationEntryPoint(isset($options['real_name']) ? $options['real_name'] : 'Secured');\n            };\n        });\n\n        $app['security.entry_point.guard._proto'] = $app->protect(function ($name, array $options) use ($app) {\n            if (isset($options['entry_point'])) {\n                // if it's configured explicitly, use it!\n                return $app[$options['entry_point']];\n            }\n            $authenticatorIds = $options['authenticators'];\n            if (count($authenticatorIds) == 1) {\n                // if there is only one authenticator, use that as the entry point\n                return $app[reset($authenticatorIds)];\n            }\n            // we have multiple entry points - we must ask them to configure one\n            throw new \\LogicException(sprintf(\n                'Because you have multiple guard configurators, you need to set the \"guard.entry_point\" key to one of you configurators (%s)',\n                implode(', ', $authenticatorIds)\n            ));\n        });\n\n        $app['security.authentication_provider.dao._proto'] = $app->protect(function ($name, $options) use ($app) {\n            return function () use ($app, $name) {\n                return new DaoAuthenticationProvider(\n                    $app['security.user_provider.'.$name],\n                    $app['security.user_checker'],\n                    $name,\n                    $app['security.encoder_factory'],\n                    $app['security.hide_user_not_found']\n                );\n            };\n        });\n\n        $app['security.authentication_provider.guard._proto'] = $app->protect(function ($name, $options) use ($app) {\n            return function () use ($app, $name, $options) {\n                $authenticators = array();\n                foreach ($options['authenticators'] as $authenticatorId) {\n                    $authenticators[] = $app[$authenticatorId];\n                }\n\n                return new GuardAuthenticationProvider(\n                    $authenticators,\n                    $app['security.user_provider.'.$name],\n                    $name,\n                    $app['security.user_checker']\n                );\n            };\n        });\n\n        $app['security.authentication_provider.anonymous._proto'] = $app->protect(function ($name, $options) use ($app) {\n            return function () use ($app, $name) {\n                return new AnonymousAuthenticationProvider($name);\n            };\n        });\n\n        if (isset($app['validator'])) {\n            $app['security.validator.user_password_validator'] = function ($app) {\n                return new UserPasswordValidator($app['security.token_storage'], $app['security.encoder_factory']);\n            };\n\n            $app['validator.validator_service_ids'] = array_merge($app['validator.validator_service_ids'], array('security.validator.user_password' => 'security.validator.user_password_validator'));\n        }\n    }\n\n    public function subscribe(Container $app, EventDispatcherInterface $dispatcher)\n    {\n        $dispatcher->addSubscriber($app['security.firewall']);\n    }\n\n    public function connect(Application $app)\n    {\n        $controllers = $app['controllers_factory'];\n        foreach ($this->fakeRoutes as $route) {\n            list($method, $pattern, $name) = $route;\n\n            $controllers->$method($pattern)->run(null)->bind($name);\n        }\n\n        return $controllers;\n    }\n\n    public function boot(Application $app)\n    {\n        $app->mount('/', $this->connect($app));\n    }\n\n    public function addFakeRoute($method, $pattern, $name)\n    {\n        $this->fakeRoutes[] = array($method, $pattern, $name);\n    }\n}\n"
  },
  {
    "path": "src/Silex/Provider/SerializerServiceProvider.php",
    "content": "<?php\n\n/*\n * This file is part of the Silex framework.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Silex\\Provider;\n\nuse Pimple\\Container;\nuse Pimple\\ServiceProviderInterface;\nuse Symfony\\Component\\Serializer\\Serializer;\nuse Symfony\\Component\\Serializer\\Encoder\\JsonEncoder;\nuse Symfony\\Component\\Serializer\\Encoder\\XmlEncoder;\nuse Symfony\\Component\\Serializer\\Normalizer\\CustomNormalizer;\nuse Symfony\\Component\\Serializer\\Normalizer\\GetSetMethodNormalizer;\n\n/**\n * Symfony Serializer component Provider.\n *\n * @author Fabien Potencier <fabien@symfony.com>\n * @author Marijn Huizendveld <marijn@pink-tie.com>\n */\nclass SerializerServiceProvider implements ServiceProviderInterface\n{\n    /**\n     * {@inheritdoc}\n     *\n     * This method registers a serializer service. {@link http://api.symfony.com/master/Symfony/Component/Serializer/Serializer.html\n     * The service is provided by the Symfony Serializer component}.\n     */\n    public function register(Container $app)\n    {\n        $app['serializer'] = function ($app) {\n            return new Serializer($app['serializer.normalizers'], $app['serializer.encoders']);\n        };\n\n        $app['serializer.encoders'] = function () {\n            return array(new JsonEncoder(), new XmlEncoder());\n        };\n\n        $app['serializer.normalizers'] = function () {\n            return array(new CustomNormalizer(), new GetSetMethodNormalizer());\n        };\n    }\n}\n"
  },
  {
    "path": "src/Silex/Provider/ServiceControllerServiceProvider.php",
    "content": "<?php\n\n/*\n * This file is part of the Silex framework.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Silex\\Provider;\n\nuse Pimple\\Container;\nuse Pimple\\ServiceProviderInterface;\nuse Silex\\ServiceControllerResolver;\n\nclass ServiceControllerServiceProvider implements ServiceProviderInterface\n{\n    public function register(Container $app)\n    {\n        $app->extend('resolver', function ($resolver, $app) {\n            return new ServiceControllerResolver($resolver, $app['callback_resolver']);\n        });\n    }\n}\n"
  },
  {
    "path": "src/Silex/Provider/Session/SessionListener.php",
    "content": "<?php\n\n/*\n * This file is part of the Silex framework.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Silex\\Provider\\Session;\n\nuse Pimple\\Container;\nuse Symfony\\Component\\HttpKernel\\EventListener\\SessionListener as BaseSessionListener;\n\n/**\n * Sets the session in the request.\n *\n * @author Fabien Potencier <fabien@symfony.com>\n */\nclass SessionListener extends BaseSessionListener\n{\n    private $app;\n\n    public function __construct(Container $app)\n    {\n        $this->app = $app;\n    }\n\n    protected function getSession()\n    {\n        if (!isset($this->app['session'])) {\n            return;\n        }\n\n        return $this->app['session'];\n    }\n}\n"
  },
  {
    "path": "src/Silex/Provider/Session/TestSessionListener.php",
    "content": "<?php\n\n/*\n * This file is part of the Silex framework.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Silex\\Provider\\Session;\n\nuse Pimple\\Container;\nuse Symfony\\Component\\HttpKernel\\EventListener\\TestSessionListener as BaseTestSessionListener;\n\n/**\n * Simulates sessions for testing purpose.\n *\n * @author Fabien Potencier <fabien@symfony.com>\n */\nclass TestSessionListener extends BaseTestSessionListener\n{\n    private $app;\n\n    public function __construct(Container $app)\n    {\n        $this->app = $app;\n    }\n\n    protected function getSession()\n    {\n        if (!isset($this->app['session'])) {\n            return;\n        }\n\n        return $this->app['session'];\n    }\n}\n"
  },
  {
    "path": "src/Silex/Provider/SessionServiceProvider.php",
    "content": "<?php\n\n/*\n * This file is part of the Silex framework.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Silex\\Provider;\n\nuse Pimple\\Container;\nuse Pimple\\ServiceProviderInterface;\nuse Silex\\Api\\EventListenerProviderInterface;\nuse Silex\\Provider\\Session\\SessionListener;\nuse Silex\\Provider\\Session\\TestSessionListener;\nuse Symfony\\Component\\EventDispatcher\\EventDispatcherInterface;\nuse Symfony\\Component\\HttpFoundation\\Session\\Storage\\Handler\\NativeFileSessionHandler;\nuse Symfony\\Component\\HttpFoundation\\Session\\Storage\\NativeSessionStorage;\nuse Symfony\\Component\\HttpFoundation\\Session\\Storage\\MockFileSessionStorage;\nuse Symfony\\Component\\HttpFoundation\\Session\\Session;\n\n/**\n * Symfony HttpFoundation component Provider for sessions.\n *\n * @author Fabien Potencier <fabien@symfony.com>\n */\nclass SessionServiceProvider implements ServiceProviderInterface, EventListenerProviderInterface\n{\n    public function register(Container $app)\n    {\n        $app['session.test'] = false;\n\n        $app['session'] = function ($app) {\n            return new Session($app['session.storage'], $app['session.attribute_bag'], $app['session.flash_bag']);\n        };\n\n        $app['session.storage'] = function ($app) {\n            if ($app['session.test']) {\n                return $app['session.storage.test'];\n            }\n\n            return $app['session.storage.native'];\n        };\n\n        $app['session.storage.handler'] = function ($app) {\n            return new NativeFileSessionHandler($app['session.storage.save_path']);\n        };\n\n        $app['session.storage.native'] = function ($app) {\n            return new NativeSessionStorage(\n                $app['session.storage.options'],\n                $app['session.storage.handler']\n            );\n        };\n\n        $app['session.listener'] = function ($app) {\n            return new SessionListener($app);\n        };\n\n        $app['session.storage.test'] = function () {\n            return new MockFileSessionStorage();\n        };\n\n        $app['session.listener.test'] = function ($app) {\n            return new TestSessionListener($app);\n        };\n\n        $app['session.storage.options'] = array();\n        $app['session.default_locale'] = 'en';\n        $app['session.storage.save_path'] = null;\n        $app['session.attribute_bag'] = null;\n        $app['session.flash_bag'] = null;\n    }\n\n    public function subscribe(Container $app, EventDispatcherInterface $dispatcher)\n    {\n        $dispatcher->addSubscriber($app['session.listener']);\n\n        if ($app['session.test']) {\n            $app['dispatcher']->addSubscriber($app['session.listener.test']);\n        }\n    }\n}\n"
  },
  {
    "path": "src/Silex/Provider/SwiftmailerServiceProvider.php",
    "content": "<?php\n\n/*\n * This file is part of the Silex framework.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Silex\\Provider;\n\nuse Pimple\\Container;\nuse Pimple\\ServiceProviderInterface;\nuse Silex\\Api\\EventListenerProviderInterface;\nuse Symfony\\Component\\Console\\ConsoleEvents;\nuse Symfony\\Component\\EventDispatcher\\EventDispatcherInterface;\nuse Symfony\\Component\\HttpKernel\\KernelEvents;\nuse Symfony\\Component\\HttpKernel\\Event\\PostResponseEvent;\n\n/**\n * Swiftmailer Provider.\n *\n * @author Fabien Potencier <fabien@symfony.com>\n */\nclass SwiftmailerServiceProvider implements ServiceProviderInterface, EventListenerProviderInterface\n{\n    public function register(Container $app)\n    {\n        $app['swiftmailer.options'] = array();\n        $app['swiftmailer.use_spool'] = true;\n\n        $app['mailer.initialized'] = false;\n\n        $app['mailer'] = function ($app) {\n            $app['mailer.initialized'] = true;\n            $transport = $app['swiftmailer.use_spool'] ? $app['swiftmailer.spooltransport'] : $app['swiftmailer.transport'];\n\n            return new \\Swift_Mailer($transport);\n        };\n\n        $app['swiftmailer.spooltransport'] = function ($app) {\n            return new \\Swift_Transport_SpoolTransport($app['swiftmailer.transport.eventdispatcher'], $app['swiftmailer.spool']);\n        };\n\n        $app['swiftmailer.spool'] = function ($app) {\n            return new \\Swift_MemorySpool();\n        };\n\n        $app['swiftmailer.transport'] = function ($app) {\n            $transport = new \\Swift_Transport_EsmtpTransport(\n                $app['swiftmailer.transport.buffer'],\n                array($app['swiftmailer.transport.authhandler']),\n                $app['swiftmailer.transport.eventdispatcher']\n            );\n\n            $options = $app['swiftmailer.options'] = array_replace(array(\n                'host' => 'localhost',\n                'port' => 25,\n                'username' => '',\n                'password' => '',\n                'encryption' => null,\n                'auth_mode' => null,\n            ), $app['swiftmailer.options']);\n\n            $transport->setHost($options['host']);\n            $transport->setPort($options['port']);\n            $transport->setEncryption($options['encryption']);\n            $transport->setUsername($options['username']);\n            $transport->setPassword($options['password']);\n            $transport->setAuthMode($options['auth_mode']);\n\n            if (null !== $app['swiftmailer.sender_address']) {\n                $transport->registerPlugin(new \\Swift_Plugins_ImpersonatePlugin($app['swiftmailer.sender_address']));\n            }\n\n            if (!empty($app['swiftmailer.delivery_addresses'])) {\n                $transport->registerPlugin(new \\Swift_Plugins_RedirectingPlugin(\n                    $app['swiftmailer.delivery_addresses'],\n                    $app['swiftmailer.delivery_whitelist']\n                ));\n            }\n\n            return $transport;\n        };\n\n        $app['swiftmailer.transport.buffer'] = function () {\n            return new \\Swift_Transport_StreamBuffer(new \\Swift_StreamFilters_StringReplacementFilterFactory());\n        };\n\n        $app['swiftmailer.transport.authhandler'] = function () {\n            return new \\Swift_Transport_Esmtp_AuthHandler(array(\n                new \\Swift_Transport_Esmtp_Auth_CramMd5Authenticator(),\n                new \\Swift_Transport_Esmtp_Auth_LoginAuthenticator(),\n                new \\Swift_Transport_Esmtp_Auth_PlainAuthenticator(),\n            ));\n        };\n\n        $app['swiftmailer.transport.eventdispatcher'] = function () {\n            return new \\Swift_Events_SimpleEventDispatcher();\n        };\n\n        $app['swiftmailer.sender_address'] = null;\n        $app['swiftmailer.delivery_addresses'] = [];\n        $app['swiftmailer.delivery_whitelist'] = [];\n    }\n\n    public function subscribe(Container $app, EventDispatcherInterface $dispatcher)\n    {\n        // Event has no typehint as it can be either a PostResponseEvent or a ConsoleTerminateEvent\n        $onTerminate = function ($event) use ($app) {\n            // To speed things up (by avoiding Swift Mailer initialization), flush\n            // messages only if our mailer has been created (potentially used)\n            if ($app['mailer.initialized'] && $app['swiftmailer.use_spool'] && $app['swiftmailer.spooltransport'] instanceof \\Swift_Transport_SpoolTransport) {\n                $app['swiftmailer.spooltransport']->getSpool()->flushQueue($app['swiftmailer.transport']);\n            }\n        };\n\n        $dispatcher->addListener(KernelEvents::TERMINATE, $onTerminate);\n\n        if (class_exists('Symfony\\Component\\Console\\ConsoleEvents')) {\n            $dispatcher->addListener(ConsoleEvents::TERMINATE, $onTerminate);\n        }\n    }\n}\n"
  },
  {
    "path": "src/Silex/Provider/TranslationServiceProvider.php",
    "content": "<?php\n\n/*\n * This file is part of the Silex framework.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Silex\\Provider;\n\nuse Pimple\\Container;\nuse Pimple\\ServiceProviderInterface;\nuse Symfony\\Component\\Translation\\Translator;\nuse Symfony\\Component\\Translation\\MessageSelector;\nuse Symfony\\Component\\Translation\\Loader\\ArrayLoader;\nuse Symfony\\Component\\Translation\\Loader\\XliffFileLoader;\nuse Symfony\\Component\\EventDispatcher\\EventDispatcherInterface;\nuse Symfony\\Component\\HttpKernel\\EventListener\\TranslatorListener;\nuse Silex\\Api\\EventListenerProviderInterface;\n\n/**\n * Symfony Translation component Provider.\n *\n * @author Fabien Potencier <fabien@symfony.com>\n */\nclass TranslationServiceProvider implements ServiceProviderInterface, EventListenerProviderInterface\n{\n    public function register(Container $app)\n    {\n        $app['translator'] = function ($app) {\n            if (!isset($app['locale'])) {\n                throw new \\LogicException('You must define \\'locale\\' parameter or register the LocaleServiceProvider to use the TranslationServiceProvider');\n            }\n\n            $translator = new Translator($app['locale'], $app['translator.message_selector'], $app['translator.cache_dir'], $app['debug']);\n            $translator->setFallbackLocales($app['locale_fallbacks']);\n            $translator->addLoader('array', new ArrayLoader());\n            $translator->addLoader('xliff', new XliffFileLoader());\n\n            if (isset($app['validator'])) {\n                $r = new \\ReflectionClass('Symfony\\Component\\Validator\\Validation');\n                $file = dirname($r->getFilename()).'/Resources/translations/validators.'.$app['locale'].'.xlf';\n                if (file_exists($file)) {\n                    $translator->addResource('xliff', $file, $app['locale'], 'validators');\n                }\n            }\n\n            if (isset($app['form.factory'])) {\n                $r = new \\ReflectionClass('Symfony\\Component\\Form\\Form');\n                $file = dirname($r->getFilename()).'/Resources/translations/validators.'.$app['locale'].'.xlf';\n                if (file_exists($file)) {\n                    $translator->addResource('xliff', $file, $app['locale'], 'validators');\n                }\n            }\n\n            // Register default resources\n            foreach ($app['translator.resources'] as $resource) {\n                $translator->addResource($resource[0], $resource[1], $resource[2], $resource[3]);\n            }\n\n            foreach ($app['translator.domains'] as $domain => $data) {\n                foreach ($data as $locale => $messages) {\n                    $translator->addResource('array', $messages, $locale, $domain);\n                }\n            }\n\n            return $translator;\n        };\n\n        if (isset($app['request_stack'])) {\n            $app['translator.listener'] = function ($app) {\n                return new TranslatorListener($app['translator'], $app['request_stack']);\n            };\n        }\n\n        $app['translator.message_selector'] = function () {\n            return new MessageSelector();\n        };\n\n        $app['translator.resources'] = $app->protect(function ($app) {\n            return array();\n        });\n\n        $app['translator.domains'] = array();\n        $app['locale_fallbacks'] = array('en');\n        $app['translator.cache_dir'] = null;\n    }\n\n    public function subscribe(Container $app, EventDispatcherInterface $dispatcher)\n    {\n        if (isset($app['translator.listener'])) {\n            $dispatcher->addSubscriber($app['translator.listener']);\n        }\n    }\n}\n"
  },
  {
    "path": "src/Silex/Provider/TwigServiceProvider.php",
    "content": "<?php\n\n/*\n * This file is part of the Silex framework.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Silex\\Provider;\n\nuse Pimple\\Container;\nuse Pimple\\ServiceProviderInterface;\nuse Symfony\\Bridge\\Twig\\AppVariable;\nuse Symfony\\Bridge\\Twig\\Extension\\AssetExtension;\nuse Symfony\\Bridge\\Twig\\Extension\\DumpExtension;\nuse Symfony\\Bridge\\Twig\\Extension\\RoutingExtension;\nuse Symfony\\Bridge\\Twig\\Extension\\TranslationExtension;\nuse Symfony\\Bridge\\Twig\\Extension\\FormExtension;\nuse Symfony\\Bridge\\Twig\\Extension\\SecurityExtension;\nuse Symfony\\Bridge\\Twig\\Extension\\HttpFoundationExtension;\nuse Symfony\\Bridge\\Twig\\Extension\\HttpKernelExtension;\nuse Symfony\\Bridge\\Twig\\Form\\TwigRendererEngine;\nuse Symfony\\Bridge\\Twig\\Form\\TwigRenderer;\n\n/**\n * Twig integration for Silex.\n *\n * @author Fabien Potencier <fabien@symfony.com>\n */\nclass TwigServiceProvider implements ServiceProviderInterface\n{\n    public function register(Container $app)\n    {\n        $app['twig.options'] = array();\n        $app['twig.form.templates'] = array('form_div_layout.html.twig');\n        $app['twig.path'] = array();\n        $app['twig.templates'] = array();\n\n        $app['twig.app_variable'] = function ($app) {\n            $var = new AppVariable();\n            if (isset($app['security.token_storage'])) {\n                $var->setTokenStorage($app['security.token_storage']);\n            }\n            if (isset($app['request_stack'])) {\n                $var->setRequestStack($app['request_stack']);\n            }\n            $var->setDebug($app['debug']);\n\n            return $var;\n        };\n\n        $app['twig'] = function ($app) {\n            $app['twig.options'] = array_replace(\n                array(\n                    'charset' => $app['charset'],\n                    'debug' => $app['debug'],\n                    'strict_variables' => $app['debug'],\n                ), $app['twig.options']\n            );\n\n            $twig = $app['twig.environment_factory']($app);\n            // registered for BC, but should not be used anymore\n            // deprecated and should probably be removed in Silex 3.0\n            $twig->addGlobal('app', $app);\n\n            if ($app['debug']) {\n                $twig->addExtension(new \\Twig_Extension_Debug());\n            }\n\n            if (class_exists('Symfony\\Bridge\\Twig\\Extension\\RoutingExtension')) {\n                $twig->addGlobal('global', $app['twig.app_variable']);\n\n                if (isset($app['request_stack'])) {\n                    $twig->addExtension(new HttpFoundationExtension($app['request_stack']));\n                    $twig->addExtension(new RoutingExtension($app['url_generator']));\n                }\n\n                if (isset($app['translator'])) {\n                    $twig->addExtension(new TranslationExtension($app['translator']));\n                }\n\n                if (isset($app['security.authorization_checker'])) {\n                    $twig->addExtension(new SecurityExtension($app['security.authorization_checker']));\n                }\n\n                if (isset($app['fragment.handler'])) {\n                    $app['fragment.renderer.hinclude']->setTemplating($twig);\n\n                    $twig->addExtension(new HttpKernelExtension($app['fragment.handler']));\n                }\n\n                if (isset($app['assets.packages'])) {\n                    $twig->addExtension(new AssetExtension($app['assets.packages']));\n                }\n\n                if (isset($app['form.factory'])) {\n                    $app['twig.form.engine'] = function ($app) {\n                        return new TwigRendererEngine($app['twig.form.templates']);\n                    };\n\n                    $app['twig.form.renderer'] = function ($app) {\n                        $csrfTokenManager = isset($app['csrf.token_manager']) ? $app['csrf.token_manager'] : null;\n\n                        return new TwigRenderer($app['twig.form.engine'], $csrfTokenManager);\n                    };\n\n                    $twig->addExtension(new FormExtension($app['twig.form.renderer']));\n\n                    // add loader for Symfony built-in form templates\n                    $reflected = new \\ReflectionClass('Symfony\\Bridge\\Twig\\Extension\\FormExtension');\n                    $path = dirname($reflected->getFileName()).'/../Resources/views/Form';\n                    $app['twig.loader']->addLoader(new \\Twig_Loader_Filesystem($path));\n                }\n\n                if (isset($app['var_dumper.cloner'])) {\n                    $twig->addExtension(new DumpExtension($app['var_dumper.cloner']));\n                }\n            }\n\n            return $twig;\n        };\n\n        $app['twig.loader.filesystem'] = function ($app) {\n            return new \\Twig_Loader_Filesystem($app['twig.path']);\n        };\n\n        $app['twig.loader.array'] = function ($app) {\n            return new \\Twig_Loader_Array($app['twig.templates']);\n        };\n\n        $app['twig.loader'] = function ($app) {\n            return new \\Twig_Loader_Chain(array(\n                $app['twig.loader.array'],\n                $app['twig.loader.filesystem'],\n            ));\n        };\n\n        $app['twig.environment_factory'] = $app->protect(function ($app) {\n            return new \\Twig_Environment($app['twig.loader'], $app['twig.options']);\n        });\n    }\n}\n"
  },
  {
    "path": "src/Silex/Provider/Validator/ConstraintValidatorFactory.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Silex\\Provider\\Validator;\n\nuse Pimple\\Container;\nuse Symfony\\Component\\Validator\\Constraint;\nuse Symfony\\Component\\Validator\\ConstraintValidatorFactory as BaseConstraintValidatorFactory;\n\n/**\n * Uses a service container to create constraint validators with dependencies.\n *\n * @author Kris Wallsmith <kris@symfony.com>\n * @author Alex Kalyvitis <alex.kalyvitis@gmail.com>\n */\nclass ConstraintValidatorFactory extends BaseConstraintValidatorFactory\n{\n    /**\n     * @var Container\n     */\n    protected $container;\n\n    /**\n     * @var array\n     */\n    protected $serviceNames;\n\n    /**\n     * Constructor.\n     *\n     * @param Container $container    DI container\n     * @param array     $serviceNames Validator service names\n     */\n    public function __construct(Container $container, array $serviceNames = array(), $propertyAccessor = null)\n    {\n        parent::__construct($propertyAccessor);\n\n        $this->container = $container;\n        $this->serviceNames = $serviceNames;\n    }\n\n    /**\n     * {@inheritdoc}\n     */\n    public function getInstance(Constraint $constraint)\n    {\n        $name = $constraint->validatedBy();\n\n        if (isset($this->serviceNames[$name])) {\n            return $this->container[$this->serviceNames[$name]];\n        }\n\n        return parent::getInstance($constraint);\n    }\n}\n"
  },
  {
    "path": "src/Silex/Provider/ValidatorServiceProvider.php",
    "content": "<?php\n\n/*\n * This file is part of the Silex framework.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Silex\\Provider;\n\nuse Pimple\\Container;\nuse Pimple\\ServiceProviderInterface;\nuse Silex\\Provider\\Validator\\ConstraintValidatorFactory;\nuse Symfony\\Component\\Validator\\Validator;\nuse Symfony\\Component\\Validator\\Mapping\\Factory\\LazyLoadingMetadataFactory;\nuse Symfony\\Component\\Validator\\Mapping\\Loader\\StaticMethodLoader;\nuse Symfony\\Component\\Validator\\Validation;\n\n/**\n * Symfony Validator component Provider.\n *\n * @author Fabien Potencier <fabien@symfony.com>\n */\nclass ValidatorServiceProvider implements ServiceProviderInterface\n{\n    public function register(Container $app)\n    {\n        $app['validator'] = function ($app) {\n            return $app['validator.builder']->getValidator();\n        };\n\n        $app['validator.builder'] = function ($app) {\n            $builder = Validation::createValidatorBuilder();\n            $builder->setConstraintValidatorFactory($app['validator.validator_factory']);\n            $builder->setTranslationDomain('validators');\n            $builder->addObjectInitializers($app['validator.object_initializers']);\n            $builder->setMetadataFactory($app['validator.mapping.class_metadata_factory']);\n            if (isset($app['translator'])) {\n                $builder->setTranslator($app['translator']);\n            }\n\n            return $builder;\n        };\n\n        $app['validator.mapping.class_metadata_factory'] = function ($app) {\n            return new LazyLoadingMetadataFactory(new StaticMethodLoader());\n        };\n\n        $app['validator.validator_factory'] = function () use ($app) {\n            return new ConstraintValidatorFactory($app, $app['validator.validator_service_ids']);\n        };\n\n        $app['validator.object_initializers'] = function ($app) {\n            return array();\n        };\n\n        $app['validator.validator_service_ids'] = array();\n    }\n}\n"
  },
  {
    "path": "src/Silex/Provider/VarDumperServiceProvider.php",
    "content": "<?php\n\n/*\n * This file is part of the Silex framework.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Silex\\Provider;\n\nuse Pimple\\Container;\nuse Pimple\\ServiceProviderInterface;\nuse Silex\\Application;\nuse Silex\\Api\\BootableProviderInterface;\nuse Symfony\\Component\\VarDumper\\VarDumper;\nuse Symfony\\Component\\VarDumper\\Cloner\\VarCloner;\nuse Symfony\\Component\\VarDumper\\Dumper\\CliDumper;\n\n/**\n * Symfony Var Dumper component Provider.\n *\n * @author Fabien Potencier <fabien@symfony.com>\n */\nclass VarDumperServiceProvider implements ServiceProviderInterface, BootableProviderInterface\n{\n    public function register(Container $app)\n    {\n        $app['var_dumper.cli_dumper'] = function ($app) {\n            return new CliDumper($app['var_dumper.dump_destination'], $app['charset']);\n        };\n\n        $app['var_dumper.cloner'] = function ($app) {\n            return new VarCloner();\n        };\n\n        $app['var_dumper.dump_destination'] = null;\n    }\n\n    public function boot(Application $app)\n    {\n        if (!$app['debug']) {\n            return;\n        }\n\n        // This code is here to lazy load the dump stack. This default\n        // configuration for CLI mode is overridden in HTTP mode on\n        // 'kernel.request' event\n        VarDumper::setHandler(function ($var) use ($app) {\n            VarDumper::setHandler($handler = function ($var) use ($app) {\n                $app['var_dumper.cli_dumper']->dump($app['var_dumper.cloner']->cloneVar($var));\n            });\n            $handler($var);\n        });\n    }\n}\n"
  },
  {
    "path": "src/Silex/Provider/composer.json",
    "content": "{\n    \"minimum-stability\": \"dev\",\n    \"name\": \"silex/providers\",\n    \"description\": \"The Silex providers\",\n    \"keywords\": [\"microframework\"],\n    \"homepage\": \"http://silex.sensiolabs.org\",\n    \"license\": \"MIT\",\n    \"authors\": [\n        {\n            \"name\": \"Fabien Potencier\",\n            \"email\": \"fabien@symfony.com\"\n        },\n        {\n            \"name\": \"Igor Wiedler\",\n            \"email\": \"igor@wiedler.ch\"\n        }\n    ],\n    \"require\": {\n        \"php\": \">=5.5.9\",\n        \"pimple/pimple\": \"~3.0\",\n        \"silex/api\": \"~2.0\"\n    },\n    \"autoload\": {\n        \"psr-4\": { \"Silex\\\\Provider\\\\\": \"\" }\n    },\n    \"extra\": {\n        \"branch-alias\": {\n            \"dev-master\": \"2.0.x-dev\"\n        }\n    }\n}\n"
  },
  {
    "path": "src/Silex/Route/SecurityTrait.php",
    "content": "<?php\n\n/*\n * This file is part of the Silex framework.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Silex\\Route;\n\nuse Symfony\\Component\\Security\\Core\\Exception\\AccessDeniedException;\n\n/**\n * Security trait.\n *\n * @author Fabien Potencier <fabien@symfony.com>\n */\ntrait SecurityTrait\n{\n    public function secure($roles)\n    {\n        $this->before(function ($request, $app) use ($roles) {\n            if (!$app['security.authorization_checker']->isGranted($roles)) {\n                throw new AccessDeniedException();\n            }\n        });\n    }\n}\n"
  },
  {
    "path": "src/Silex/Route.php",
    "content": "<?php\n\n/*\n * This file is part of the Silex framework.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Silex;\n\nuse Symfony\\Component\\Routing\\Route as BaseRoute;\n\n/**\n * A wrapper for a controller, mapped to a route.\n *\n * @author Fabien Potencier <fabien@symfony.com>\n */\nclass Route extends BaseRoute\n{\n    /**\n     * Constructor.\n     *\n     * Available options:\n     *\n     *  * compiler_class: A class name able to compile this route instance (RouteCompiler by default)\n     *\n     * @param string       $path         The path pattern to match\n     * @param array        $defaults     An array of default parameter values\n     * @param array        $requirements An array of requirements for parameters (regexes)\n     * @param array        $options      An array of options\n     * @param string       $host         The host pattern to match\n     * @param string|array $schemes      A required URI scheme or an array of restricted schemes\n     * @param string|array $methods      A required HTTP method or an array of restricted methods\n     */\n    public function __construct($path = '/', array $defaults = array(), array $requirements = array(), array $options = array(), $host = '', $schemes = array(), $methods = array())\n    {\n        // overridden constructor to make $path optional\n        parent::__construct($path, $defaults, $requirements, $options, $host, $schemes, $methods);\n    }\n\n    /**\n     * Sets the route code that should be executed when matched.\n     *\n     * @param callable $to PHP callback that returns the response when matched\n     *\n     * @return Route $this The current Route instance\n     */\n    public function run($to)\n    {\n        $this->setDefault('_controller', $to);\n\n        return $this;\n    }\n\n    /**\n     * Sets the requirement for a route variable.\n     *\n     * @param string $variable The variable name\n     * @param string $regexp   The regexp to apply\n     *\n     * @return Route $this The current route instance\n     */\n    public function assert($variable, $regexp)\n    {\n        $this->setRequirement($variable, $regexp);\n\n        return $this;\n    }\n\n    /**\n     * Sets the default value for a route variable.\n     *\n     * @param string $variable The variable name\n     * @param mixed  $default  The default value\n     *\n     * @return Route $this The current Route instance\n     */\n    public function value($variable, $default)\n    {\n        $this->setDefault($variable, $default);\n\n        return $this;\n    }\n\n    /**\n     * Sets a converter for a route variable.\n     *\n     * @param string $variable The variable name\n     * @param mixed  $callback A PHP callback that converts the original value\n     *\n     * @return Route $this The current Route instance\n     */\n    public function convert($variable, $callback)\n    {\n        $converters = $this->getOption('_converters');\n        $converters[$variable] = $callback;\n        $this->setOption('_converters', $converters);\n\n        return $this;\n    }\n\n    /**\n     * Sets the requirement for the HTTP method.\n     *\n     * @param string $method The HTTP method name. Multiple methods can be supplied, delimited by a pipe character '|', eg. 'GET|POST'\n     *\n     * @return Route $this The current Route instance\n     */\n    public function method($method)\n    {\n        $this->setMethods(explode('|', $method));\n\n        return $this;\n    }\n\n    /**\n     * Sets the requirement of host on this Route.\n     *\n     * @param string $host The host for which this route should be enabled\n     *\n     * @return Route $this The current Route instance\n     */\n    public function host($host)\n    {\n        $this->setHost($host);\n\n        return $this;\n    }\n\n    /**\n     * Sets the requirement of HTTP (no HTTPS) on this Route.\n     *\n     * @return Route $this The current Route instance\n     */\n    public function requireHttp()\n    {\n        $this->setSchemes('http');\n\n        return $this;\n    }\n\n    /**\n     * Sets the requirement of HTTPS on this Route.\n     *\n     * @return Route $this The current Route instance\n     */\n    public function requireHttps()\n    {\n        $this->setSchemes('https');\n\n        return $this;\n    }\n\n    /**\n     * Sets a callback to handle before triggering the route callback.\n     *\n     * @param mixed $callback A PHP callback to be triggered when the Route is matched, just before the route callback\n     *\n     * @return Route $this The current Route instance\n     */\n    public function before($callback)\n    {\n        $callbacks = $this->getOption('_before_middlewares');\n        $callbacks[] = $callback;\n        $this->setOption('_before_middlewares', $callbacks);\n\n        return $this;\n    }\n\n    /**\n     * Sets a callback to handle after the route callback.\n     *\n     * @param mixed $callback A PHP callback to be triggered after the route callback\n     *\n     * @return Route $this The current Route instance\n     */\n    public function after($callback)\n    {\n        $callbacks = $this->getOption('_after_middlewares');\n        $callbacks[] = $callback;\n        $this->setOption('_after_middlewares', $callbacks);\n\n        return $this;\n    }\n\n    /**\n     * Sets a condition for the route to match.\n     *\n     * @param string $condition The condition\n     *\n     * @return Route $this The current Route instance\n     */\n    public function when($condition)\n    {\n        $this->setCondition($condition);\n\n        return $this;\n    }\n}\n"
  },
  {
    "path": "src/Silex/ServiceControllerResolver.php",
    "content": "<?php\n\n/*\n * This file is part of the Silex framework.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Silex;\n\nuse Symfony\\Component\\HttpFoundation\\Request;\nuse Symfony\\Component\\HttpKernel\\Controller\\ControllerResolverInterface;\n\n/**\n * Enables name_of_service:method_name syntax for declaring controllers.\n *\n * @link http://silex.sensiolabs.org/doc/providers/service_controller.html\n */\nclass ServiceControllerResolver implements ControllerResolverInterface\n{\n    protected $controllerResolver;\n    protected $callbackResolver;\n\n    /**\n     * Constructor.\n     *\n     * @param ControllerResolverInterface $controllerResolver A ControllerResolverInterface instance to delegate to\n     * @param CallbackResolver            $callbackResolver   A service resolver instance\n     */\n    public function __construct(ControllerResolverInterface $controllerResolver, CallbackResolver $callbackResolver)\n    {\n        $this->controllerResolver = $controllerResolver;\n        $this->callbackResolver = $callbackResolver;\n    }\n\n    /**\n     * {@inheritdoc}\n     */\n    public function getController(Request $request)\n    {\n        $controller = $request->attributes->get('_controller', null);\n\n        if (!$this->callbackResolver->isValid($controller)) {\n            return $this->controllerResolver->getController($request);\n        }\n\n        return $this->callbackResolver->convertCallback($controller);\n    }\n\n    /**\n     * {@inheritdoc}\n     */\n    public function getArguments(Request $request, $controller)\n    {\n        return $this->controllerResolver->getArguments($request, $controller);\n    }\n}\n"
  },
  {
    "path": "src/Silex/ViewListenerWrapper.php",
    "content": "<?php\n\n/*\n * This file is part of the Silex framework.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Silex;\n\nuse Symfony\\Component\\HttpFoundation\\Response;\nuse Symfony\\Component\\HttpKernel\\Event\\GetResponseForControllerResultEvent;\n\n/**\n * Wraps view listeners.\n *\n * @author Dave Marshall <dave@atst.io>\n */\nclass ViewListenerWrapper\n{\n    private $app;\n    private $callback;\n\n    /**\n     * Constructor.\n     *\n     * @param Application $app      An Application instance\n     * @param mixed       $callback\n     */\n    public function __construct(Application $app, $callback)\n    {\n        $this->app = $app;\n        $this->callback = $callback;\n    }\n\n    public function __invoke(GetResponseForControllerResultEvent $event)\n    {\n        $controllerResult = $event->getControllerResult();\n        $callback = $this->app['callback_resolver']->resolveCallback($this->callback);\n\n        if (!$this->shouldRun($callback, $controllerResult)) {\n            return;\n        }\n\n        $response = call_user_func($callback, $controllerResult, $event->getRequest());\n\n        if ($response instanceof Response) {\n            $event->setResponse($response);\n        } elseif (null !== $response) {\n            $event->setControllerResult($response);\n        }\n    }\n\n    private function shouldRun($callback, $controllerResult)\n    {\n        if (is_array($callback)) {\n            $callbackReflection = new \\ReflectionMethod($callback[0], $callback[1]);\n        } elseif (is_object($callback) && !$callback instanceof \\Closure) {\n            $callbackReflection = new \\ReflectionObject($callback);\n            $callbackReflection = $callbackReflection->getMethod('__invoke');\n        } else {\n            $callbackReflection = new \\ReflectionFunction($callback);\n        }\n\n        if ($callbackReflection->getNumberOfParameters() > 0) {\n            $parameters = $callbackReflection->getParameters();\n            $expectedControllerResult = $parameters[0];\n\n            if ($expectedControllerResult->getClass() && (!is_object($controllerResult) || !$expectedControllerResult->getClass()->isInstance($controllerResult))) {\n                return false;\n            }\n\n            if ($expectedControllerResult->isArray() && !is_array($controllerResult)) {\n                return false;\n            }\n\n            if (method_exists($expectedControllerResult, 'isCallable') && $expectedControllerResult->isCallable() && !is_callable($controllerResult)) {\n                return false;\n            }\n        }\n\n        return true;\n    }\n}\n"
  },
  {
    "path": "src/Silex/WebTestCase.php",
    "content": "<?php\n\n/*\n * This file is part of the Silex framework.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Silex;\n\nuse Symfony\\Component\\HttpKernel\\Client;\nuse Symfony\\Component\\HttpKernel\\HttpKernelInterface;\n\n/**\n * WebTestCase is the base class for functional tests.\n *\n * @author Igor Wiedler <igor@wiedler.ch>\n */\nabstract class WebTestCase extends \\PHPUnit_Framework_TestCase\n{\n    /**\n     * HttpKernelInterface instance.\n     *\n     * @var HttpKernelInterface\n     */\n    protected $app;\n\n    /**\n     * PHPUnit setUp for setting up the application.\n     *\n     * Note: Child classes that define a setUp method must call\n     * parent::setUp().\n     */\n    protected function setUp()\n    {\n        $this->app = $this->createApplication();\n    }\n\n    /**\n     * Creates the application.\n     *\n     * @return HttpKernelInterface\n     */\n    abstract public function createApplication();\n\n    /**\n     * Creates a Client.\n     *\n     * @param array $server Server parameters\n     *\n     * @return Client A Client instance\n     */\n    public function createClient(array $server = array())\n    {\n        if (!class_exists('Symfony\\Component\\BrowserKit\\Client')) {\n            throw new \\LogicException('Component \"symfony/browser-kit\" is required by WebTestCase.'.PHP_EOL.'Run composer require symfony/browser-kit');\n        }\n\n        return new Client($this->app, $server);\n    }\n}\n"
  },
  {
    "path": "tests/Silex/Tests/Application/FormApplication.php",
    "content": "<?php\n\n/*\n * This file is part of the Silex framework.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * This source file is subject to the MIT license that is bundled\n * with this source code in the file LICENSE.\n */\n\nnamespace Silex\\Tests\\Application;\n\nuse Silex\\Application;\n\nclass FormApplication extends Application\n{\n    use Application\\FormTrait;\n}\n"
  },
  {
    "path": "tests/Silex/Tests/Application/FormTraitTest.php",
    "content": "<?php\n\n/*\n * This file is part of the Silex framework.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * This source file is subject to the MIT license that is bundled\n * with this source code in the file LICENSE.\n */\n\nnamespace Silex\\Tests\\Application;\n\nuse Silex\\Provider\\FormServiceProvider;\n\n/**\n * FormTrait test cases.\n *\n * @author Fabien Potencier <fabien@symfony.com>\n */\nclass FormTraitTest extends \\PHPUnit_Framework_TestCase\n{\n    public function testForm()\n    {\n        $this->assertInstanceOf('Symfony\\Component\\Form\\FormBuilder', $this->createApplication()->form());\n    }\n\n    public function createApplication()\n    {\n        $app = new FormApplication();\n        $app->register(new FormServiceProvider());\n\n        return $app;\n    }\n}\n"
  },
  {
    "path": "tests/Silex/Tests/Application/MonologApplication.php",
    "content": "<?php\n\n/*\n * This file is part of the Silex framework.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * This source file is subject to the MIT license that is bundled\n * with this source code in the file LICENSE.\n */\n\nnamespace Silex\\Tests\\Application;\n\nuse Silex\\Application;\n\nclass MonologApplication extends Application\n{\n    use Application\\MonologTrait;\n}\n"
  },
  {
    "path": "tests/Silex/Tests/Application/MonologTraitTest.php",
    "content": "<?php\n\n/*\n * This file is part of the Silex framework.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * This source file is subject to the MIT license that is bundled\n * with this source code in the file LICENSE.\n */\n\nnamespace Silex\\Tests\\Application;\n\nuse Silex\\Provider\\MonologServiceProvider;\nuse Monolog\\Handler\\TestHandler;\nuse Monolog\\Logger;\n\n/**\n * MonologTrait test cases.\n *\n * @author Fabien Potencier <fabien@symfony.com>\n */\nclass MonologTraitTest extends \\PHPUnit_Framework_TestCase\n{\n    public function testLog()\n    {\n        $app = $this->createApplication();\n\n        $app->log('Foo');\n        $app->log('Bar', array(), Logger::DEBUG);\n        $this->assertTrue($app['monolog.handler']->hasInfo('Foo'));\n        $this->assertTrue($app['monolog.handler']->hasDebug('Bar'));\n    }\n\n    public function createApplication()\n    {\n        $app = new MonologApplication();\n        $app->register(new MonologServiceProvider(), array(\n            'monolog.handler' => function () use ($app) {\n                return new TestHandler($app['monolog.level']);\n            },\n            'monolog.logfile' => 'php://memory',\n        ));\n\n        return $app;\n    }\n}\n"
  },
  {
    "path": "tests/Silex/Tests/Application/SecurityApplication.php",
    "content": "<?php\n\n/*\n * This file is part of the Silex framework.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * This source file is subject to the MIT license that is bundled\n * with this source code in the file LICENSE.\n */\n\nnamespace Silex\\Tests\\Application;\n\nuse Silex\\Application;\n\nclass SecurityApplication extends Application\n{\n    use Application\\SecurityTrait;\n}\n"
  },
  {
    "path": "tests/Silex/Tests/Application/SecurityTraitTest.php",
    "content": "<?php\n\n/*\n * This file is part of the Silex framework.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * This source file is subject to the MIT license that is bundled\n * with this source code in the file LICENSE.\n */\n\nnamespace Silex\\Tests\\Application;\n\nuse Silex\\Provider\\SecurityServiceProvider;\nuse Symfony\\Component\\Security\\Core\\User\\User;\nuse Symfony\\Component\\HttpFoundation\\Request;\n\n/**\n * SecurityTrait test cases.\n *\n * @author Fabien Potencier <fabien@symfony.com>\n */\nclass SecurityTraitTest extends \\PHPUnit_Framework_TestCase\n{\n    public function testEncodePassword()\n    {\n        $app = $this->createApplication(array(\n            'fabien' => array('ROLE_ADMIN', '$2y$15$lzUNsTegNXvZW3qtfucV0erYBcEqWVeyOmjolB7R1uodsAVJ95vvu'),\n        ));\n\n        $user = new User('foo', 'bar');\n        $password = 'foo';\n        $encoded = $app->encodePassword($user, $password);\n\n        $this->assertTrue(\n            $app['security.encoder_factory']->getEncoder($user)->isPasswordValid($encoded, $password, $user->getSalt())\n        );\n    }\n\n    /**\n     * @expectedException \\Symfony\\Component\\Security\\Core\\Exception\\AuthenticationCredentialsNotFoundException\n     */\n    public function testIsGrantedWithoutTokenThrowsException()\n    {\n        $app = $this->createApplication();\n        $app->get('/', function () { return 'foo'; });\n        $app->handle(Request::create('/'));\n        $app->isGranted('ROLE_ADMIN');\n    }\n\n    public function testIsGranted()\n    {\n        $request = Request::create('/');\n\n        $app = $this->createApplication(array(\n            'fabien' => array('ROLE_ADMIN', '$2y$15$lzUNsTegNXvZW3qtfucV0erYBcEqWVeyOmjolB7R1uodsAVJ95vvu'),\n            'monique' => array('ROLE_USER',  '$2y$15$lzUNsTegNXvZW3qtfucV0erYBcEqWVeyOmjolB7R1uodsAVJ95vvu'),\n        ));\n        $app->get('/', function () { return 'foo'; });\n\n        // User is Monique (ROLE_USER)\n        $request->headers->set('PHP_AUTH_USER', 'monique');\n        $request->headers->set('PHP_AUTH_PW', 'foo');\n        $app->handle($request);\n        $this->assertTrue($app->isGranted('ROLE_USER'));\n        $this->assertFalse($app->isGranted('ROLE_ADMIN'));\n\n        // User is Fabien (ROLE_ADMIN)\n        $request->headers->set('PHP_AUTH_USER', 'fabien');\n        $request->headers->set('PHP_AUTH_PW', 'foo');\n        $app->handle($request);\n        $this->assertFalse($app->isGranted('ROLE_USER'));\n        $this->assertTrue($app->isGranted('ROLE_ADMIN'));\n    }\n\n    public function createApplication($users = array())\n    {\n        $app = new SecurityApplication();\n        $app->register(new SecurityServiceProvider(), array(\n            'security.firewalls' => array(\n                'default' => array(\n                    'http' => true,\n                    'users' => $users,\n                ),\n            ),\n        ));\n\n        return $app;\n    }\n}\n"
  },
  {
    "path": "tests/Silex/Tests/Application/SwiftmailerApplication.php",
    "content": "<?php\n\n/*\n * This file is part of the Silex framework.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * This source file is subject to the MIT license that is bundled\n * with this source code in the file LICENSE.\n */\n\nnamespace Silex\\Tests\\Application;\n\nuse Silex\\Application;\n\nclass SwiftmailerApplication extends Application\n{\n    use Application\\SwiftmailerTrait;\n}\n"
  },
  {
    "path": "tests/Silex/Tests/Application/SwiftmailerTraitTest.php",
    "content": "<?php\n\n/*\n * This file is part of the Silex framework.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * This source file is subject to the MIT license that is bundled\n * with this source code in the file LICENSE.\n */\n\nnamespace Silex\\Tests\\Application;\n\nuse Silex\\Provider\\SwiftmailerServiceProvider;\n\n/**\n * SwiftmailerTrait test cases.\n *\n * @author Fabien Potencier <fabien@symfony.com>\n */\nclass SwiftmailerTraitTest extends \\PHPUnit_Framework_TestCase\n{\n    public function testMail()\n    {\n        $app = $this->createApplication();\n\n        $message = $this->getMockBuilder('Swift_Message')->disableOriginalConstructor()->getMock();\n        $app['mailer'] = $mailer = $this->getMockBuilder('Swift_Mailer')->disableOriginalConstructor()->getMock();\n        $mailer->expects($this->once())\n               ->method('send')\n               ->with($message)\n        ;\n\n        $app->mail($message);\n    }\n\n    public function createApplication()\n    {\n        $app = new SwiftmailerApplication();\n        $app->register(new SwiftmailerServiceProvider());\n\n        return $app;\n    }\n}\n"
  },
  {
    "path": "tests/Silex/Tests/Application/TranslationApplication.php",
    "content": "<?php\n\n/*\n * This file is part of the Silex framework.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * This source file is subject to the MIT license that is bundled\n * with this source code in the file LICENSE.\n */\n\nnamespace Silex\\Tests\\Application;\n\nuse Silex\\Application;\n\nclass TranslationApplication extends Application\n{\n    use Application\\TranslationTrait;\n}\n"
  },
  {
    "path": "tests/Silex/Tests/Application/TranslationTraitTest.php",
    "content": "<?php\n\n/*\n * This file is part of the Silex framework.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * This source file is subject to the MIT license that is bundled\n * with this source code in the file LICENSE.\n */\n\nnamespace Silex\\Tests\\Application;\n\nuse Silex\\Provider\\TranslationServiceProvider;\n\n/**\n * TranslationTrait test cases.\n *\n * @author Fabien Potencier <fabien@symfony.com>\n */\nclass TranslationTraitTest extends \\PHPUnit_Framework_TestCase\n{\n    public function testTrans()\n    {\n        $app = $this->createApplication();\n        $app['translator'] = $translator = $this->getMockBuilder('Symfony\\Component\\Translation\\Translator')->disableOriginalConstructor()->getMock();\n        $translator->expects($this->once())->method('trans');\n        $app->trans('foo');\n    }\n\n    public function testTransChoice()\n    {\n        $app = $this->createApplication();\n        $app['translator'] = $translator = $this->getMockBuilder('Symfony\\Component\\Translation\\Translator')->disableOriginalConstructor()->getMock();\n        $translator->expects($this->once())->method('transChoice');\n        $app->transChoice('foo', 2);\n    }\n\n    public function createApplication()\n    {\n        $app = new TranslationApplication();\n        $app->register(new TranslationServiceProvider());\n\n        return $app;\n    }\n}\n"
  },
  {
    "path": "tests/Silex/Tests/Application/TwigApplication.php",
    "content": "<?php\n\n/*\n * This file is part of the Silex framework.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * This source file is subject to the MIT license that is bundled\n * with this source code in the file LICENSE.\n */\n\nnamespace Silex\\Tests\\Application;\n\nuse Silex\\Application;\n\nclass TwigApplication extends Application\n{\n    use Application\\TwigTrait;\n}\n"
  },
  {
    "path": "tests/Silex/Tests/Application/TwigTraitTest.php",
    "content": "<?php\n\n/*\n * This file is part of the Silex framework.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * This source file is subject to the MIT license that is bundled\n * with this source code in the file LICENSE.\n */\n\nnamespace Silex\\Tests\\Application;\n\nuse Silex\\Provider\\TwigServiceProvider;\nuse Symfony\\Component\\HttpFoundation\\Response;\nuse Symfony\\Component\\HttpFoundation\\StreamedResponse;\n\n/**\n * TwigTrait test cases.\n *\n * @author Fabien Potencier <fabien@symfony.com>\n */\nclass TwigTraitTest extends \\PHPUnit_Framework_TestCase\n{\n    public function testRender()\n    {\n        $app = $this->createApplication();\n\n        $app['twig'] = $mailer = $this->getMockBuilder('Twig_Environment')->disableOriginalConstructor()->getMock();\n        $mailer->expects($this->once())->method('render')->will($this->returnValue('foo'));\n\n        $response = $app->render('view');\n        $this->assertEquals('Symfony\\Component\\HttpFoundation\\Response', get_class($response));\n        $this->assertEquals('foo', $response->getContent());\n    }\n\n    public function testRenderKeepResponse()\n    {\n        $app = $this->createApplication();\n\n        $app['twig'] = $mailer = $this->getMockBuilder('Twig_Environment')->disableOriginalConstructor()->getMock();\n        $mailer->expects($this->once())->method('render')->will($this->returnValue('foo'));\n\n        $response = $app->render('view', array(), new Response('', 404));\n        $this->assertEquals(404, $response->getStatusCode());\n    }\n\n    public function testRenderForStream()\n    {\n        $app = $this->createApplication();\n\n        $app['twig'] = $mailer = $this->getMockBuilder('Twig_Environment')->disableOriginalConstructor()->getMock();\n        $mailer->expects($this->once())->method('display')->will($this->returnCallback(function () { echo 'foo'; }));\n\n        $response = $app->render('view', array(), new StreamedResponse());\n        $this->assertEquals('Symfony\\Component\\HttpFoundation\\StreamedResponse', get_class($response));\n\n        ob_start();\n        $response->send();\n        $this->assertEquals('foo', ob_get_clean());\n    }\n\n    public function testRenderView()\n    {\n        $app = $this->createApplication();\n\n        $app['twig'] = $mailer = $this->getMockBuilder('Twig_Environment')->disableOriginalConstructor()->getMock();\n        $mailer->expects($this->once())->method('render');\n\n        $app->renderView('view');\n    }\n\n    public function createApplication()\n    {\n        $app = new TwigApplication();\n        $app->register(new TwigServiceProvider());\n\n        return $app;\n    }\n}\n"
  },
  {
    "path": "tests/Silex/Tests/Application/UrlGeneratorApplication.php",
    "content": "<?php\n\n/*\n * This file is part of the Silex framework.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * This source file is subject to the MIT license that is bundled\n * with this source code in the file LICENSE.\n */\n\nnamespace Silex\\Tests\\Application;\n\nuse Silex\\Application;\n\nclass UrlGeneratorApplication extends Application\n{\n    use Application\\UrlGeneratorTrait;\n}\n"
  },
  {
    "path": "tests/Silex/Tests/Application/UrlGeneratorTraitTest.php",
    "content": "<?php\n\n/*\n * This file is part of the Silex framework.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * This source file is subject to the MIT license that is bundled\n * with this source code in the file LICENSE.\n */\n\nnamespace Silex\\Tests\\Application;\n\nuse Symfony\\Component\\Routing\\Generator\\UrlGeneratorInterface;\n\n/**\n * UrlGeneratorTrait test cases.\n *\n * @author Fabien Potencier <fabien@symfony.com>\n */\nclass UrlGeneratorTraitTest extends \\PHPUnit_Framework_TestCase\n{\n    public function testUrl()\n    {\n        $app = new UrlGeneratorApplication();\n        $app['url_generator'] = $this->getMockBuilder('Symfony\\Component\\Routing\\Generator\\UrlGeneratorInterface')->disableOriginalConstructor()->getMock();\n        $app['url_generator']->expects($this->once())->method('generate')->with('foo', array(), UrlGeneratorInterface::ABSOLUTE_URL);\n        $app->url('foo');\n    }\n\n    public function testPath()\n    {\n        $app = new UrlGeneratorApplication();\n        $app['url_generator'] = $this->getMockBuilder('Symfony\\Component\\Routing\\Generator\\UrlGeneratorInterface')->disableOriginalConstructor()->getMock();\n        $app['url_generator']->expects($this->once())->method('generate')->with('foo', array(), UrlGeneratorInterface::ABSOLUTE_PATH);\n        $app->path('foo');\n    }\n}\n"
  },
  {
    "path": "tests/Silex/Tests/ApplicationTest.php",
    "content": "<?php\n\n/*\n * This file is part of the Silex framework.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * This source file is subject to the MIT license that is bundled\n * with this source code in the file LICENSE.\n */\n\nnamespace Silex\\Tests;\n\nuse Silex\\Application;\nuse Silex\\ControllerCollection;\nuse Silex\\Api\\ControllerProviderInterface;\nuse Silex\\Route;\nuse Symfony\\Component\\HttpFoundation\\Request;\nuse Symfony\\Component\\HttpKernel\\Exception\\HttpException;\nuse Symfony\\Component\\HttpFoundation\\Response;\nuse Symfony\\Component\\HttpFoundation\\StreamedResponse;\nuse Symfony\\Component\\HttpKernel\\HttpKernelInterface;\nuse Symfony\\Component\\EventDispatcher\\Event;\nuse Symfony\\Component\\Routing\\RouteCollection;\n\n/**\n * Application test cases.\n *\n * @author Igor Wiedler <igor@wiedler.ch>\n */\nclass ApplicationTest extends \\PHPUnit_Framework_TestCase\n{\n    public function testMatchReturnValue()\n    {\n        $app = new Application();\n\n        $returnValue = $app->match('/foo', function () {});\n        $this->assertInstanceOf('Silex\\Controller', $returnValue);\n\n        $returnValue = $app->get('/foo', function () {});\n        $this->assertInstanceOf('Silex\\Controller', $returnValue);\n\n        $returnValue = $app->post('/foo', function () {});\n        $this->assertInstanceOf('Silex\\Controller', $returnValue);\n\n        $returnValue = $app->put('/foo', function () {});\n        $this->assertInstanceOf('Silex\\Controller', $returnValue);\n\n        $returnValue = $app->patch('/foo', function () {});\n        $this->assertInstanceOf('Silex\\Controller', $returnValue);\n\n        $returnValue = $app->delete('/foo', function () {});\n        $this->assertInstanceOf('Silex\\Controller', $returnValue);\n    }\n\n    public function testConstructorInjection()\n    {\n        // inject a custom parameter\n        $params = array('param' => 'value');\n        $app = new Application($params);\n        $this->assertSame($params['param'], $app['param']);\n\n        // inject an existing parameter\n        $params = array('locale' => 'value');\n        $app = new Application($params);\n        $this->assertSame($params['locale'], $app['locale']);\n    }\n\n    public function testGetRequest()\n    {\n        $request = Request::create('/');\n\n        $app = new Application();\n        $app->get('/', function (Request $req) use ($request) {\n            return $request === $req ? 'ok' : 'ko';\n        });\n\n        $this->assertEquals('ok', $app->handle($request)->getContent());\n    }\n\n    public function testGetRoutesWithNoRoutes()\n    {\n        $app = new Application();\n\n        $routes = $app['routes'];\n        $this->assertInstanceOf('Symfony\\Component\\Routing\\RouteCollection', $routes);\n        $this->assertEquals(0, count($routes->all()));\n    }\n\n    public function testGetRoutesWithRoutes()\n    {\n        $app = new Application();\n\n        $app->get('/foo', function () {\n            return 'foo';\n        });\n\n        $app->get('/bar')->run(function () {\n            return 'bar';\n        });\n\n        $routes = $app['routes'];\n        $this->assertInstanceOf('Symfony\\Component\\Routing\\RouteCollection', $routes);\n        $this->assertEquals(0, count($routes->all()));\n        $app->flush();\n        $this->assertEquals(2, count($routes->all()));\n    }\n\n    public function testOnCoreController()\n    {\n        $app = new Application();\n\n        $app->get('/foo/{foo}', function (\\ArrayObject $foo) {\n            return $foo['foo'];\n        })->convert('foo', function ($foo) { return new \\ArrayObject(array('foo' => $foo)); });\n\n        $response = $app->handle(Request::create('/foo/bar'));\n        $this->assertEquals('bar', $response->getContent());\n\n        $app->get('/foo/{foo}/{bar}', function (\\ArrayObject $foo) {\n            return $foo['foo'];\n        })->convert('foo', function ($foo, Request $request) { return new \\ArrayObject(array('foo' => $foo.$request->attributes->get('bar'))); });\n\n        $response = $app->handle(Request::create('/foo/foo/bar'));\n        $this->assertEquals('foobar', $response->getContent());\n    }\n\n    public function testOn()\n    {\n        $app = new Application();\n        $app['pass'] = false;\n\n        $app->on('test', function (Event $e) use ($app) {\n            $app['pass'] = true;\n        });\n\n        $app['dispatcher']->dispatch('test');\n\n        $this->assertTrue($app['pass']);\n    }\n\n    public function testAbort()\n    {\n        $app = new Application();\n\n        try {\n            $app->abort(404);\n            $this->fail();\n        } catch (HttpException $e) {\n            $this->assertEquals(404, $e->getStatusCode());\n        }\n    }\n\n    /**\n     * @dataProvider escapeProvider\n     */\n    public function testEscape($expected, $text)\n    {\n        $app = new Application();\n\n        $this->assertEquals($expected, $app->escape($text));\n    }\n\n    public function escapeProvider()\n    {\n        return array(\n            array('&lt;', '<'),\n            array('&gt;', '>'),\n            array('&quot;', '\"'),\n            array(\"'\", \"'\"),\n            array('abc', 'abc'),\n        );\n    }\n\n    public function testControllersAsMethods()\n    {\n        $app = new Application();\n        unset($app['exception_handler']);\n\n        $app->get('/{name}', 'Silex\\Tests\\FooController::barAction');\n\n        $this->assertEquals('Hello Fabien', $app->handle(Request::create('/Fabien'))->getContent());\n    }\n\n    public function testApplicationTypeHintWorks()\n    {\n        $app = new SpecialApplication();\n        unset($app['exception_handler']);\n\n        $app->get('/{name}', 'Silex\\Tests\\FooController::barSpecialAction');\n\n        $this->assertEquals('Hello Fabien in Silex\\Tests\\SpecialApplication', $app->handle(Request::create('/Fabien'))->getContent());\n    }\n\n    /**\n     * @requires PHP 7.0\n     */\n    public function testPhp7TypeHintWorks()\n    {\n        $app = new SpecialApplication();\n        unset($app['exception_handler']);\n\n        $app->get('/{name}', 'Silex\\Tests\\Fixtures\\Php7Controller::typehintedAction');\n\n        $this->assertEquals('Hello Fabien in Silex\\Tests\\SpecialApplication', $app->handle(Request::create('/Fabien'))->getContent());\n    }\n\n    public function testHttpSpec()\n    {\n        $app = new Application();\n        $app['charset'] = 'ISO-8859-1';\n\n        $app->get('/', function () {\n            return 'hello';\n        });\n\n        // content is empty for HEAD requests\n        $response = $app->handle(Request::create('/', 'HEAD'));\n        $this->assertEquals('', $response->getContent());\n\n        // charset is appended to Content-Type\n        $response = $app->handle(Request::create('/'));\n\n        $this->assertEquals('text/html; charset=ISO-8859-1', $response->headers->get('Content-Type'));\n    }\n\n    public function testRoutesMiddlewares()\n    {\n        $app = new Application();\n\n        $test = $this;\n\n        $middlewareTarget = array();\n        $beforeMiddleware1 = function (Request $request) use (&$middlewareTarget, $test) {\n            $test->assertEquals('/reached', $request->getRequestUri());\n            $middlewareTarget[] = 'before_middleware1_triggered';\n        };\n        $beforeMiddleware2 = function (Request $request) use (&$middlewareTarget, $test) {\n            $test->assertEquals('/reached', $request->getRequestUri());\n            $middlewareTarget[] = 'before_middleware2_triggered';\n        };\n        $beforeMiddleware3 = function (Request $request) use (&$middlewareTarget, $test) {\n            throw new \\Exception('This middleware shouldn\\'t run!');\n        };\n\n        $afterMiddleware1 = function (Request $request, Response $response) use (&$middlewareTarget, $test) {\n            $test->assertEquals('/reached', $request->getRequestUri());\n            $middlewareTarget[] = 'after_middleware1_triggered';\n        };\n        $afterMiddleware2 = function (Request $request, Response $response) use (&$middlewareTarget, $test) {\n            $test->assertEquals('/reached', $request->getRequestUri());\n            $middlewareTarget[] = 'after_middleware2_triggered';\n        };\n        $afterMiddleware3 = function (Request $request, Response $response) use (&$middlewareTarget, $test) {\n            throw new \\Exception('This middleware shouldn\\'t run!');\n        };\n\n        $app->get('/reached', function () use (&$middlewareTarget) {\n            $middlewareTarget[] = 'route_triggered';\n\n            return 'hello';\n        })\n        ->before($beforeMiddleware1)\n        ->before($beforeMiddleware2)\n        ->after($afterMiddleware1)\n        ->after($afterMiddleware2);\n\n        $app->get('/never-reached', function () use (&$middlewareTarget) {\n            throw new \\Exception('This route shouldn\\'t run!');\n        })\n        ->before($beforeMiddleware3)\n        ->after($afterMiddleware3);\n\n        $result = $app->handle(Request::create('/reached'));\n\n        $this->assertSame(array('before_middleware1_triggered', 'before_middleware2_triggered', 'route_triggered', 'after_middleware1_triggered', 'after_middleware2_triggered'), $middlewareTarget);\n        $this->assertEquals('hello', $result->getContent());\n    }\n\n    public function testRoutesBeforeMiddlewaresWithResponseObject()\n    {\n        $app = new Application();\n\n        $app->get('/foo', function () {\n            throw new \\Exception('This route shouldn\\'t run!');\n        })\n        ->before(function () {\n            return new Response('foo');\n        });\n\n        $request = Request::create('/foo');\n        $result = $app->handle($request);\n\n        $this->assertEquals('foo', $result->getContent());\n    }\n\n    public function testRoutesAfterMiddlewaresWithResponseObject()\n    {\n        $app = new Application();\n\n        $app->get('/foo', function () {\n            return new Response('foo');\n        })\n        ->after(function () {\n            return new Response('bar');\n        });\n\n        $request = Request::create('/foo');\n        $result = $app->handle($request);\n\n        $this->assertEquals('bar', $result->getContent());\n    }\n\n    public function testRoutesBeforeMiddlewaresWithRedirectResponseObject()\n    {\n        $app = new Application();\n\n        $app->get('/foo', function () {\n            throw new \\Exception('This route shouldn\\'t run!');\n        })\n        ->before(function () use ($app) {\n            return $app->redirect('/bar');\n        });\n\n        $request = Request::create('/foo');\n        $result = $app->handle($request);\n\n        $this->assertInstanceOf('Symfony\\Component\\HttpFoundation\\RedirectResponse', $result);\n        $this->assertEquals('/bar', $result->getTargetUrl());\n    }\n\n    public function testRoutesBeforeMiddlewaresTriggeredAfterSilexBeforeFilters()\n    {\n        $app = new Application();\n\n        $middlewareTarget = array();\n        $middleware = function (Request $request) use (&$middlewareTarget) {\n            $middlewareTarget[] = 'middleware_triggered';\n        };\n\n        $app->get('/foo', function () use (&$middlewareTarget) {\n            $middlewareTarget[] = 'route_triggered';\n        })\n        ->before($middleware);\n\n        $app->before(function () use (&$middlewareTarget) {\n            $middlewareTarget[] = 'before_triggered';\n        });\n\n        $app->handle(Request::create('/foo'));\n\n        $this->assertSame(array('before_triggered', 'middleware_triggered', 'route_triggered'), $middlewareTarget);\n    }\n\n    public function testRoutesAfterMiddlewaresTriggeredBeforeSilexAfterFilters()\n    {\n        $app = new Application();\n\n        $middlewareTarget = array();\n        $middleware = function (Request $request) use (&$middlewareTarget) {\n            $middlewareTarget[] = 'middleware_triggered';\n        };\n\n        $app->get('/foo', function () use (&$middlewareTarget) {\n            $middlewareTarget[] = 'route_triggered';\n        })\n        ->after($middleware);\n\n        $app->after(function () use (&$middlewareTarget) {\n            $middlewareTarget[] = 'after_triggered';\n        });\n\n        $app->handle(Request::create('/foo'));\n\n        $this->assertSame(array('route_triggered', 'middleware_triggered', 'after_triggered'), $middlewareTarget);\n    }\n\n    public function testFinishFilter()\n    {\n        $containerTarget = array();\n\n        $app = new Application();\n\n        $app->finish(function () use (&$containerTarget) {\n            $containerTarget[] = '4_filterFinish';\n        });\n\n        $app->get('/foo', function () use (&$containerTarget) {\n            $containerTarget[] = '1_routeTriggered';\n\n            return new StreamedResponse(function () use (&$containerTarget) {\n                $containerTarget[] = '3_responseSent';\n            });\n        });\n\n        $app->after(function () use (&$containerTarget) {\n            $containerTarget[] = '2_filterAfter';\n        });\n\n        $app->run(Request::create('/foo'));\n\n        $this->assertSame(array('1_routeTriggered', '2_filterAfter', '3_responseSent', '4_filterFinish'), $containerTarget);\n    }\n\n    /**\n     * @expectedException \\RuntimeException\n     */\n    public function testNonResponseAndNonNullReturnFromRouteBeforeMiddlewareShouldThrowRuntimeException()\n    {\n        $app = new Application();\n\n        $middleware = function (Request $request) {\n            return 'string return';\n        };\n\n        $app->get('/', function () {\n            return 'hello';\n        })\n        ->before($middleware);\n\n        $app->handle(Request::create('/'), HttpKernelInterface::MASTER_REQUEST, false);\n    }\n\n    /**\n     * @expectedException \\RuntimeException\n     */\n    public function testNonResponseAndNonNullReturnFromRouteAfterMiddlewareShouldThrowRuntimeException()\n    {\n        $app = new Application();\n\n        $middleware = function (Request $request) {\n            return 'string return';\n        };\n\n        $app->get('/', function () {\n            return 'hello';\n        })\n        ->after($middleware);\n\n        $app->handle(Request::create('/'), HttpKernelInterface::MASTER_REQUEST, false);\n    }\n\n    public function testSubRequest()\n    {\n        $app = new Application();\n        $app->get('/sub', function (Request $request) {\n            return new Response('foo');\n        });\n        $app->get('/', function (Request $request) use ($app) {\n            return $app->handle(Request::create('/sub'), HttpKernelInterface::SUB_REQUEST);\n        });\n\n        $this->assertEquals('foo', $app->handle(Request::create('/'))->getContent());\n    }\n\n    public function testRegisterShouldReturnSelf()\n    {\n        $app = new Application();\n        $provider = $this->getMockBuilder('Pimple\\ServiceProviderInterface')->getMock();\n\n        $this->assertSame($app, $app->register($provider));\n    }\n\n    public function testMountShouldReturnSelf()\n    {\n        $app = new Application();\n        $mounted = new ControllerCollection(new Route());\n        $mounted->get('/{name}', function ($name) { return new Response($name); });\n\n        $this->assertSame($app, $app->mount('/hello', $mounted));\n    }\n\n    public function testMountPreservesOrder()\n    {\n        $app = new Application();\n        $mounted = new ControllerCollection(new Route());\n        $mounted->get('/mounted')->bind('second');\n\n        $app->get('/before')->bind('first');\n        $app->mount('/', $mounted);\n        $app->get('/after')->bind('third');\n        $app->flush();\n\n        $this->assertEquals(array('first', 'second', 'third'), array_keys(iterator_to_array($app['routes'])));\n    }\n\n    /**\n     * @expectedException        \\LogicException\n     * @expectedExceptionMessage The \"mount\" method takes either a \"ControllerCollection\" instance, \"ControllerProviderInterface\" instance, or a callable.\n     */\n    public function testMountNullException()\n    {\n        $app = new Application();\n        $app->mount('/exception', null);\n    }\n\n    /**\n     * @expectedException        \\LogicException\n     * @expectedExceptionMessage The method \"Silex\\Tests\\IncorrectControllerCollection::connect\" must return a \"ControllerCollection\" instance. Got: \"NULL\"\n     */\n    public function testMountWrongConnectReturnValueException()\n    {\n        $app = new Application();\n        $app->mount('/exception', new IncorrectControllerCollection());\n    }\n\n    public function testMountCallable()\n    {\n        $app = new Application();\n        $app->mount('/prefix', function (ControllerCollection $coll) {\n            $coll->get('/path');\n        });\n\n        $app->flush();\n\n        $this->assertEquals(1, $app['routes']->count());\n    }\n\n    public function testSendFile()\n    {\n        $app = new Application();\n\n        $response = $app->sendFile(__FILE__, 200, array('Content-Type: application/php'));\n        $this->assertInstanceOf('Symfony\\Component\\HttpFoundation\\BinaryFileResponse', $response);\n        $this->assertEquals(__FILE__, (string) $response->getFile());\n    }\n\n    /**\n     * @expectedException        \\LogicException\n     * @expectedExceptionMessage The \"homepage\" route must have code to run when it matches.\n     */\n    public function testGetRouteCollectionWithRouteWithoutController()\n    {\n        $app = new Application();\n        unset($app['exception_handler']);\n        $app->match('/')->bind('homepage');\n        $app->handle(Request::create('/'));\n    }\n\n    public function testBeforeFilterOnMountedControllerGroupIsolatedToGroup()\n    {\n        $app = new Application();\n        $app->match('/', function () { return new Response('ok'); });\n        $mounted = $app['controllers_factory'];\n        $mounted->before(function () { return new Response('not ok'); });\n        $app->mount('/group', $mounted);\n\n        $response = $app->handle(Request::create('/'));\n        $this->assertEquals('ok', $response->getContent());\n    }\n\n    public function testViewListenerWithPrimitive()\n    {\n        $app = new Application();\n        $app->get('/foo', function () { return 123; });\n        $app->view(function ($view, Request $request) {\n            return new Response($view);\n        });\n\n        $response = $app->handle(Request::create('/foo'));\n\n        $this->assertEquals('123', $response->getContent());\n    }\n\n    public function testViewListenerWithArrayTypeHint()\n    {\n        $app = new Application();\n        $app->get('/foo', function () { return array('ok'); });\n        $app->view(function (array $view) {\n            return new Response($view[0]);\n        });\n\n        $response = $app->handle(Request::create('/foo'));\n\n        $this->assertEquals('ok', $response->getContent());\n    }\n\n    public function testViewListenerWithObjectTypeHint()\n    {\n        $app = new Application();\n        $app->get('/foo', function () { return (object) array('name' => 'world'); });\n        $app->view(function (\\stdClass $view) {\n            return new Response('Hello '.$view->name);\n        });\n\n        $response = $app->handle(Request::create('/foo'));\n\n        $this->assertEquals('Hello world', $response->getContent());\n    }\n\n    public function testViewListenerWithCallableTypeHint()\n    {\n        $app = new Application();\n        $app->get('/foo', function () { return function () { return 'world'; }; });\n        $app->view(function (callable $view) {\n            return new Response('Hello '.$view());\n        });\n\n        $response = $app->handle(Request::create('/foo'));\n\n        $this->assertEquals('Hello world', $response->getContent());\n    }\n\n    public function testViewListenersCanBeChained()\n    {\n        $app = new Application();\n        $app->get('/foo', function () { return (object) array('name' => 'world'); });\n\n        $app->view(function (\\stdClass $view) {\n            return array('msg' => 'Hello '.$view->name);\n        });\n\n        $app->view(function (array $view) {\n            return $view['msg'];\n        });\n\n        $response = $app->handle(Request::create('/foo'));\n\n        $this->assertEquals('Hello world', $response->getContent());\n    }\n\n    public function testViewListenersAreIgnoredIfNotSuitable()\n    {\n        $app = new Application();\n        $app->get('/foo', function () { return 'Hello world'; });\n\n        $app->view(function (\\stdClass $view) {\n            throw new \\Exception('View listener was called');\n        });\n\n        $app->view(function (array $view) {\n            throw new \\Exception('View listener was called');\n        });\n\n        $response = $app->handle(Request::create('/foo'));\n\n        $this->assertEquals('Hello world', $response->getContent());\n    }\n\n    public function testViewListenersResponsesAreNotUsedIfNull()\n    {\n        $app = new Application();\n        $app->get('/foo', function () { return 'Hello world'; });\n\n        $app->view(function ($view) {\n            return 'Hello view listener';\n        });\n\n        $app->view(function ($view) {\n            return;\n        });\n\n        $response = $app->handle(Request::create('/foo'));\n\n        $this->assertEquals('Hello view listener', $response->getContent());\n    }\n\n    public function testDefaultRoutesFactory()\n    {\n        $app = new Application();\n        $this->assertInstanceOf('Symfony\\Component\\Routing\\RouteCollection', $app['routes']);\n    }\n\n    public function testOverriddenRoutesFactory()\n    {\n        $app = new Application();\n        $app['routes_factory'] = $app->factory(function () {\n            return new RouteCollectionSubClass();\n        });\n        $this->assertInstanceOf('Silex\\Tests\\RouteCollectionSubClass', $app['routes']);\n    }\n}\n\nclass FooController\n{\n    public function barAction(Application $app, $name)\n    {\n        return 'Hello '.$app->escape($name);\n    }\n\n    public function barSpecialAction(SpecialApplication $app, $name)\n    {\n        return 'Hello '.$app->escape($name).' in '.get_class($app);\n    }\n}\n\nclass IncorrectControllerCollection implements ControllerProviderInterface\n{\n    public function connect(Application $app)\n    {\n        return;\n    }\n}\n\nclass RouteCollectionSubClass extends RouteCollection\n{\n}\n\nclass SpecialApplication extends Application\n{\n}\n"
  },
  {
    "path": "tests/Silex/Tests/CallbackResolverTest.php",
    "content": "<?php\n\n/*\n * This file is part of the Silex framework.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Silex\\Tests;\n\nuse Pimple\\Container;\nuse Silex\\CallbackResolver;\n\nclass CallbackResolverTest extends \\PHPUnit_Framework_Testcase\n{\n    private $app;\n    private $resolver;\n\n    public function setup()\n    {\n        $this->app = new Container();\n        $this->resolver = new CallbackResolver($this->app);\n    }\n\n    public function testShouldResolveCallback()\n    {\n        $callable = function () {};\n        $this->app['some_service'] = function () { return new \\ArrayObject(); };\n        $this->app['callable_service'] = function () use ($callable) {\n            return $callable;\n        };\n\n        $this->assertTrue($this->resolver->isValid('some_service:methodName'));\n        $this->assertTrue($this->resolver->isValid('callable_service'));\n        $this->assertEquals(\n            array($this->app['some_service'], 'append'),\n            $this->resolver->convertCallback('some_service:append')\n        );\n        $this->assertSame($callable, $this->resolver->convertCallback('callable_service'));\n    }\n\n    /**\n     * @dataProvider nonStringsAreNotValidProvider\n     */\n    public function testNonStringsAreNotValid($name)\n    {\n        $this->assertFalse($this->resolver->isValid($name));\n    }\n\n    public function nonStringsAreNotValidProvider()\n    {\n        return array(\n            array(null),\n            array('some_service::methodName'),\n            array('missing_service'),\n        );\n    }\n\n    /**\n     * @expectedException          \\InvalidArgumentException\n     * @expectedExceptionMessageRegExp  /Service \"[a-z_]+\" is not callable./\n     * @dataProvider shouldThrowAnExceptionIfServiceIsNotCallableProvider\n     */\n    public function testShouldThrowAnExceptionIfServiceIsNotCallable($name)\n    {\n        $this->app['non_callable_obj'] = function () { return new \\stdClass(); };\n        $this->app['non_callable'] = function () { return array(); };\n        $this->resolver->convertCallback($name);\n    }\n\n    public function shouldThrowAnExceptionIfServiceIsNotCallableProvider()\n    {\n        return array(\n            array('non_callable_obj:methodA'),\n            array('non_callable'),\n        );\n    }\n}\n"
  },
  {
    "path": "tests/Silex/Tests/CallbackServicesTest.php",
    "content": "<?php\n\n/*\n * This file is part of the Silex framework.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * This source file is subject to the MIT license that is bundled\n * with this source code in the file LICENSE.\n */\n\nnamespace Silex\\Tests;\n\nuse Silex\\Application;\nuse Symfony\\Component\\HttpFoundation\\Request;\nuse Silex\\Provider\\ServiceControllerServiceProvider;\n\n/**\n * Callback as services test cases.\n *\n * @author Fabien Potencier <fabien@symfony.com>\n */\nclass CallbackServicesTest extends \\PHPUnit_Framework_TestCase\n{\n    public $called = array();\n\n    public function testCallbacksAsServices()\n    {\n        $app = new Application();\n        $app->register(new ServiceControllerServiceProvider());\n\n        $app['service'] = function () {\n            return new CallbackServicesTest();\n        };\n\n        $app->before('service:beforeApp');\n        $app->after('service:afterApp');\n        $app->finish('service:finishApp');\n        $app->error('service:error');\n        $app->on('kernel.request', 'service:onRequest');\n\n        $app\n            ->match('/', 'service:controller')\n            ->convert('foo', 'service:convert')\n            ->before('service:before')\n            ->after('service:after')\n        ;\n\n        $request = Request::create('/');\n        $response = $app->handle($request);\n        $app->terminate($request, $response);\n\n        $this->assertEquals(array(\n            'BEFORE APP',\n            'ON REQUEST',\n            'BEFORE',\n            'CONVERT',\n            'ERROR',\n            'AFTER',\n            'AFTER APP',\n            'FINISH APP',\n        ), $app['service']->called);\n    }\n\n    public function controller(Application $app)\n    {\n        $app->abort(404);\n    }\n\n    public function before()\n    {\n        $this->called[] = 'BEFORE';\n    }\n\n    public function after()\n    {\n        $this->called[] = 'AFTER';\n    }\n\n    public function beforeApp()\n    {\n        $this->called[] = 'BEFORE APP';\n    }\n\n    public function afterApp()\n    {\n        $this->called[] = 'AFTER APP';\n    }\n\n    public function finishApp()\n    {\n        $this->called[] = 'FINISH APP';\n    }\n\n    public function error()\n    {\n        $this->called[] = 'ERROR';\n    }\n\n    public function convert()\n    {\n        $this->called[] = 'CONVERT';\n    }\n\n    public function onRequest()\n    {\n        $this->called[] = 'ON REQUEST';\n    }\n}\n"
  },
  {
    "path": "tests/Silex/Tests/ControllerCollectionTest.php",
    "content": "<?php\n\n/*\n * This file is part of the Silex framework.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * This source file is subject to the MIT license that is bundled\n * with this source code in the file LICENSE.\n */\n\nnamespace Silex\\Tests;\n\nuse Silex\\Application;\nuse Silex\\Controller;\nuse Silex\\ControllerCollection;\nuse Silex\\Exception\\ControllerFrozenException;\nuse Silex\\Route;\nuse Symfony\\Component\\Routing\\RouteCollection;\n\n/**\n * ControllerCollection test cases.\n *\n * @author Igor Wiedler <igor@wiedler.ch>\n */\nclass ControllerCollectionTest extends \\PHPUnit_Framework_TestCase\n{\n    public function testGetRouteCollectionWithNoRoutes()\n    {\n        $controllers = new ControllerCollection(new Route());\n        $routes = $controllers->flush();\n        $this->assertEquals(0, count($routes->all()));\n    }\n\n    public function testGetRouteCollectionWithRoutes()\n    {\n        $controllers = new ControllerCollection(new Route());\n        $controllers->match('/foo', function () {});\n        $controllers->match('/bar', function () {});\n\n        $routes = $controllers->flush();\n        $this->assertEquals(2, count($routes->all()));\n    }\n\n    public function testControllerFreezing()\n    {\n        $controllers = new ControllerCollection(new Route());\n\n        $fooController = $controllers->match('/foo', function () {})->bind('foo');\n        $barController = $controllers->match('/bar', function () {})->bind('bar');\n\n        $controllers->flush();\n\n        try {\n            $fooController->bind('foo2');\n            $this->fail();\n        } catch (ControllerFrozenException $e) {\n        }\n\n        try {\n            $barController->bind('bar2');\n            $this->fail();\n        } catch (ControllerFrozenException $e) {\n        }\n    }\n\n    public function testConflictingRouteNames()\n    {\n        $controllers = new ControllerCollection(new Route());\n\n        $mountedRootController = $controllers->match('/', function () {});\n\n        $mainRootController = new Controller(new Route('/'));\n        $mainRootController->bind($mainRootController->generateRouteName('main_1'));\n\n        $controllers->flush();\n\n        $this->assertNotEquals($mainRootController->getRouteName(), $mountedRootController->getRouteName());\n    }\n\n    public function testUniqueGeneratedRouteNames()\n    {\n        $controllers = new ControllerCollection(new Route());\n\n        $controllers->match('/a-a', function () {});\n        $controllers->match('/a_a', function () {});\n        $controllers->match('/a/a', function () {});\n\n        $routes = $controllers->flush();\n\n        $this->assertCount(3, $routes->all());\n        $this->assertEquals(array('_a_a', '_a_a_1', '_a_a_2'), array_keys($routes->all()));\n    }\n\n    public function testUniqueGeneratedRouteNamesAmongMounts()\n    {\n        $controllers = new ControllerCollection(new Route());\n\n        $controllers->mount('/root-a', $rootA = new ControllerCollection(new Route()));\n        $controllers->mount('/root_a', $rootB = new ControllerCollection(new Route()));\n\n        $rootA->match('/leaf', function () {});\n        $rootB->match('/leaf', function () {});\n\n        $routes = $controllers->flush();\n\n        $this->assertCount(2, $routes->all());\n        $this->assertEquals(array('_root_a_leaf', '_root_a_leaf_1'), array_keys($routes->all()));\n    }\n\n    public function testUniqueGeneratedRouteNamesAmongNestedMounts()\n    {\n        $controllers = new ControllerCollection(new Route());\n\n        $controllers->mount('/root-a', $rootA = new ControllerCollection(new Route()));\n        $controllers->mount('/root_a', $rootB = new ControllerCollection(new Route()));\n\n        $rootA->mount('/tree', $treeA = new ControllerCollection(new Route()));\n        $rootB->mount('/tree', $treeB = new ControllerCollection(new Route()));\n\n        $treeA->match('/leaf', function () {});\n        $treeB->match('/leaf', function () {});\n\n        $routes = $controllers->flush();\n\n        $this->assertCount(2, $routes->all());\n        $this->assertEquals(array('_root_a_tree_leaf', '_root_a_tree_leaf_1'), array_keys($routes->all()));\n    }\n\n    public function testMountCallable()\n    {\n        $controllers = new ControllerCollection(new Route());\n        $controllers->mount('/prefix', function (ControllerCollection $coll) {\n            $coll->mount('/path', function ($coll) {\n                $coll->get('/part');\n            });\n        });\n\n        $routes = $controllers->flush();\n        $this->assertEquals('/prefix/path/part', current($routes->all())->getPath());\n    }\n\n    public function testMountCallableProperClone()\n    {\n        $controllers = new ControllerCollection(new Route(), new RouteCollection());\n        $controllers->get('/');\n\n        $subControllers = null;\n        $controllers->mount('/prefix', function (ControllerCollection $coll) use (&$subControllers) {\n            $subControllers = $coll;\n            $coll->get('/');\n        });\n\n        $routes = $controllers->flush();\n        $subRoutes = $subControllers->flush();\n        $this->assertTrue($routes->count() == 2 && $subRoutes->count() == 0);\n    }\n\n    public function testMountControllersFactory()\n    {\n        $testControllers = new ControllerCollection(new Route());\n        $controllers = new ControllerCollection(new Route(), null, function () use ($testControllers) {\n            return $testControllers;\n        });\n\n        $controllers->mount('/prefix', function ($mounted) use ($testControllers) {\n            $this->assertSame($mounted, $testControllers);\n        });\n    }\n\n    /**\n     * @expectedException \\LogicException\n     * @expectedExceptionMessage The \"mount\" method takes either a \"ControllerCollection\" instance or callable.\n     */\n    public function testMountCallableException()\n    {\n        $controllers = new ControllerCollection(new Route());\n        $controllers->mount('/prefix', '');\n    }\n\n    public function testAssert()\n    {\n        $controllers = new ControllerCollection(new Route());\n        $controllers->assert('id', '\\d+');\n        $controller = $controllers->match('/{id}/{name}/{extra}', function () {})->assert('name', '\\w+')->assert('extra', '.*');\n        $controllers->assert('extra', '\\w+');\n\n        $this->assertEquals('\\d+', $controller->getRoute()->getRequirement('id'));\n        $this->assertEquals('\\w+', $controller->getRoute()->getRequirement('name'));\n        $this->assertEquals('\\w+', $controller->getRoute()->getRequirement('extra'));\n    }\n\n    public function testValue()\n    {\n        $controllers = new ControllerCollection(new Route());\n        $controllers->value('id', '1');\n        $controller = $controllers->match('/{id}/{name}/{extra}', function () {})->value('name', 'Fabien')->value('extra', 'Symfony');\n        $controllers->value('extra', 'Twig');\n\n        $this->assertEquals('1', $controller->getRoute()->getDefault('id'));\n        $this->assertEquals('Fabien', $controller->getRoute()->getDefault('name'));\n        $this->assertEquals('Twig', $controller->getRoute()->getDefault('extra'));\n    }\n\n    public function testConvert()\n    {\n        $controllers = new ControllerCollection(new Route());\n        $controllers->convert('id', '1');\n        $controller = $controllers->match('/{id}/{name}/{extra}', function () {})->convert('name', 'Fabien')->convert('extra', 'Symfony');\n        $controllers->convert('extra', 'Twig');\n\n        $this->assertEquals(array('id' => '1', 'name' => 'Fabien', 'extra' => 'Twig'), $controller->getRoute()->getOption('_converters'));\n    }\n\n    public function testRequireHttp()\n    {\n        $controllers = new ControllerCollection(new Route());\n        $controllers->requireHttp();\n        $controller = $controllers->match('/{id}/{name}/{extra}', function () {})->requireHttps();\n\n        $this->assertEquals(array('https'), $controller->getRoute()->getSchemes());\n\n        $controllers->requireHttp();\n\n        $this->assertEquals(array('http'), $controller->getRoute()->getSchemes());\n    }\n\n    public function testBefore()\n    {\n        $controllers = new ControllerCollection(new Route());\n        $controllers->before('mid1');\n        $controller = $controllers->match('/{id}/{name}/{extra}', function () {})->before('mid2');\n        $controllers->before('mid3');\n\n        $this->assertEquals(array('mid1', 'mid2', 'mid3'), $controller->getRoute()->getOption('_before_middlewares'));\n    }\n\n    public function testAfter()\n    {\n        $controllers = new ControllerCollection(new Route());\n        $controllers->after('mid1');\n        $controller = $controllers->match('/{id}/{name}/{extra}', function () {})->after('mid2');\n        $controllers->after('mid3');\n\n        $this->assertEquals(array('mid1', 'mid2', 'mid3'), $controller->getRoute()->getOption('_after_middlewares'));\n    }\n\n    public function testWhen()\n    {\n        $controllers = new ControllerCollection(new Route());\n        $controller = $controllers->match('/{id}/{name}/{extra}', function () {})->when('request.isSecure() == true');\n\n        $this->assertEquals('request.isSecure() == true', $controller->getRoute()->getCondition());\n    }\n\n    public function testRouteExtension()\n    {\n        $route = new MyRoute1();\n\n        $controller = new ControllerCollection($route);\n        $controller->foo('foo');\n\n        $this->assertEquals('foo', $route->foo);\n    }\n\n    /**\n     * @expectedException \\BadMethodCallException\n     */\n    public function testRouteMethodDoesNotExist()\n    {\n        $route = new MyRoute1();\n\n        $controller = new ControllerCollection($route);\n        $controller->bar();\n    }\n\n    public function testNestedCollectionRouteCallbacks()\n    {\n        $cl1 = new ControllerCollection(new MyRoute1());\n        $cl2 = new ControllerCollection(new MyRoute1());\n\n        $c1 = $cl2->match('/c1', function () {});\n        $cl1->mount('/foo', $cl2);\n        $c2 = $cl2->match('/c2', function () {});\n        $cl1->before('before');\n        $c3 = $cl2->match('/c3', function () {});\n\n        $cl1->flush();\n\n        $this->assertEquals(array('before'), $c1->getRoute()->getOption('_before_middlewares'));\n        $this->assertEquals(array('before'), $c2->getRoute()->getOption('_before_middlewares'));\n        $this->assertEquals(array('before'), $c3->getRoute()->getOption('_before_middlewares'));\n    }\n\n    public function testRoutesFactoryOmitted()\n    {\n        $controllers = new ControllerCollection(new Route());\n        $routes = $controllers->flush();\n        $this->assertInstanceOf('Symfony\\Component\\Routing\\RouteCollection', $routes);\n    }\n\n    public function testRoutesFactoryInConstructor()\n    {\n        $app = new Application();\n        $app['routes_factory'] = $app->factory(function () {\n            return new RouteCollectionSubClass2();\n        });\n\n        $controllers = new ControllerCollection(new Route(), $app['routes_factory']);\n        $routes = $controllers->flush();\n        $this->assertInstanceOf('Silex\\Tests\\RouteCollectionSubClass2', $routes);\n    }\n}\n\nclass MyRoute1 extends Route\n{\n    public $foo;\n\n    public function foo($value)\n    {\n        $this->foo = $value;\n    }\n}\n\nclass RouteCollectionSubClass2 extends RouteCollection\n{\n}\n"
  },
  {
    "path": "tests/Silex/Tests/ControllerResolverTest.php",
    "content": "<?php\n\n/*\n * This file is part of the Silex framework.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * This source file is subject to the MIT license that is bundled\n * with this source code in the file LICENSE.\n */\n\nnamespace Silex\\Tests;\n\nuse Silex\\ControllerResolver;\nuse Silex\\Application;\nuse Symfony\\Component\\HttpFoundation\\Request;\n\n/**\n * ControllerResolver test cases.\n *\n * @author Fabien Potencier <fabien@symfony.com>\n */\nclass ControllerResolverTest extends \\PHPUnit_Framework_TestCase\n{\n    /**\n     * @group legacy\n     */\n    public function testGetArguments()\n    {\n        $app = new Application();\n        $resolver = new ControllerResolver($app);\n\n        $controller = function (Application $app) {};\n\n        $args = $resolver->getArguments(Request::create('/'), $controller);\n        $this->assertSame($app, $args[0]);\n    }\n}\n"
  },
  {
    "path": "tests/Silex/Tests/ControllerTest.php",
    "content": "<?php\n\n/*\n * This file is part of the Silex framework.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * This source file is subject to the MIT license that is bundled\n * with this source code in the file LICENSE.\n */\n\nnamespace Silex\\Tests;\n\nuse Silex\\Controller;\nuse Silex\\Route;\n\n/**\n * Controller test cases.\n *\n * @author Igor Wiedler <igor@wiedler.ch>\n */\nclass ControllerTest extends \\PHPUnit_Framework_TestCase\n{\n    public function testBind()\n    {\n        $controller = new Controller(new Route('/foo'));\n        $ret = $controller->bind('foo');\n\n        $this->assertSame($ret, $controller);\n        $this->assertEquals('foo', $controller->getRouteName());\n    }\n\n    /**\n     * @expectedException \\Silex\\Exception\\ControllerFrozenException\n     */\n    public function testBindOnFrozenControllerShouldThrowException()\n    {\n        $controller = new Controller(new Route('/foo'));\n        $controller->bind('foo');\n        $controller->freeze();\n        $controller->bind('bar');\n    }\n\n    public function testAssert()\n    {\n        $controller = new Controller(new Route('/foo/{bar}'));\n        $ret = $controller->assert('bar', '\\d+');\n\n        $this->assertSame($ret, $controller);\n        $this->assertEquals(array('bar' => '\\d+'), $controller->getRoute()->getRequirements());\n    }\n\n    public function testValue()\n    {\n        $controller = new Controller(new Route('/foo/{bar}'));\n        $ret = $controller->value('bar', 'foo');\n\n        $this->assertSame($ret, $controller);\n        $this->assertEquals(array('bar' => 'foo'), $controller->getRoute()->getDefaults());\n    }\n\n    public function testConvert()\n    {\n        $controller = new Controller(new Route('/foo/{bar}'));\n        $ret = $controller->convert('bar', $func = function ($bar) { return $bar; });\n\n        $this->assertSame($ret, $controller);\n        $this->assertEquals(array('bar' => $func), $controller->getRoute()->getOption('_converters'));\n    }\n\n    public function testRun()\n    {\n        $controller = new Controller(new Route('/foo/{bar}'));\n        $ret = $controller->run($cb = function () { return 'foo'; });\n\n        $this->assertSame($ret, $controller);\n        $this->assertEquals($cb, $controller->getRoute()->getDefault('_controller'));\n    }\n\n    /**\n     * @dataProvider provideRouteAndExpectedRouteName\n     */\n    public function testDefaultRouteNameGeneration(Route $route, $prefix, $expectedRouteName)\n    {\n        $controller = new Controller($route);\n        $controller->bind($controller->generateRouteName($prefix));\n\n        $this->assertEquals($expectedRouteName, $controller->getRouteName());\n    }\n\n    public function provideRouteAndExpectedRouteName()\n    {\n        return array(\n            array(new Route('/Invalid%Symbols#Stripped', array(), array(), array(), '', array(), array('POST')), '', 'POST_InvalidSymbolsStripped'),\n            array(new Route('/post/{id}', array(), array(), array(), '', array(), array('GET')), '', 'GET_post_id'),\n            array(new Route('/colon:pipe|dashes-escaped'), '', '_colon_pipe_dashes_escaped'),\n            array(new Route('/underscores_and.periods'), '', '_underscores_and.periods'),\n            array(new Route('/post/{id}', array(), array(), array(), '', array(), array('GET')), 'prefix', 'GET_prefix_post_id'),\n        );\n    }\n\n    public function testRouteExtension()\n    {\n        $route = new MyRoute();\n\n        $controller = new Controller($route);\n        $controller->foo('foo');\n\n        $this->assertEquals('foo', $route->foo);\n    }\n\n    /**\n     * @expectedException \\BadMethodCallException\n     */\n    public function testRouteMethodDoesNotExist()\n    {\n        $route = new MyRoute();\n\n        $controller = new Controller($route);\n        $controller->bar();\n    }\n}\n\nclass MyRoute extends Route\n{\n    public $foo;\n\n    public function foo($value)\n    {\n        $this->foo = $value;\n    }\n}\n"
  },
  {
    "path": "tests/Silex/Tests/EventListener/LogListenerTest.php",
    "content": "<?php\n\n/*\n * This file is part of the Silex framework.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * This source file is subject to the MIT license that is bundled\n * with this source code in the file LICENSE.\n */\n\nnamespace Silex\\Tests\\EventListener;\n\nuse Psr\\Log\\LogLevel;\nuse Silex\\EventListener\\LogListener;\nuse Symfony\\Component\\HttpKernel\\Event\\GetResponseEvent;\nuse Symfony\\Component\\HttpKernel\\Event\\FilterResponseEvent;\nuse Symfony\\Component\\HttpKernel\\Event\\GetResponseForExceptionEvent;\nuse Symfony\\Component\\HttpKernel\\KernelEvents;\nuse Symfony\\Component\\EventDispatcher\\EventDispatcher;\nuse Symfony\\Component\\HttpFoundation\\Request;\nuse Symfony\\Component\\HttpFoundation\\Response;\nuse Symfony\\Component\\HttpKernel\\HttpKernelInterface;\nuse Symfony\\Component\\HttpKernel\\Exception\\HttpException;\n\n/**\n * LogListener.\n *\n * @author Jérôme Tamarelle <jerome@tamarelle.net>\n */\nclass LogListenerTest extends \\PHPUnit_Framework_TestCase\n{\n    public function testRequestListener()\n    {\n        $logger = $this->getMockBuilder('Psr\\\\Log\\\\LoggerInterface')->getMock();\n        $logger\n            ->expects($this->once())\n            ->method('log')\n            ->with(LogLevel::DEBUG, '> GET /foo')\n        ;\n\n        $dispatcher = new EventDispatcher();\n        $dispatcher->addSubscriber(new LogListener($logger));\n\n        $kernel = $this->getMockBuilder('Symfony\\\\Component\\\\HttpKernel\\\\HttpKernelInterface')->getMock();\n\n        $dispatcher->dispatch(KernelEvents::REQUEST, new GetResponseEvent($kernel, Request::create('/subrequest'), HttpKernelInterface::SUB_REQUEST), 'Skip sub requests');\n\n        $dispatcher->dispatch(KernelEvents::REQUEST, new GetResponseEvent($kernel, Request::create('/foo'), HttpKernelInterface::MASTER_REQUEST), 'Log master requests');\n    }\n\n    public function testResponseListener()\n    {\n        $logger = $this->getMockBuilder('Psr\\\\Log\\\\LoggerInterface')->getMock();\n        $logger\n            ->expects($this->once())\n            ->method('log')\n            ->with(LogLevel::DEBUG, '< 301')\n        ;\n\n        $dispatcher = new EventDispatcher();\n        $dispatcher->addSubscriber(new LogListener($logger));\n\n        $kernel = $this->getMockBuilder('Symfony\\\\Component\\\\HttpKernel\\\\HttpKernelInterface')->getMock();\n\n        $dispatcher->dispatch(KernelEvents::RESPONSE, new FilterResponseEvent($kernel, Request::create('/foo'), HttpKernelInterface::SUB_REQUEST, Response::create('subrequest', 200)), 'Skip sub requests');\n\n        $dispatcher->dispatch(KernelEvents::RESPONSE, new FilterResponseEvent($kernel, Request::create('/foo'), HttpKernelInterface::MASTER_REQUEST, Response::create('bar', 301)), 'Log master requests');\n    }\n\n    public function testExceptionListener()\n    {\n        $logger = $this->getMockBuilder('Psr\\\\Log\\\\LoggerInterface')->getMock();\n        $logger\n            ->expects($this->at(0))\n            ->method('log')\n            ->with(LogLevel::CRITICAL, 'RuntimeException: Fatal error (uncaught exception) at '.__FILE__.' line '.(__LINE__ + 13))\n        ;\n        $logger\n            ->expects($this->at(1))\n            ->method('log')\n            ->with(LogLevel::ERROR, 'Symfony\\Component\\HttpKernel\\Exception\\HttpException: Http error (uncaught exception) at '.__FILE__.' line '.(__LINE__ + 9))\n        ;\n\n        $dispatcher = new EventDispatcher();\n        $dispatcher->addSubscriber(new LogListener($logger));\n\n        $kernel = $this->getMockBuilder('Symfony\\\\Component\\\\HttpKernel\\\\HttpKernelInterface')->getMock();\n\n        $dispatcher->dispatch(KernelEvents::EXCEPTION, new GetResponseForExceptionEvent($kernel, Request::create('/foo'), HttpKernelInterface::SUB_REQUEST, new \\RuntimeException('Fatal error')));\n        $dispatcher->dispatch(KernelEvents::EXCEPTION, new GetResponseForExceptionEvent($kernel, Request::create('/foo'), HttpKernelInterface::SUB_REQUEST, new HttpException(400, 'Http error')));\n    }\n}\n"
  },
  {
    "path": "tests/Silex/Tests/ExceptionHandlerTest.php",
    "content": "<?php\n\n/*\n * This file is part of the Silex framework.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * This source file is subject to the MIT license that is bundled\n * with this source code in the file LICENSE.\n */\n\nnamespace Silex\\Tests;\n\nuse Silex\\Application;\nuse Symfony\\Component\\HttpFoundation\\Request;\nuse Symfony\\Component\\HttpFoundation\\Response;\nuse Symfony\\Component\\HttpKernel\\Exception\\NotFoundHttpException;\n\n/**\n * Error handler test cases.\n *\n * @author Igor Wiedler <igor@wiedler.ch>\n */\nclass ExceptionHandlerTest extends \\PHPUnit_Framework_TestCase\n{\n    public function testExceptionHandlerExceptionNoDebug()\n    {\n        $app = new Application();\n        $app['debug'] = false;\n\n        $app->match('/foo', function () {\n            throw new \\RuntimeException('foo exception');\n        });\n\n        $request = Request::create('/foo');\n        $response = $app->handle($request);\n        $this->assertContains('<h1>Whoops, looks like something went wrong.</h1>', $response->getContent());\n        $this->assertEquals(500, $response->getStatusCode());\n    }\n\n    public function testExceptionHandlerExceptionDebug()\n    {\n        $app = new Application();\n        $app['debug'] = true;\n\n        $app->match('/foo', function () {\n            throw new \\RuntimeException('foo exception');\n        });\n\n        $request = Request::create('/foo');\n        $response = $app->handle($request);\n\n        $this->assertContains('foo exception', $response->getContent());\n        $this->assertEquals(500, $response->getStatusCode());\n    }\n\n    public function testExceptionHandlerNotFoundNoDebug()\n    {\n        $app = new Application();\n        $app['debug'] = false;\n\n        $request = Request::create('/foo');\n        $response = $app->handle($request);\n        $this->assertContains('<h1>Sorry, the page you are looking for could not be found.</h1>', $response->getContent());\n        $this->assertEquals(404, $response->getStatusCode());\n    }\n\n    public function testExceptionHandlerNotFoundDebug()\n    {\n        $app = new Application();\n        $app['debug'] = true;\n\n        $request = Request::create('/foo');\n        $response = $app->handle($request);\n        $this->assertContains('No route found for \"GET /foo\"', html_entity_decode($response->getContent()));\n        $this->assertEquals(404, $response->getStatusCode());\n    }\n\n    public function testExceptionHandlerMethodNotAllowedNoDebug()\n    {\n        $app = new Application();\n        $app['debug'] = false;\n\n        $app->get('/foo', function () { return 'foo'; });\n\n        $request = Request::create('/foo', 'POST');\n        $response = $app->handle($request);\n        $this->assertContains('<h1>Whoops, looks like something went wrong.</h1>', $response->getContent());\n        $this->assertEquals(405, $response->getStatusCode());\n        $this->assertEquals('GET', $response->headers->get('Allow'));\n    }\n\n    public function testExceptionHandlerMethodNotAllowedDebug()\n    {\n        $app = new Application();\n        $app['debug'] = true;\n\n        $app->get('/foo', function () { return 'foo'; });\n\n        $request = Request::create('/foo', 'POST');\n        $response = $app->handle($request);\n        $this->assertContains('No route found for \"POST /foo\": Method Not Allowed (Allow: GET)', html_entity_decode($response->getContent()));\n        $this->assertEquals(405, $response->getStatusCode());\n        $this->assertEquals('GET', $response->headers->get('Allow'));\n    }\n\n    public function testNoExceptionHandler()\n    {\n        $app = new Application();\n        unset($app['exception_handler']);\n\n        $app->match('/foo', function () {\n            throw new \\RuntimeException('foo exception');\n        });\n\n        try {\n            $request = Request::create('/foo');\n            $app->handle($request);\n            $this->fail('->handle() should not catch exceptions where no error handler was supplied');\n        } catch (\\RuntimeException $e) {\n            $this->assertEquals('foo exception', $e->getMessage());\n        }\n    }\n\n    public function testOneExceptionHandler()\n    {\n        $app = new Application();\n\n        $app->match('/500', function () {\n            throw new \\RuntimeException('foo exception');\n        });\n\n        $app->match('/404', function () {\n            throw new NotFoundHttpException('foo exception');\n        });\n\n        $app->get('/405', function () { return 'foo'; });\n\n        $app->error(function ($e, $code) {\n            return new Response('foo exception handler');\n        });\n\n        $response = $this->checkRouteResponse($app, '/500', 'foo exception handler');\n        $this->assertEquals(500, $response->getStatusCode());\n\n        $response = $app->handle(Request::create('/404'));\n        $this->assertEquals(404, $response->getStatusCode());\n\n        $response = $app->handle(Request::create('/405', 'POST'));\n        $this->assertEquals(405, $response->getStatusCode());\n        $this->assertEquals('GET', $response->headers->get('Allow'));\n    }\n\n    public function testMultipleExceptionHandlers()\n    {\n        $app = new Application();\n\n        $app->match('/foo', function () {\n            throw new \\RuntimeException('foo exception');\n        });\n\n        $errors = 0;\n\n        $app->error(function ($e) use (&$errors) {\n            ++$errors;\n        });\n\n        $app->error(function ($e) use (&$errors) {\n            ++$errors;\n        });\n\n        $app->error(function ($e) use (&$errors) {\n            ++$errors;\n\n            return new Response('foo exception handler');\n        });\n\n        $app->error(function ($e) use (&$errors) {\n            // should not execute\n            ++$errors;\n        });\n\n        $request = Request::create('/foo');\n        $this->checkRouteResponse($app, '/foo', 'foo exception handler', 'should return the first response returned by an exception handler');\n\n        $this->assertEquals(3, $errors, 'should execute error handlers until a response is returned');\n    }\n\n    public function testNoResponseExceptionHandler()\n    {\n        $app = new Application();\n        unset($app['exception_handler']);\n\n        $app->match('/foo', function () {\n            throw new \\RuntimeException('foo exception');\n        });\n\n        $errors = 0;\n\n        $app->error(function ($e) use (&$errors) {\n            ++$errors;\n        });\n\n        try {\n            $request = Request::create('/foo');\n            $app->handle($request);\n            $this->fail('->handle() should not catch exceptions where an empty error handler was supplied');\n        } catch (\\RuntimeException $e) {\n            $this->assertEquals('foo exception', $e->getMessage());\n        } catch (\\LogicException $e) {\n            $this->assertEquals('foo exception', $e->getPrevious()->getMessage());\n        }\n\n        $this->assertEquals(1, $errors, 'should execute the error handler');\n    }\n\n    public function testStringResponseExceptionHandler()\n    {\n        $app = new Application();\n\n        $app->match('/foo', function () {\n            throw new \\RuntimeException('foo exception');\n        });\n\n        $app->error(function ($e) {\n            return 'foo exception handler';\n        });\n\n        $request = Request::create('/foo');\n        $this->checkRouteResponse($app, '/foo', 'foo exception handler', 'should accept a string response from the error handler');\n    }\n\n    public function testExceptionHandlerException()\n    {\n        $app = new Application();\n\n        $app->match('/foo', function () {\n            throw new \\RuntimeException('foo exception');\n        });\n\n        $app->error(function ($e) {\n            throw new \\RuntimeException('foo exception handler exception');\n        });\n\n        try {\n            $request = Request::create('/foo');\n            $app->handle($request);\n            $this->fail('->handle() should not catch exceptions thrown from an error handler');\n        } catch (\\RuntimeException $e) {\n            $this->assertEquals('foo exception handler exception', $e->getMessage());\n        }\n    }\n\n    public function testRemoveExceptionHandlerAfterDispatcherAccess()\n    {\n        $app = new Application();\n\n        $app->match('/foo', function () {\n            throw new \\RuntimeException('foo exception');\n        });\n\n        $app->before(function () {\n            // just making sure the dispatcher gets created\n        });\n\n        unset($app['exception_handler']);\n\n        try {\n            $request = Request::create('/foo');\n            $app->handle($request);\n            $this->fail('default exception handler should have been removed');\n        } catch (\\RuntimeException $e) {\n            $this->assertEquals('foo exception', $e->getMessage());\n        }\n    }\n\n    public function testExceptionHandlerWithDefaultException()\n    {\n        $app = new Application();\n        $app['debug'] = false;\n\n        $app->match('/foo', function () {\n            throw new \\Exception();\n        });\n\n        $app->error(function (\\Exception $e) {\n            return new Response('Exception thrown', 500);\n        });\n\n        $request = Request::create('/foo');\n        $response = $app->handle($request);\n        $this->assertContains('Exception thrown', $response->getContent());\n        $this->assertEquals(500, $response->getStatusCode());\n    }\n\n    public function testExceptionHandlerWithStandardException()\n    {\n        $app = new Application();\n        $app['debug'] = false;\n\n        $app->match('/foo', function () {\n            // Throw a normal exception\n            throw new \\Exception();\n        });\n\n        // Register 2 error handlers, each with a specified Exception class\n        // Since we throw a standard Exception above only\n        // the second error handler should fire\n        $app->error(function (\\LogicException $e) { // Extends \\Exception\n\n            return 'Caught LogicException';\n        });\n        $app->error(function (\\Exception $e) {\n            return 'Caught Exception';\n        });\n\n        $request = Request::create('/foo');\n        $response = $app->handle($request);\n        $this->assertContains('Caught Exception', $response->getContent());\n    }\n\n    public function testExceptionHandlerWithSpecifiedException()\n    {\n        $app = new Application();\n        $app['debug'] = false;\n\n        $app->match('/foo', function () {\n            // Throw a specified exception\n            throw new \\LogicException();\n        });\n\n        // Register 2 error handlers, each with a specified Exception class\n        // Since we throw a LogicException above\n        // the first error handler should fire\n        $app->error(function (\\LogicException $e) { // Extends \\Exception\n\n            return 'Caught LogicException';\n        });\n        $app->error(function (\\Exception $e) {\n            return 'Caught Exception';\n        });\n\n        $request = Request::create('/foo');\n        $response = $app->handle($request);\n        $this->assertContains('Caught LogicException', $response->getContent());\n    }\n\n    public function testExceptionHandlerWithSpecifiedExceptionInReverseOrder()\n    {\n        $app = new Application();\n        $app['debug'] = false;\n\n        $app->match('/foo', function () {\n            // Throw a specified exception\n            throw new \\LogicException();\n        });\n\n        // Register the \\Exception error handler first, since the\n        // error handler works with an instanceof mechanism the\n        // second more specific error handler should not fire since\n        // the \\Exception error handler is registered first and also\n        // captures all exceptions that extend it\n        $app->error(function (\\Exception $e) {\n            return 'Caught Exception';\n        });\n        $app->error(function (\\LogicException $e) { // Extends \\Exception\n\n            return 'Caught LogicException';\n        });\n\n        $request = Request::create('/foo');\n        $response = $app->handle($request);\n        $this->assertContains('Caught Exception', $response->getContent());\n    }\n\n    public function testExceptionHandlerWithArrayStyleCallback()\n    {\n        $app = new Application();\n        $app['debug'] = false;\n\n        $app->match('/foo', function () {\n            throw new \\Exception();\n        });\n\n        // Array style callback for error handler\n        $app->error(array($this, 'exceptionHandler'));\n\n        $request = Request::create('/foo');\n        $response = $app->handle($request);\n        $this->assertContains('Caught Exception', $response->getContent());\n    }\n\n    protected function checkRouteResponse($app, $path, $expectedContent, $method = 'get', $message = null)\n    {\n        $request = Request::create($path, $method);\n        $response = $app->handle($request);\n        $this->assertEquals($expectedContent, $response->getContent(), $message);\n\n        return $response;\n    }\n\n    public function exceptionHandler()\n    {\n        return 'Caught Exception';\n    }\n}\n"
  },
  {
    "path": "tests/Silex/Tests/Fixtures/Php7Controller.php",
    "content": "<?php\n\n/*\n * This file is part of the Silex framework.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * This source file is subject to the MIT license that is bundled\n * with this source code in the file LICENSE.\n */\n\nnamespace Silex\\Tests\\Fixtures;\n\nuse Silex\\Application;\n\nclass Php7Controller\n{\n    public function typehintedAction(Application $application, string $name)\n    {\n        return 'Hello '.$application->escape($name).' in '.get_class($application);\n    }\n}\n"
  },
  {
    "path": "tests/Silex/Tests/FunctionalTest.php",
    "content": "<?php\n\n/*\n * This file is part of the Silex framework.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * This source file is subject to the MIT license that is bundled\n * with this source code in the file LICENSE.\n */\n\nnamespace Silex\\Tests;\n\nuse Silex\\Application;\nuse Silex\\Route;\nuse Silex\\ControllerCollection;\nuse Symfony\\Component\\HttpFoundation\\Request;\nuse Symfony\\Component\\HttpFoundation\\Response;\n\n/**\n * Functional test cases.\n *\n * @author Igor Wiedler <igor@wiedler.ch>\n */\nclass FunctionalTest extends \\PHPUnit_Framework_TestCase\n{\n    public function testBind()\n    {\n        $app = new Application();\n\n        $app->get('/', function () {\n            return 'hello';\n        })\n        ->bind('homepage');\n\n        $app->get('/foo', function () {\n            return 'foo';\n        })\n        ->bind('foo_abc');\n\n        $app->flush();\n        $routes = $app['routes'];\n        $this->assertInstanceOf('Symfony\\Component\\Routing\\Route', $routes->get('homepage'));\n        $this->assertInstanceOf('Symfony\\Component\\Routing\\Route', $routes->get('foo_abc'));\n    }\n\n    public function testMount()\n    {\n        $mounted = new ControllerCollection(new Route());\n        $mounted->get('/{name}', function ($name) { return new Response($name); });\n\n        $app = new Application();\n        $app->mount('/hello', $mounted);\n\n        $response = $app->handle(Request::create('/hello/Silex'));\n        $this->assertEquals('Silex', $response->getContent());\n    }\n}\n"
  },
  {
    "path": "tests/Silex/Tests/JsonTest.php",
    "content": "<?php\n\n/*\n * This file is part of the Silex framework.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * This source file is subject to the MIT license that is bundled\n * with this source code in the file LICENSE.\n */\n\nnamespace Silex\\Tests;\n\nuse Silex\\Application;\n\n/**\n * JSON test cases.\n *\n * @author Igor Wiedler <igor@wiedler.ch>\n */\nclass JsonTest extends \\PHPUnit_Framework_TestCase\n{\n    public function testJsonReturnsJsonResponse()\n    {\n        $app = new Application();\n\n        $response = $app->json();\n        $this->assertInstanceOf('Symfony\\Component\\HttpFoundation\\JsonResponse', $response);\n        $response = json_decode($response->getContent(), true);\n        $this->assertSame(array(), $response);\n    }\n\n    public function testJsonUsesData()\n    {\n        $app = new Application();\n\n        $response = $app->json(array('foo' => 'bar'));\n        $this->assertSame('{\"foo\":\"bar\"}', $response->getContent());\n    }\n\n    public function testJsonUsesStatus()\n    {\n        $app = new Application();\n\n        $response = $app->json(array(), 202);\n        $this->assertSame(202, $response->getStatusCode());\n    }\n\n    public function testJsonUsesHeaders()\n    {\n        $app = new Application();\n\n        $response = $app->json(array(), 200, array('ETag' => 'foo'));\n        $this->assertSame('foo', $response->headers->get('ETag'));\n    }\n}\n"
  },
  {
    "path": "tests/Silex/Tests/LazyDispatcherTest.php",
    "content": "<?php\n\n/*\n * This file is part of the Silex framework.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * This source file is subject to the MIT license that is bundled\n * with this source code in the file LICENSE.\n */\n\nnamespace Silex\\Tests;\n\nuse Silex\\Application;\nuse Symfony\\Component\\HttpFoundation\\Request;\n\nclass LazyDispatcherTest extends \\PHPUnit_Framework_TestCase\n{\n    /** @test */\n    public function beforeMiddlewareShouldNotCreateDispatcherEarly()\n    {\n        $dispatcherCreated = false;\n\n        $app = new Application();\n        $app->extend('dispatcher', function ($dispatcher, $app) use (&$dispatcherCreated) {\n            $dispatcherCreated = true;\n\n            return $dispatcher;\n        });\n\n        $app->before(function () {});\n\n        $this->assertFalse($dispatcherCreated);\n\n        $request = Request::create('/');\n        $app->handle($request);\n\n        $this->assertTrue($dispatcherCreated);\n    }\n\n    /** @test */\n    public function eventHelpersShouldDirectlyAddListenersAfterBoot()\n    {\n        $app = new Application();\n\n        $fired = false;\n        $app->get('/', function () use ($app, &$fired) {\n            $app->finish(function () use (&$fired) {\n                $fired = true;\n            });\n        });\n\n        $request = Request::create('/');\n        $response = $app->handle($request);\n        $app->terminate($request, $response);\n\n        $this->assertTrue($fired, 'Event was not fired');\n    }\n}\n"
  },
  {
    "path": "tests/Silex/Tests/LazyRequestMatcherTest.php",
    "content": "<?php\n\n/*\n * This file is part of the Silex framework.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * This source file is subject to the MIT license that is bundled\n * with this source code in the file LICENSE.\n */\n\nnamespace Silex\\Tests;\n\nuse Symfony\\Component\\HttpFoundation\\Request;\nuse Silex\\Provider\\Routing\\LazyRequestMatcher;\n\n/**\n * LazyRequestMatcher test case.\n *\n * @author Leszek Prabucki <leszek.prabucki@gmail.com>\n */\nclass LazyRequestMatcherTest extends \\PHPUnit_Framework_TestCase\n{\n    /**\n     * @covers Silex\\LazyRequestMatcher::getRequestMatcher\n     */\n    public function testUserMatcherIsCreatedLazily()\n    {\n        $callCounter = 0;\n        $requestMatcher = $this->getMockBuilder('Symfony\\Component\\Routing\\Matcher\\RequestMatcherInterface')->getMock();\n\n        $matcher = new LazyRequestMatcher(function () use ($requestMatcher, &$callCounter) {\n            ++$callCounter;\n\n            return $requestMatcher;\n        });\n\n        $this->assertEquals(0, $callCounter);\n        $request = Request::create('path');\n        $matcher->matchRequest($request);\n        $this->assertEquals(1, $callCounter);\n    }\n\n    /**\n     * @expectedException LogicException\n     * @expectedExceptionMessage Factory supplied to LazyRequestMatcher must return implementation of Symfony\\Component\\Routing\\RequestMatcherInterface.\n     */\n    public function testThatCanInjectRequestMatcherOnly()\n    {\n        $matcher = new LazyRequestMatcher(function () {\n            return 'someMatcher';\n        });\n\n        $request = Request::create('path');\n        $matcher->matchRequest($request);\n    }\n\n    /**\n     * @covers Silex\\LazyRequestMatcher::matchRequest\n     */\n    public function testMatchIsProxy()\n    {\n        $request = Request::create('path');\n        $matcher = $this->getMockBuilder('Symfony\\Component\\Routing\\Matcher\\RequestMatcherInterface')->getMock();\n        $matcher->expects($this->once())\n            ->method('matchRequest')\n            ->with($request)\n            ->will($this->returnValue('matcherReturnValue'));\n\n        $matcher = new LazyRequestMatcher(function () use ($matcher) {\n            return $matcher;\n        });\n        $result = $matcher->matchRequest($request);\n\n        $this->assertEquals('matcherReturnValue', $result);\n    }\n}\n"
  },
  {
    "path": "tests/Silex/Tests/LocaleTest.php",
    "content": "<?php\n\n/*\n * This file is part of the Silex framework.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * This source file is subject to the MIT license that is bundled\n * with this source code in the file LICENSE.\n */\n\nnamespace Silex\\Tests;\n\nuse Silex\\Application;\nuse Silex\\Provider\\LocaleServiceProvider;\nuse Symfony\\Component\\HttpFoundation\\Request;\nuse Symfony\\Component\\HttpKernel\\HttpKernelInterface;\n\n/**\n * Locale test cases.\n *\n * @author Fabien Potencier <fabien@symfony.com>\n */\nclass LocaleTest extends \\PHPUnit_Framework_TestCase\n{\n    public function testLocale()\n    {\n        $app = new Application();\n        $app->register(new LocaleServiceProvider());\n        $app->get('/', function (Request $request) { return $request->getLocale(); });\n        $response = $app->handle(Request::create('/'));\n        $this->assertEquals('en', $response->getContent());\n\n        $app = new Application();\n        $app->register(new LocaleServiceProvider());\n        $app['locale'] = 'fr';\n        $app->get('/', function (Request $request) { return $request->getLocale(); });\n        $response = $app->handle(Request::create('/'));\n        $this->assertEquals('fr', $response->getContent());\n\n        $app = new Application();\n        $app->register(new LocaleServiceProvider());\n        $app->get('/{_locale}', function (Request $request) { return $request->getLocale(); });\n        $response = $app->handle(Request::create('/es'));\n        $this->assertEquals('es', $response->getContent());\n    }\n\n    public function testLocaleInSubRequests()\n    {\n        $app = new Application();\n        $app->register(new LocaleServiceProvider());\n        $app->get('/embed/{_locale}', function (Request $request) { return $request->getLocale(); });\n        $app->get('/{_locale}', function (Request $request) use ($app) {\n            return $request->getLocale().$app->handle(Request::create('/embed/es'), HttpKernelInterface::SUB_REQUEST)->getContent().$request->getLocale();\n        });\n        $response = $app->handle(Request::create('/fr'));\n        $this->assertEquals('fresfr', $response->getContent());\n\n        $app = new Application();\n        $app->register(new LocaleServiceProvider());\n        $app->get('/embed', function (Request $request) { return $request->getLocale(); });\n        $app->get('/{_locale}', function (Request $request) use ($app) {\n            return $request->getLocale().$app->handle(Request::create('/embed'), HttpKernelInterface::SUB_REQUEST)->getContent().$request->getLocale();\n        });\n        $response = $app->handle(Request::create('/fr'));\n        // locale in sub-request must be \"en\" as this is the value if the sub-request is converted to an ESI\n        $this->assertEquals('frenfr', $response->getContent());\n    }\n\n    public function testLocaleWithBefore()\n    {\n        $app = new Application();\n        $app->register(new LocaleServiceProvider());\n        $app->before(function (Request $request) use ($app) { $request->setLocale('fr'); });\n        $app->get('/embed', function (Request $request) { return $request->getLocale(); });\n        $app->get('/', function (Request $request) use ($app) {\n            return $request->getLocale().$app->handle(Request::create('/embed'), HttpKernelInterface::SUB_REQUEST)->getContent().$request->getLocale();\n        });\n        $response = $app->handle(Request::create('/'));\n        // locale in sub-request is \"en\" as the before filter is only executed for the main request\n        $this->assertEquals('frenfr', $response->getContent());\n    }\n}\n"
  },
  {
    "path": "tests/Silex/Tests/MiddlewareTest.php",
    "content": "<?php\n\n/*\n * This file is part of the Silex framework.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * This source file is subject to the MIT license that is bundled\n * with this source code in the file LICENSE.\n */\n\nnamespace Silex\\Tests;\n\nuse Silex\\Application;\nuse Symfony\\Component\\HttpFoundation\\Request;\nuse Symfony\\Component\\HttpFoundation\\Response;\n\n/**\n * Middleware test cases.\n *\n * @author Igor Wiedler <igor@wiedler.ch>\n */\nclass MiddlewareTest extends \\PHPUnit_Framework_TestCase\n{\n    public function testBeforeAndAfterFilter()\n    {\n        $i = 0;\n        $test = $this;\n\n        $app = new Application();\n\n        $app->before(function () use (&$i, $test) {\n            $test->assertEquals(0, $i);\n            ++$i;\n        });\n\n        $app->match('/foo', function () use (&$i, $test) {\n            $test->assertEquals(1, $i);\n            ++$i;\n        });\n\n        $app->after(function () use (&$i, $test) {\n            $test->assertEquals(2, $i);\n            ++$i;\n        });\n\n        $request = Request::create('/foo');\n        $app->handle($request);\n\n        $this->assertEquals(3, $i);\n    }\n\n    public function testAfterFilterWithResponseObject()\n    {\n        $i = 0;\n\n        $app = new Application();\n\n        $app->match('/foo', function () use (&$i) {\n            ++$i;\n\n            return new Response('foo');\n        });\n\n        $app->after(function () use (&$i) {\n            ++$i;\n        });\n\n        $request = Request::create('/foo');\n        $app->handle($request);\n\n        $this->assertEquals(2, $i);\n    }\n\n    public function testMultipleFilters()\n    {\n        $i = 0;\n        $test = $this;\n\n        $app = new Application();\n\n        $app->before(function () use (&$i, $test) {\n            $test->assertEquals(0, $i);\n            ++$i;\n        });\n\n        $app->before(function () use (&$i, $test) {\n            $test->assertEquals(1, $i);\n            ++$i;\n        });\n\n        $app->match('/foo', function () use (&$i, $test) {\n            $test->assertEquals(2, $i);\n            ++$i;\n        });\n\n        $app->after(function () use (&$i, $test) {\n            $test->assertEquals(3, $i);\n            ++$i;\n        });\n\n        $app->after(function () use (&$i, $test) {\n            $test->assertEquals(4, $i);\n            ++$i;\n        });\n\n        $request = Request::create('/foo');\n        $app->handle($request);\n\n        $this->assertEquals(5, $i);\n    }\n\n    public function testFiltersShouldFireOnException()\n    {\n        $i = 0;\n\n        $app = new Application();\n\n        $app->before(function () use (&$i) {\n            ++$i;\n        });\n\n        $app->match('/foo', function () {\n            throw new \\RuntimeException();\n        });\n\n        $app->after(function () use (&$i) {\n            ++$i;\n        });\n\n        $app->error(function () {\n            return 'error handled';\n        });\n\n        $request = Request::create('/foo');\n        $app->handle($request);\n\n        $this->assertEquals(2, $i);\n    }\n\n    public function testFiltersShouldFireOnHttpException()\n    {\n        $i = 0;\n\n        $app = new Application();\n\n        $app->before(function () use (&$i) {\n            ++$i;\n        }, Application::EARLY_EVENT);\n\n        $app->after(function () use (&$i) {\n            ++$i;\n        });\n\n        $app->error(function () {\n            return 'error handled';\n        });\n\n        $request = Request::create('/nowhere');\n        $app->handle($request);\n\n        $this->assertEquals(2, $i);\n    }\n\n    public function testBeforeFilterPreventsBeforeMiddlewaresToBeExecuted()\n    {\n        $app = new Application();\n\n        $app->before(function () { return new Response('app before'); });\n\n        $app->get('/', function () {\n            return new Response('test');\n        })->before(function () {\n            return new Response('middleware before');\n        });\n\n        $this->assertEquals('app before', $app->handle(Request::create('/'))->getContent());\n    }\n\n    public function testBeforeFilterExceptionsWhenHandlingAnException()\n    {\n        $app = new Application();\n\n        $app->before(function () { throw new \\RuntimeException(''); });\n\n        // even if the before filter throws an exception, we must have the 404\n        $this->assertEquals(404, $app->handle(Request::create('/'))->getStatusCode());\n    }\n\n    public function testRequestShouldBePopulatedOnBefore()\n    {\n        $app = new Application();\n\n        $app->before(function (Request $request) use ($app) {\n            $app['project'] = $request->get('project');\n        });\n\n        $app->match('/foo/{project}', function () use ($app) {\n            return $app['project'];\n        });\n\n        $request = Request::create('/foo/bar');\n        $this->assertEquals('bar', $app->handle($request)->getContent());\n\n        $request = Request::create('/foo/baz');\n        $this->assertEquals('baz', $app->handle($request)->getContent());\n    }\n\n    public function testBeforeFilterAccessesRequestAndCanReturnResponse()\n    {\n        $app = new Application();\n\n        $app->before(function (Request $request) {\n            return new Response($request->get('name'));\n        });\n\n        $app->match('/', function () use ($app) { throw new \\Exception('Should never be executed'); });\n\n        $request = Request::create('/?name=Fabien');\n        $this->assertEquals('Fabien', $app->handle($request)->getContent());\n    }\n\n    public function testAfterFilterAccessRequestResponse()\n    {\n        $app = new Application();\n\n        $app->after(function (Request $request, Response $response) {\n            $response->setContent($response->getContent().'---');\n        });\n\n        $app->match('/', function () { return new Response('foo'); });\n\n        $request = Request::create('/');\n        $this->assertEquals('foo---', $app->handle($request)->getContent());\n    }\n\n    public function testAfterFilterCanReturnResponse()\n    {\n        $app = new Application();\n\n        $app->after(function (Request $request, Response $response) {\n            return new Response('bar');\n        });\n\n        $app->match('/', function () { return new Response('foo'); });\n\n        $request = Request::create('/');\n        $this->assertEquals('bar', $app->handle($request)->getContent());\n    }\n\n    public function testRouteAndApplicationMiddlewareParameterInjection()\n    {\n        $app = new Application();\n\n        $test = $this;\n\n        $middlewareTarget = array();\n        $applicationBeforeMiddleware = function ($request, $app) use (&$middlewareTarget, $test) {\n            $test->assertInstanceOf('\\Symfony\\Component\\HttpFoundation\\Request', $request);\n            $test->assertInstanceOf('\\Silex\\Application', $app);\n            $middlewareTarget[] = 'application_before_middleware_triggered';\n        };\n\n        $applicationAfterMiddleware = function ($request, $response, $app) use (&$middlewareTarget, $test) {\n            $test->assertInstanceOf('\\Symfony\\Component\\HttpFoundation\\Request', $request);\n            $test->assertInstanceOf('\\Symfony\\Component\\HttpFoundation\\Response', $response);\n            $test->assertInstanceOf('\\Silex\\Application', $app);\n            $middlewareTarget[] = 'application_after_middleware_triggered';\n        };\n\n        $applicationFinishMiddleware = function ($request, $response, $app) use (&$middlewareTarget, $test) {\n            $test->assertInstanceOf('\\Symfony\\Component\\HttpFoundation\\Request', $request);\n            $test->assertInstanceOf('\\Symfony\\Component\\HttpFoundation\\Response', $response);\n            $test->assertInstanceOf('\\Silex\\Application', $app);\n            $middlewareTarget[] = 'application_finish_middleware_triggered';\n        };\n\n        $routeBeforeMiddleware = function ($request, $app) use (&$middlewareTarget, $test) {\n            $test->assertInstanceOf('\\Symfony\\Component\\HttpFoundation\\Request', $request);\n            $test->assertInstanceOf('\\Silex\\Application', $app);\n            $middlewareTarget[] = 'route_before_middleware_triggered';\n        };\n\n        $routeAfterMiddleware = function ($request, $response, $app) use (&$middlewareTarget, $test) {\n            $test->assertInstanceOf('\\Symfony\\Component\\HttpFoundation\\Request', $request);\n            $test->assertInstanceOf('\\Symfony\\Component\\HttpFoundation\\Response', $response);\n            $test->assertInstanceOf('\\Silex\\Application', $app);\n            $middlewareTarget[] = 'route_after_middleware_triggered';\n        };\n\n        $app->before($applicationBeforeMiddleware);\n        $app->after($applicationAfterMiddleware);\n        $app->finish($applicationFinishMiddleware);\n\n        $app->match('/', function () {\n            return new Response('foo');\n        })\n        ->before($routeBeforeMiddleware)\n        ->after($routeAfterMiddleware);\n\n        $request = Request::create('/');\n        $response = $app->handle($request);\n        $app->terminate($request, $response);\n\n        $this->assertSame(array('application_before_middleware_triggered', 'route_before_middleware_triggered', 'route_after_middleware_triggered', 'application_after_middleware_triggered', 'application_finish_middleware_triggered'), $middlewareTarget);\n    }\n}\n"
  },
  {
    "path": "tests/Silex/Tests/Provider/AssetServiceProviderTest.php",
    "content": "<?php\n\n/*\n * This file is part of the Silex framework.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * This source file is subject to the MIT license that is bundled\n * with this source code in the file LICENSE.\n */\n\nnamespace Silex\\Tests\\Provider;\n\nuse Silex\\Application;\nuse Silex\\Provider\\AssetServiceProvider;\n\nclass AssetServiceProviderTest extends \\PHPUnit_Framework_TestCase\n{\n    public function testGenerateAssetUrl()\n    {\n        $app = new Application();\n        $app->register(new AssetServiceProvider(), array(\n            'assets.version' => 'v1',\n            'assets.version_format' => '%s?version=%s',\n            'assets.named_packages' => array(\n                'css' => array('version' => 'css2', 'base_path' => '/whatever-makes-sense'),\n                'images' => array('base_urls' => array('https://img.example.com')),\n            ),\n        ));\n\n        $this->assertEquals('/foo.png?version=v1', $app['assets.packages']->getUrl('/foo.png'));\n        $this->assertEquals('/whatever-makes-sense/foo.css?css2', $app['assets.packages']->getUrl('/foo.css', 'css'));\n        $this->assertEquals('https://img.example.com/foo.png', $app['assets.packages']->getUrl('/foo.png', 'images'));\n    }\n}\n"
  },
  {
    "path": "tests/Silex/Tests/Provider/DoctrineServiceProviderTest.php",
    "content": "<?php\n\n/*\n * This file is part of the Silex framework.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * This source file is subject to the MIT license that is bundled\n * with this source code in the file LICENSE.\n */\n\nnamespace Silex\\Tests\\Provider;\n\nuse Pimple\\Container;\nuse Silex\\Application;\nuse Silex\\Provider\\DoctrineServiceProvider;\n\n/**\n * DoctrineProvider test cases.\n *\n * Fabien Potencier <fabien@symfony.com>\n */\nclass DoctrineServiceProviderTest extends \\PHPUnit_Framework_TestCase\n{\n    public function testOptionsInitializer()\n    {\n        $app = new Application();\n        $app->register(new DoctrineServiceProvider());\n\n        $this->assertEquals($app['db.default_options'], $app['db']->getParams());\n    }\n\n    public function testSingleConnection()\n    {\n        if (!in_array('sqlite', \\PDO::getAvailableDrivers())) {\n            $this->markTestSkipped('pdo_sqlite is not available');\n        }\n\n        $app = new Application();\n        $app->register(new DoctrineServiceProvider(), array(\n            'db.options' => array('driver' => 'pdo_sqlite', 'memory' => true),\n        ));\n\n        $db = $app['db'];\n        $params = $db->getParams();\n        $this->assertTrue(array_key_exists('memory', $params));\n        $this->assertTrue($params['memory']);\n        $this->assertInstanceof('Doctrine\\DBAL\\Driver\\PDOSqlite\\Driver', $db->getDriver());\n        $this->assertEquals(22, $app['db']->fetchColumn('SELECT 22'));\n\n        $this->assertSame($app['dbs']['default'], $db);\n    }\n\n    public function testMultipleConnections()\n    {\n        if (!in_array('sqlite', \\PDO::getAvailableDrivers())) {\n            $this->markTestSkipped('pdo_sqlite is not available');\n        }\n\n        $app = new Application();\n        $app->register(new DoctrineServiceProvider(), array(\n            'dbs.options' => array(\n                'sqlite1' => array('driver' => 'pdo_sqlite', 'memory' => true),\n                'sqlite2' => array('driver' => 'pdo_sqlite', 'path' => sys_get_temp_dir().'/silex'),\n            ),\n        ));\n\n        $db = $app['db'];\n        $params = $db->getParams();\n        $this->assertTrue(array_key_exists('memory', $params));\n        $this->assertTrue($params['memory']);\n        $this->assertInstanceof('Doctrine\\DBAL\\Driver\\PDOSqlite\\Driver', $db->getDriver());\n        $this->assertEquals(22, $app['db']->fetchColumn('SELECT 22'));\n\n        $this->assertSame($app['dbs']['sqlite1'], $db);\n\n        $db2 = $app['dbs']['sqlite2'];\n        $params = $db2->getParams();\n        $this->assertTrue(array_key_exists('path', $params));\n        $this->assertEquals(sys_get_temp_dir().'/silex', $params['path']);\n    }\n\n    public function testLoggerLoading()\n    {\n        if (!in_array('sqlite', \\PDO::getAvailableDrivers())) {\n            $this->markTestSkipped('pdo_sqlite is not available');\n        }\n\n        $app = new Application();\n        $this->assertTrue(isset($app['logger']));\n        $this->assertNull($app['logger']);\n        $app->register(new DoctrineServiceProvider(), array(\n            'dbs.options' => array(\n                'sqlite1' => array('driver' => 'pdo_sqlite', 'memory' => true),\n            ),\n        ));\n        $this->assertEquals(22, $app['db']->fetchColumn('SELECT 22'));\n        $this->assertNull($app['db']->getConfiguration()->getSQLLogger());\n    }\n\n    public function testLoggerNotLoaded()\n    {\n        if (!in_array('sqlite', \\PDO::getAvailableDrivers())) {\n            $this->markTestSkipped('pdo_sqlite is not available');\n        }\n\n        $app = new Container();\n        $app->register(new DoctrineServiceProvider(), array(\n            'dbs.options' => array(\n                'sqlite1' => array('driver' => 'pdo_sqlite', 'memory' => true),\n            ),\n        ));\n        $this->assertEquals(22, $app['db']->fetchColumn('SELECT 22'));\n        $this->assertNull($app['db']->getConfiguration()->getSQLLogger());\n    }\n}\n"
  },
  {
    "path": "tests/Silex/Tests/Provider/FormServiceProviderTest/DisableCsrfExtension.php",
    "content": "<?php\n\nnamespace Silex\\Tests\\Provider\\FormServiceProviderTest;\n\nuse Symfony\\Component\\Form\\AbstractTypeExtension;\nuse Symfony\\Component\\Form\\Extension\\Core\\Type\\FormType;\nuse Symfony\\Component\\OptionsResolver\\OptionsResolver;\n\nclass DisableCsrfExtension extends AbstractTypeExtension\n{\n    public function configureOptions(OptionsResolver $resolver)\n    {\n        $resolver->setDefaults(array(\n            'csrf_protection' => false,\n        ));\n    }\n\n    public function getExtendedType()\n    {\n        return FormType::class;\n    }\n}\n"
  },
  {
    "path": "tests/Silex/Tests/Provider/FormServiceProviderTest.php",
    "content": "<?php\n\n/*\n * This file is part of the Silex framework.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * This source file is subject to the MIT license that is bundled\n * with this source code in the file LICENSE.\n */\n\nnamespace Silex\\Tests\\Provider;\n\nuse Silex\\Application;\nuse Silex\\Provider\\FormServiceProvider;\nuse Silex\\Provider\\CsrfServiceProvider;\nuse Silex\\Provider\\SessionServiceProvider;\nuse Silex\\Provider\\TranslationServiceProvider;\nuse Silex\\Provider\\ValidatorServiceProvider;\nuse Symfony\\Component\\Form\\AbstractType;\nuse Symfony\\Component\\Form\\AbstractTypeExtension;\nuse Symfony\\Component\\Form\\FormTypeGuesserChain;\nuse Symfony\\Component\\HttpFoundation\\Request;\nuse Symfony\\Component\\OptionsResolver\\OptionsResolver;\nuse Symfony\\Component\\OptionsResolver\\OptionsResolverInterface;\nuse Symfony\\Component\\Translation\\Exception\\NotFoundResourceException;\n\nclass FormServiceProviderTest extends \\PHPUnit_Framework_TestCase\n{\n    public function testFormFactoryServiceIsFormFactory()\n    {\n        $app = new Application();\n        $app->register(new FormServiceProvider());\n        $this->assertInstanceOf('Symfony\\Component\\Form\\FormFactory', $app['form.factory']);\n    }\n\n    public function testFormServiceProviderWillLoadTypes()\n    {\n        $app = new Application();\n\n        $app->register(new FormServiceProvider());\n\n        $app->extend('form.types', function ($extensions) {\n            $extensions[] = new DummyFormType();\n\n            return $extensions;\n        });\n\n        $form = $app['form.factory']->createBuilder('Symfony\\Component\\Form\\Extension\\Core\\Type\\FormType', array())\n            ->add('dummy', 'Silex\\Tests\\Provider\\DummyFormType')\n            ->getForm();\n\n        $this->assertInstanceOf('Symfony\\Component\\Form\\Form', $form);\n    }\n\n    public function testFormServiceProviderWillLoadTypesServices()\n    {\n        $app = new Application();\n\n        $app->register(new FormServiceProvider());\n\n        $app['dummy'] = function () {\n            return new DummyFormType();\n        };\n        $app->extend('form.types', function ($extensions) {\n            $extensions[] = 'dummy';\n\n            return $extensions;\n        });\n\n        $form = $app['form.factory']\n            ->createBuilder('Symfony\\Component\\Form\\Extension\\Core\\Type\\FormType', array())\n            ->add('dummy', 'dummy')\n            ->getForm();\n\n        $this->assertInstanceOf('Symfony\\Component\\Form\\Form', $form);\n    }\n\n    /**\n     * @expectedException \\Symfony\\Component\\Form\\Exception\\InvalidArgumentException\n     * @expectedExceptionMessage Invalid form type. The silex service \"dummy\" does not exist.\n     */\n    public function testNonExistentTypeService()\n    {\n        $app = new Application();\n\n        $app->register(new FormServiceProvider());\n\n        $app->extend('form.types', function ($extensions) {\n            $extensions[] = 'dummy';\n\n            return $extensions;\n        });\n\n        $app['form.factory']\n            ->createBuilder('Symfony\\Component\\Form\\Extension\\Core\\Type\\FormType', array())\n            ->add('dummy', 'dummy')\n            ->getForm();\n    }\n\n    public function testFormServiceProviderWillLoadTypeExtensions()\n    {\n        $app = new Application();\n\n        $app->register(new FormServiceProvider());\n\n        $app->extend('form.type.extensions', function ($extensions) {\n            $extensions[] = new DummyFormTypeExtension();\n\n            return $extensions;\n        });\n\n        $form = $app['form.factory']->createBuilder('Symfony\\Component\\Form\\Extension\\Core\\Type\\FormType', array())\n            ->add('file', 'Symfony\\Component\\Form\\Extension\\Core\\Type\\FileType', array('image_path' => 'webPath'))\n            ->getForm();\n\n        $this->assertInstanceOf('Symfony\\Component\\Form\\Form', $form);\n    }\n\n    public function testFormServiceProviderWillLoadTypeExtensionsServices()\n    {\n        $app = new Application();\n\n        $app->register(new FormServiceProvider());\n\n        $app['dummy.form.type.extension'] = function () {\n            return new DummyFormTypeExtension();\n        };\n        $app->extend('form.type.extensions', function ($extensions) {\n            $extensions[] = 'dummy.form.type.extension';\n\n            return $extensions;\n        });\n\n        $form = $app['form.factory']\n            ->createBuilder('Symfony\\Component\\Form\\Extension\\Core\\Type\\FormType', array())\n            ->add('file', 'Symfony\\Component\\Form\\Extension\\Core\\Type\\FileType', array('image_path' => 'webPath'))\n            ->getForm();\n\n        $this->assertInstanceOf('Symfony\\Component\\Form\\Form', $form);\n    }\n\n    /**\n     * @expectedException \\Symfony\\Component\\Form\\Exception\\InvalidArgumentException\n     * @expectedExceptionMessage Invalid form type extension. The silex service \"dummy.form.type.extension\" does not exist.\n     */\n    public function testNonExistentTypeExtensionService()\n    {\n        $app = new Application();\n\n        $app->register(new FormServiceProvider());\n\n        $app->extend('form.type.extensions', function ($extensions) {\n            $extensions[] = 'dummy.form.type.extension';\n\n            return $extensions;\n        });\n\n        $app['form.factory']\n            ->createBuilder('Symfony\\Component\\Form\\Extension\\Core\\Type\\FormType', array())\n            ->add('dummy', 'dummy.form.type')\n            ->getForm();\n    }\n\n    public function testFormServiceProviderWillLoadTypeGuessers()\n    {\n        $app = new Application();\n\n        $app->register(new FormServiceProvider());\n\n        $app->extend('form.type.guessers', function ($guessers) {\n            $guessers[] = new FormTypeGuesserChain(array());\n\n            return $guessers;\n        });\n\n        $this->assertInstanceOf('Symfony\\Component\\Form\\FormFactory', $app['form.factory']);\n    }\n\n    public function testFormServiceProviderWillLoadTypeGuessersServices()\n    {\n        $app = new Application();\n\n        $app->register(new FormServiceProvider());\n\n        $app['dummy.form.type.guesser'] = function () {\n            return new FormTypeGuesserChain(array());\n        };\n        $app->extend('form.type.guessers', function ($guessers) {\n            $guessers[] = 'dummy.form.type.guesser';\n\n            return $guessers;\n        });\n\n        $this->assertInstanceOf('Symfony\\Component\\Form\\FormFactory', $app['form.factory']);\n    }\n\n    /**\n     * @expectedException \\Symfony\\Component\\Form\\Exception\\InvalidArgumentException\n     * @expectedExceptionMessage Invalid form type guesser. The silex service \"dummy.form.type.guesser\" does not exist.\n     */\n    public function testNonExistentTypeGuesserService()\n    {\n        $app = new Application();\n\n        $app->register(new FormServiceProvider());\n\n        $app->extend('form.type.guessers', function ($extensions) {\n            $extensions[] = 'dummy.form.type.guesser';\n\n            return $extensions;\n        });\n\n        $factory = $app['form.factory'];\n    }\n\n    public function testFormServiceProviderWillUseTranslatorIfAvailable()\n    {\n        $app = new Application();\n\n        $app->register(new FormServiceProvider());\n        $app->register(new TranslationServiceProvider());\n        $app['translator.domains'] = array(\n            'messages' => array(\n                'de' => array(\n                    'The CSRF token is invalid. Please try to resubmit the form.' => 'German translation',\n                ),\n            ),\n        );\n        $app['locale'] = 'de';\n\n        $app['csrf.token_manager'] = function () {\n            return $this->getMockBuilder('Symfony\\Component\\Security\\Csrf\\CsrfTokenManagerInterface')->getMock();\n        };\n\n        $form = $app['form.factory']->createBuilder('Symfony\\Component\\Form\\Extension\\Core\\Type\\FormType', array())\n            ->getForm();\n\n        $form->handleRequest($req = Request::create('/', 'POST', array('form' => array(\n            '_token' => 'the wrong token',\n        ))));\n\n        $this->assertFalse($form->isValid());\n        $r = new \\ReflectionMethod($form, 'getErrors');\n        if (!$r->getNumberOfParameters()) {\n            $this->assertContains('ERROR: German translation', $form->getErrorsAsString());\n        } else {\n            // as of 2.5\n            $this->assertContains('ERROR: German translation', (string) $form->getErrors(true, false));\n        }\n    }\n\n    public function testFormServiceProviderWillNotAddNonexistentTranslationFiles()\n    {\n        $app = new Application(array(\n            'locale' => 'nonexistent',\n        ));\n\n        $app->register(new FormServiceProvider());\n        $app->register(new ValidatorServiceProvider());\n        $app->register(new TranslationServiceProvider(), array(\n            'locale_fallbacks' => array(),\n        ));\n\n        $app['form.factory'];\n        $translator = $app['translator'];\n\n        try {\n            $translator->trans('test');\n        } catch (NotFoundResourceException $e) {\n            $this->fail('Form factory should not add a translation resource that does not exist');\n        }\n    }\n\n    public function testFormCsrf()\n    {\n        $app = new Application();\n        $app->register(new FormServiceProvider());\n        $app->register(new SessionServiceProvider());\n        $app->register(new CsrfServiceProvider());\n        $app['session.test'] = true;\n\n        $form = $app['form.factory']->createBuilder('Symfony\\Component\\Form\\Extension\\Core\\Type\\FormType', array())->getForm();\n\n        $this->assertTrue(isset($form->createView()['_token']));\n    }\n\n    public function testUserExtensionCanConfigureDefaultExtensions()\n    {\n        $app = new Application();\n        $app->register(new FormServiceProvider());\n        $app->register(new SessionServiceProvider());\n        $app->register(new CsrfServiceProvider());\n        $app['session.test'] = true;\n\n        $app->extend('form.type.extensions', function ($extensions) {\n            $extensions[] = new FormServiceProviderTest\\DisableCsrfExtension();\n\n            return $extensions;\n        });\n        $form = $app['form.factory']->createBuilder('Symfony\\Component\\Form\\Extension\\Core\\Type\\FormType', array())->getForm();\n\n        $this->assertFalse($form->getConfig()->getOption('csrf_protection'));\n    }\n}\n\nif (!class_exists('Symfony\\Component\\Form\\Deprecated\\FormEvents')) {\n    class DummyFormType extends AbstractType\n    {\n    }\n} else {\n    // FormTypeInterface::getName() is needed by the form component 2.8.x\n    class DummyFormType extends AbstractType\n    {\n        /**\n         * @return string The name of this type\n         */\n        public function getName()\n        {\n            return 'dummy';\n        }\n    }\n}\n\nif (method_exists('Symfony\\Component\\Form\\AbstractType', 'configureOptions')) {\n    class DummyFormTypeExtension extends AbstractTypeExtension\n    {\n        public function getExtendedType()\n        {\n            return 'Symfony\\Component\\Form\\Extension\\Core\\Type\\FileType';\n        }\n\n        public function configureOptions(OptionsResolver $resolver)\n        {\n            $resolver->setDefined(array('image_path'));\n        }\n    }\n} else {\n    class DummyFormTypeExtension extends AbstractTypeExtension\n    {\n        public function getExtendedType()\n        {\n            return 'Symfony\\Component\\Form\\Extension\\Core\\Type\\FileType';\n        }\n\n        public function setDefaultOptions(OptionsResolverInterface $resolver)\n        {\n            if (!method_exists($resolver, 'setDefined')) {\n                $resolver->setOptional(array('image_path'));\n            } else {\n                $resolver->setDefined(array('image_path'));\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "tests/Silex/Tests/Provider/HttpCacheServiceProviderTest.php",
    "content": "<?php\n\n/*\n * This file is part of the Silex framework.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * This source file is subject to the MIT license that is bundled\n * with this source code in the file LICENSE.\n */\n\nnamespace Silex\\Tests\\Provider;\n\nuse Silex\\Application;\nuse Silex\\Provider\\HttpCacheServiceProvider;\nuse Symfony\\Component\\HttpFoundation\\Request;\nuse Symfony\\Component\\HttpFoundation\\Response;\n\n/**\n * HttpCacheProvider test cases.\n *\n * @author Igor Wiedler <igor@wiedler.ch>\n */\nclass HttpCacheServiceProviderTest extends \\PHPUnit_Framework_TestCase\n{\n    public function testRegister()\n    {\n        $app = new Application();\n\n        $app->register(new HttpCacheServiceProvider(), array(\n            'http_cache.cache_dir' => sys_get_temp_dir().'/silex_http_cache_'.uniqid(),\n        ));\n\n        $this->assertInstanceOf('Silex\\Provider\\HttpCache\\HttpCache', $app['http_cache']);\n\n        return $app;\n    }\n\n    /**\n     * @depends testRegister\n     */\n    public function testRunCallsShutdown($app)\n    {\n        $finished = false;\n\n        $app->finish(function () use (&$finished) {\n            $finished = true;\n        });\n\n        $app->get('/', function () use ($app) {\n            return new UnsendableResponse('will do something after finish');\n        });\n\n        $request = Request::create('/');\n        $app['http_cache']->run($request);\n\n        $this->assertTrue($finished);\n    }\n\n    public function testDebugDefaultsToThatOfApp()\n    {\n        $app = new Application();\n\n        $app->register(new HttpCacheServiceProvider(), array(\n            'http_cache.cache_dir' => sys_get_temp_dir().'/silex_http_cache_'.uniqid(),\n        ));\n\n        $app['debug'] = true;\n        $app['http_cache'];\n        $this->assertTrue($app['http_cache.options']['debug']);\n    }\n}\n\nclass UnsendableResponse extends Response\n{\n    public function send()\n    {\n        // do nothing\n    }\n}\n"
  },
  {
    "path": "tests/Silex/Tests/Provider/HttpFragmentServiceProviderTest.php",
    "content": "<?php\n\n/*\n * This file is part of the Silex framework.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * This source file is subject to the MIT license that is bundled\n * with this source code in the file LICENSE.\n */\n\nnamespace Silex\\Tests\\Provider;\n\nuse Silex\\Application;\nuse Silex\\Provider\\HttpCacheServiceProvider;\nuse Silex\\Provider\\HttpFragmentServiceProvider;\nuse Silex\\Provider\\TwigServiceProvider;\nuse Symfony\\Component\\HttpFoundation\\Request;\n\nclass HttpFragmentServiceProviderTest extends \\PHPUnit_Framework_TestCase\n{\n    public function testRenderFunction()\n    {\n        $app = new Application();\n\n        $app->register(new HttpFragmentServiceProvider());\n        $app->register(new HttpCacheServiceProvider(), array('http_cache.cache_dir' => sys_get_temp_dir()));\n        $app->register(new TwigServiceProvider(), array(\n            'twig.templates' => array(\n                'hello' => '{{ render(\"/foo\") }}{{ render_esi(\"/foo\") }}{{ render_hinclude(\"/foo\") }}',\n                'foo' => 'foo',\n            ),\n        ));\n\n        $app->get('/hello', function () use ($app) {\n            return $app['twig']->render('hello');\n        });\n\n        $app->get('/foo', function () use ($app) {\n            return $app['twig']->render('foo');\n        });\n\n        $response = $app['http_cache']->handle(Request::create('/hello'));\n\n        $this->assertEquals('foofoo<hx:include src=\"/foo\"></hx:include>', $response->getContent());\n    }\n}\n"
  },
  {
    "path": "tests/Silex/Tests/Provider/MonologServiceProviderTest.php",
    "content": "<?php\n\n/*\n * This file is part of the Silex framework.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * This source file is subject to the MIT license that is bundled\n * with this source code in the file LICENSE.\n */\n\nnamespace Silex\\Tests\\Provider;\n\nuse Monolog\\Formatter\\JsonFormatter;\nuse Monolog\\Handler\\TestHandler;\nuse Monolog\\Logger;\nuse Silex\\Application;\nuse Silex\\Provider\\MonologServiceProvider;\nuse Symfony\\Component\\HttpFoundation\\RedirectResponse;\nuse Symfony\\Component\\HttpFoundation\\Request;\nuse Symfony\\Component\\HttpKernel\\Kernel;\n\n/**\n * MonologProvider test cases.\n *\n * @author Igor Wiedler <igor@wiedler.ch>\n */\nclass MonologServiceProviderTest extends \\PHPUnit_Framework_TestCase\n{\n    private $currErrorHandler;\n\n    protected function setUp()\n    {\n        $this->currErrorHandler = set_error_handler('var_dump');\n        restore_error_handler();\n    }\n\n    protected function tearDown()\n    {\n        set_error_handler($this->currErrorHandler);\n    }\n\n    public function testRequestLogging()\n    {\n        $app = $this->getApplication();\n\n        $app->get('/foo', function () use ($app) {\n            return 'foo';\n        });\n\n        $this->assertFalse($app['monolog.handler']->hasInfoRecords());\n\n        $request = Request::create('/foo');\n        $app->handle($request);\n\n        $this->assertTrue($app['monolog.handler']->hasDebug('> GET /foo'));\n        $this->assertTrue($app['monolog.handler']->hasDebug('< 200'));\n\n        $records = $app['monolog.handler']->getRecords();\n        if (Kernel::VERSION_ID < 30100) {\n            $this->assertContains('Matched route \"GET_foo\"', $records[0]['message']);\n        } else {\n            $this->assertContains('Matched route \"{route}\".', $records[0]['message']);\n            $this->assertSame('GET_foo', $records[0]['context']['route']);\n        }\n    }\n\n    public function testManualLogging()\n    {\n        $app = $this->getApplication();\n\n        $app->get('/log', function () use ($app) {\n            $app['monolog']->addDebug('logging a message');\n        });\n\n        $this->assertFalse($app['monolog.handler']->hasDebugRecords());\n\n        $request = Request::create('/log');\n        $app->handle($request);\n\n        $this->assertTrue($app['monolog.handler']->hasDebug('logging a message'));\n    }\n\n    public function testOverrideFormatter()\n    {\n        $app = new Application();\n\n        $app->register(new MonologServiceProvider(), array(\n            'monolog.formatter' => new JsonFormatter(),\n            'monolog.logfile' => 'php://memory',\n        ));\n\n        $this->assertInstanceOf('Monolog\\Formatter\\JsonFormatter', $app['monolog.handler']->getFormatter());\n    }\n\n    public function testErrorLogging()\n    {\n        $app = $this->getApplication();\n\n        $app->error(function (\\Exception $e) {\n            return 'error handled';\n        });\n\n        /*\n         * Simulate 404, logged to error level\n         */\n        $this->assertFalse($app['monolog.handler']->hasErrorRecords());\n\n        $request = Request::create('/error');\n        $app->handle($request);\n\n        $records = $app['monolog.handler']->getRecords();\n        $pattern = \"#Symfony\\\\\\\\Component\\\\\\\\HttpKernel\\\\\\\\Exception\\\\\\\\NotFoundHttpException: No route found for \\\"GET /error\\\" \\(uncaught exception\\) at .* line \\d+#\";\n        $this->assertMatchingRecord($pattern, Logger::ERROR, $app['monolog.handler']);\n\n        /*\n         * Simulate unhandled exception, logged to critical\n         */\n        $app->get('/error', function () {\n            throw new \\RuntimeException('very bad error');\n        });\n\n        $this->assertFalse($app['monolog.handler']->hasCriticalRecords());\n\n        $request = Request::create('/error');\n        $app->handle($request);\n\n        $pattern = \"#RuntimeException: very bad error \\(uncaught exception\\) at .* line \\d+#\";\n        $this->assertMatchingRecord($pattern, Logger::CRITICAL, $app['monolog.handler']);\n    }\n\n    public function testRedirectLogging()\n    {\n        $app = $this->getApplication();\n\n        $app->get('/foo', function () use ($app) {\n            return new RedirectResponse('/bar', 302);\n        });\n\n        $this->assertFalse($app['monolog.handler']->hasInfoRecords());\n\n        $request = Request::create('/foo');\n        $app->handle($request);\n\n        $this->assertTrue($app['monolog.handler']->hasDebug('< 302 /bar'));\n    }\n\n    public function testErrorLoggingGivesWayToSecurityExceptionHandling()\n    {\n        $app = $this->getApplication();\n        $app['monolog.level'] = Logger::ERROR;\n\n        $app->register(new \\Silex\\Provider\\SecurityServiceProvider(), array(\n            'security.firewalls' => array(\n                'admin' => array(\n                    'pattern' => '^/admin',\n                    'http' => true,\n                    'users' => array(),\n                ),\n            ),\n        ));\n\n        $app->get('/admin', function () {\n            return 'SECURE!';\n        });\n\n        $request = Request::create('/admin');\n        $app->run($request);\n\n        $this->assertEmpty($app['monolog.handler']->getRecords(), 'Expected no logging to occur');\n    }\n\n    public function testStringErrorLevel()\n    {\n        $app = $this->getApplication();\n        $app['monolog.level'] = 'info';\n\n        $this->assertSame(Logger::INFO, $app['monolog.handler']->getLevel());\n    }\n\n    /**\n     * @expectedException \\InvalidArgumentException\n     * @expectedExceptionMessage Provided logging level 'foo' does not exist. Must be a valid monolog logging level.\n     */\n    public function testNonExistentStringErrorLevel()\n    {\n        $app = $this->getApplication();\n        $app['monolog.level'] = 'foo';\n\n        $app['monolog.handler']->getLevel();\n    }\n\n    public function testDisableListener()\n    {\n        $app = $this->getApplication();\n        unset($app['monolog.listener']);\n\n        $app->handle(Request::create('/404'));\n\n        $this->assertEmpty($app['monolog.handler']->getRecords(), 'Expected no logging to occur');\n    }\n\n    protected function assertMatchingRecord($pattern, $level, $handler)\n    {\n        $found = false;\n        $records = $handler->getRecords();\n        foreach ($records as $record) {\n            if (preg_match($pattern, $record['message']) && $record['level'] == $level) {\n                $found = true;\n                continue;\n            }\n        }\n        $this->assertTrue($found, \"Trying to find record matching $pattern with level $level\");\n    }\n\n    protected function getApplication()\n    {\n        $app = new Application();\n\n        $app->register(new MonologServiceProvider(), array(\n            'monolog.handler' => function () use ($app) {\n                $level = MonologServiceProvider::translateLevel($app['monolog.level']);\n\n                return new TestHandler($level);\n            },\n            'monolog.logfile' => 'php://memory',\n        ));\n\n        return $app;\n    }\n}\n"
  },
  {
    "path": "tests/Silex/Tests/Provider/RememberMeServiceProviderTest.php",
    "content": "<?php\n\n/*\n * This file is part of the Silex framework.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * This source file is subject to the MIT license that is bundled\n * with this source code in the file LICENSE.\n */\n\nnamespace Silex\\Tests\\Provider;\n\nuse Silex\\Application;\nuse Silex\\WebTestCase;\nuse Silex\\Provider\\RememberMeServiceProvider;\nuse Silex\\Provider\\SecurityServiceProvider;\nuse Silex\\Provider\\SessionServiceProvider;\nuse Symfony\\Component\\HttpKernel\\Client;\nuse Symfony\\Component\\Security\\Http\\SecurityEvents;\n\n/**\n * SecurityServiceProvider.\n *\n * @author Fabien Potencier <fabien@symfony.com>\n */\nclass RememberMeServiceProviderTest extends WebTestCase\n{\n    public function testRememberMeAuthentication()\n    {\n        $app = $this->createApplication();\n\n        $interactiveLogin = new InteractiveLoginTriggered();\n        $app->on(SecurityEvents::INTERACTIVE_LOGIN, array($interactiveLogin, 'onInteractiveLogin'));\n\n        $client = new Client($app);\n\n        $client->request('get', '/');\n        $this->assertFalse($interactiveLogin->triggered, 'The interactive login has not been triggered yet');\n        $client->request('post', '/login_check', array('_username' => 'fabien', '_password' => 'foo', '_remember_me' => 'true'));\n        $client->followRedirect();\n        $this->assertEquals('AUTHENTICATED_FULLY', $client->getResponse()->getContent());\n        $this->assertTrue($interactiveLogin->triggered, 'The interactive login has been triggered');\n\n        $this->assertNotNull($client->getCookiejar()->get('REMEMBERME'), 'The REMEMBERME cookie is set');\n        $event = false;\n\n        $client->getCookiejar()->expire('MOCKSESSID');\n\n        $client->request('get', '/');\n        $this->assertEquals('AUTHENTICATED_REMEMBERED', $client->getResponse()->getContent());\n        $this->assertTrue($interactiveLogin->triggered, 'The interactive login has been triggered');\n\n        $client->request('get', '/logout');\n        $client->followRedirect();\n\n        $this->assertNull($client->getCookiejar()->get('REMEMBERME'), 'The REMEMBERME cookie has been removed');\n    }\n\n    public function createApplication($authenticationMethod = 'form')\n    {\n        $app = new Application();\n\n        $app['debug'] = true;\n        unset($app['exception_handler']);\n\n        $app->register(new SessionServiceProvider(), array(\n            'session.test' => true,\n        ));\n        $app->register(new SecurityServiceProvider());\n        $app->register(new RememberMeServiceProvider());\n\n        $app['security.firewalls'] = array(\n            'http-auth' => array(\n                'pattern' => '^.*$',\n                'form' => true,\n                'remember_me' => array(),\n                'logout' => true,\n                'users' => array(\n                    'fabien' => array('ROLE_USER', '$2y$15$lzUNsTegNXvZW3qtfucV0erYBcEqWVeyOmjolB7R1uodsAVJ95vvu'),\n                ),\n            ),\n        );\n\n        $app->get('/', function () use ($app) {\n            if ($app['security.authorization_checker']->isGranted('IS_AUTHENTICATED_FULLY')) {\n                return 'AUTHENTICATED_FULLY';\n            } elseif ($app['security.authorization_checker']->isGranted('IS_AUTHENTICATED_REMEMBERED')) {\n                return 'AUTHENTICATED_REMEMBERED';\n            } else {\n                return 'AUTHENTICATED_ANONYMOUSLY';\n            }\n        });\n\n        return $app;\n    }\n}\n\nclass InteractiveLoginTriggered\n{\n    public $triggered = false;\n\n    public function onInteractiveLogin()\n    {\n        $this->triggered = true;\n    }\n}\n"
  },
  {
    "path": "tests/Silex/Tests/Provider/RoutingServiceProviderTest.php",
    "content": "<?php\n\n/*\n * This file is part of the Silex framework.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * This source file is subject to the MIT license that is bundled\n * with this source code in the file LICENSE.\n */\n\nnamespace Silex\\Tests\\Provider;\n\nuse Pimple\\Container;\nuse Silex\\Application;\nuse Silex\\Provider\\RoutingServiceProvider;\nuse Symfony\\Component\\HttpFoundation\\Request;\nuse Symfony\\Component\\Routing\\Generator\\UrlGeneratorInterface;\n\n/**\n * RoutingProvider test cases.\n *\n * @author Igor Wiedler <igor@wiedler.ch>\n */\nclass RoutingServiceProviderTest extends \\PHPUnit_Framework_TestCase\n{\n    public function testRegister()\n    {\n        $app = new Application();\n\n        $app->get('/hello/{name}', function ($name) {})\n            ->bind('hello');\n\n        $app->get('/', function () {});\n\n        $request = Request::create('/');\n        $app->handle($request);\n\n        $this->assertInstanceOf('Symfony\\Component\\Routing\\Generator\\UrlGenerator', $app['url_generator']);\n    }\n\n    public function testUrlGeneration()\n    {\n        $app = new Application();\n\n        $app->get('/hello/{name}', function ($name) {})\n            ->bind('hello');\n\n        $app->get('/', function () use ($app) {\n            return $app['url_generator']->generate('hello', array('name' => 'john'));\n        });\n\n        $request = Request::create('/');\n        $response = $app->handle($request);\n\n        $this->assertEquals('/hello/john', $response->getContent());\n    }\n\n    public function testAbsoluteUrlGeneration()\n    {\n        $app = new Application();\n\n        $app->get('/hello/{name}', function ($name) {})\n            ->bind('hello');\n\n        $app->get('/', function () use ($app) {\n            return $app['url_generator']->generate('hello', array('name' => 'john'), UrlGeneratorInterface::ABSOLUTE_URL);\n        });\n\n        $request = Request::create('https://localhost:81/');\n        $response = $app->handle($request);\n\n        $this->assertEquals('https://localhost:81/hello/john', $response->getContent());\n    }\n\n    public function testUrlGenerationWithHttp()\n    {\n        $app = new Application();\n\n        $app->get('/insecure', function () {})\n            ->bind('insecure_page')\n            ->requireHttp();\n\n        $app->get('/', function () use ($app) {\n            return $app['url_generator']->generate('insecure_page');\n        });\n\n        $request = Request::create('https://localhost/');\n        $response = $app->handle($request);\n\n        $this->assertEquals('http://localhost/insecure', $response->getContent());\n    }\n\n    public function testUrlGenerationWithHttps()\n    {\n        $app = new Application();\n\n        $app->get('/secure', function () {})\n            ->bind('secure_page')\n            ->requireHttps();\n\n        $app->get('/', function () use ($app) {\n            return $app['url_generator']->generate('secure_page');\n        });\n\n        $request = Request::create('http://localhost/');\n        $response = $app->handle($request);\n\n        $this->assertEquals('https://localhost/secure', $response->getContent());\n    }\n\n    public function testControllersFactory()\n    {\n        $app = new Container();\n        $app->register(new RoutingServiceProvider());\n        $coll = $app['controllers_factory'];\n        $coll->mount('/blog', function ($blog) {\n            $this->assertInstanceOf('Silex\\ControllerCollection', $blog);\n        });\n    }\n}\n"
  },
  {
    "path": "tests/Silex/Tests/Provider/SecurityServiceProviderTest/TokenAuthenticator.php",
    "content": "<?php\n\n/*\n * This file is part of the Silex framework.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * This source file is subject to the MIT license that is bundled\n * with this source code in the file LICENSE.\n */\n\nnamespace Silex\\Tests\\Provider\\SecurityServiceProviderTest;\n\nuse Symfony\\Component\\HttpFoundation\\Request;\nuse Symfony\\Component\\HttpFoundation\\JsonResponse;\nuse Symfony\\Component\\Security\\Core\\User\\UserInterface;\nuse Symfony\\Component\\Security\\Core\\User\\UserProviderInterface;\nuse Symfony\\Component\\Security\\Guard\\AbstractGuardAuthenticator;\nuse Symfony\\Component\\Security\\Core\\Authentication\\Token\\TokenInterface;\nuse Symfony\\Component\\Security\\Core\\Exception\\AuthenticationException;\n\n/**\n * This class is used to test \"guard\" authentication with the SecurityServiceProvider.\n */\nclass TokenAuthenticator extends AbstractGuardAuthenticator\n{\n    public function getCredentials(Request $request)\n    {\n        if (!$token = $request->headers->get('X-AUTH-TOKEN')) {\n            return;\n        }\n\n        list($username, $secret) = explode(':', $token);\n\n        return array(\n            'username' => $username,\n            'secret' => $secret,\n        );\n    }\n\n    public function getUser($credentials, UserProviderInterface $userProvider)\n    {\n        return $userProvider->loadUserByUsername($credentials['username']);\n    }\n\n    public function checkCredentials($credentials, UserInterface $user)\n    {\n        // This is not a safe way of validating a password.\n        return $user->getPassword() === $credentials['secret'];\n    }\n\n    public function onAuthenticationSuccess(Request $request, TokenInterface $token, $providerKey)\n    {\n        return;\n    }\n\n    public function onAuthenticationFailure(Request $request, AuthenticationException $exception)\n    {\n        $data = array(\n            'message' => strtr($exception->getMessageKey(), $exception->getMessageData()),\n        );\n\n        return new JsonResponse($data, 403);\n    }\n\n    public function start(Request $request, AuthenticationException $authException = null)\n    {\n        $data = array(\n            'message' => 'Authentication Required',\n        );\n\n        return new JsonResponse($data, 401);\n    }\n\n    public function supportsRememberMe()\n    {\n        return false;\n    }\n}\n"
  },
  {
    "path": "tests/Silex/Tests/Provider/SecurityServiceProviderTest.php",
    "content": "<?php\n\n/*\n * This file is part of the Silex framework.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * This source file is subject to the MIT license that is bundled\n * with this source code in the file LICENSE.\n */\n\nnamespace Silex\\Tests\\Provider;\n\nuse Silex\\Application;\nuse Silex\\WebTestCase;\nuse Silex\\Provider\\SecurityServiceProvider;\nuse Silex\\Provider\\SessionServiceProvider;\nuse Silex\\Provider\\ValidatorServiceProvider;\nuse Symfony\\Component\\Security\\Core\\Authentication\\Token\\UsernamePasswordToken;\nuse Symfony\\Component\\HttpKernel\\Client;\nuse Symfony\\Component\\HttpFoundation\\Request;\n\n/**\n * SecurityServiceProvider.\n *\n * @author Fabien Potencier <fabien@symfony.com>\n */\nclass SecurityServiceProviderTest extends WebTestCase\n{\n    /**\n     * @expectedException \\LogicException\n     */\n    public function testWrongAuthenticationType()\n    {\n        $app = new Application();\n        $app->register(new SecurityServiceProvider(), array(\n            'security.firewalls' => array(\n                'wrong' => array(\n                    'foobar' => true,\n                    'users' => array(),\n                ),\n            ),\n        ));\n        $app->get('/', function () {});\n        $app->handle(Request::create('/'));\n    }\n\n    public function testFormAuthentication()\n    {\n        $app = $this->createApplication('form');\n\n        $client = new Client($app);\n\n        $client->request('get', '/');\n        $this->assertEquals('ANONYMOUS', $client->getResponse()->getContent());\n\n        $client->request('post', '/login_check', array('_username' => 'fabien', '_password' => 'bar'));\n        $this->assertContains('Bad credentials', $app['security.last_error']($client->getRequest()));\n        // hack to re-close the session as the previous assertions re-opens it\n        $client->getRequest()->getSession()->save();\n\n        $client->request('post', '/login_check', array('_username' => 'fabien', '_password' => 'foo'));\n        $this->assertEquals('', $app['security.last_error']($client->getRequest()));\n        $client->getRequest()->getSession()->save();\n        $this->assertEquals(302, $client->getResponse()->getStatusCode());\n        $this->assertEquals('http://localhost/', $client->getResponse()->getTargetUrl());\n\n        $client->request('get', '/');\n        $this->assertEquals('fabienAUTHENTICATED', $client->getResponse()->getContent());\n        $client->request('get', '/admin');\n        $this->assertEquals(403, $client->getResponse()->getStatusCode());\n\n        $client->request('get', '/logout');\n        $this->assertEquals(302, $client->getResponse()->getStatusCode());\n        $this->assertEquals('http://localhost/', $client->getResponse()->getTargetUrl());\n\n        $client->request('get', '/');\n        $this->assertEquals('ANONYMOUS', $client->getResponse()->getContent());\n\n        $client->request('get', '/admin');\n        $this->assertEquals(302, $client->getResponse()->getStatusCode());\n        $this->assertEquals('http://localhost/login', $client->getResponse()->getTargetUrl());\n\n        $client->request('post', '/login_check', array('_username' => 'admin', '_password' => 'foo'));\n        $this->assertEquals('', $app['security.last_error']($client->getRequest()));\n        $client->getRequest()->getSession()->save();\n        $this->assertEquals(302, $client->getResponse()->getStatusCode());\n        $this->assertEquals('http://localhost/admin', $client->getResponse()->getTargetUrl());\n\n        $client->request('get', '/');\n        $this->assertEquals('adminAUTHENTICATEDADMIN', $client->getResponse()->getContent());\n        $client->request('get', '/admin');\n        $this->assertEquals('admin', $client->getResponse()->getContent());\n    }\n\n    public function testHttpAuthentication()\n    {\n        $app = $this->createApplication('http');\n\n        $client = new Client($app);\n\n        $client->request('get', '/');\n        $this->assertEquals(401, $client->getResponse()->getStatusCode());\n        $this->assertEquals('Basic realm=\"Secured\"', $client->getResponse()->headers->get('www-authenticate'));\n\n        $client->request('get', '/', array(), array(), array('PHP_AUTH_USER' => 'dennis', 'PHP_AUTH_PW' => 'foo'));\n        $this->assertEquals('dennisAUTHENTICATED', $client->getResponse()->getContent());\n        $client->request('get', '/admin');\n        $this->assertEquals(403, $client->getResponse()->getStatusCode());\n\n        $client->restart();\n\n        $client->request('get', '/');\n        $this->assertEquals(401, $client->getResponse()->getStatusCode());\n        $this->assertEquals('Basic realm=\"Secured\"', $client->getResponse()->headers->get('www-authenticate'));\n\n        $client->request('get', '/', array(), array(), array('PHP_AUTH_USER' => 'admin', 'PHP_AUTH_PW' => 'foo'));\n        $this->assertEquals('adminAUTHENTICATEDADMIN', $client->getResponse()->getContent());\n        $client->request('get', '/admin');\n        $this->assertEquals('admin', $client->getResponse()->getContent());\n    }\n\n    public function testGuardAuthentication()\n    {\n        $app = $this->createApplication('guard');\n\n        $client = new Client($app);\n\n        $client->request('get', '/');\n        $this->assertEquals(401, $client->getResponse()->getStatusCode(), 'The entry point is configured');\n        $this->assertEquals('{\"message\":\"Authentication Required\"}', $client->getResponse()->getContent());\n\n        $client->request('get', '/', array(), array(), array('HTTP_X_AUTH_TOKEN' => 'lili:not the secret'));\n        $this->assertEquals(403, $client->getResponse()->getStatusCode(), 'User not found');\n        $this->assertEquals('{\"message\":\"Username could not be found.\"}', $client->getResponse()->getContent());\n\n        $client->request('get', '/', array(), array(), array('HTTP_X_AUTH_TOKEN' => 'victoria:not the secret'));\n        $this->assertEquals(403, $client->getResponse()->getStatusCode(), 'Invalid credentials');\n        $this->assertEquals('{\"message\":\"Invalid credentials.\"}', $client->getResponse()->getContent());\n\n        $client->request('get', '/', array(), array(), array('HTTP_X_AUTH_TOKEN' => 'victoria:victoriasecret'));\n        $this->assertEquals('victoria', $client->getResponse()->getContent());\n    }\n\n    public function testUserPasswordValidatorIsRegistered()\n    {\n        $app = new Application();\n\n        $app->register(new ValidatorServiceProvider());\n        $app->register(new SecurityServiceProvider(), array(\n            'security.firewalls' => array(\n                'admin' => array(\n                    'pattern' => '^/admin',\n                    'http' => true,\n                    'users' => array(\n                        'admin' => array('ROLE_ADMIN', '513aeb0121909'),\n                    ),\n                ),\n            ),\n        ));\n\n        $app->boot();\n\n        $this->assertInstanceOf('Symfony\\Component\\Security\\Core\\Validator\\Constraints\\UserPasswordValidator', $app['security.validator.user_password_validator']);\n    }\n\n    public function testExposedExceptions()\n    {\n        $app = $this->createApplication('form');\n        $app['security.hide_user_not_found'] = false;\n\n        $client = new Client($app);\n\n        $client->request('get', '/');\n        $this->assertEquals('ANONYMOUS', $client->getResponse()->getContent());\n\n        $client->request('post', '/login_check', array('_username' => 'fabien', '_password' => 'bar'));\n        $this->assertEquals('The presented password is invalid.', $app['security.last_error']($client->getRequest()));\n        $client->getRequest()->getSession()->save();\n\n        $client->request('post', '/login_check', array('_username' => 'unknown', '_password' => 'bar'));\n        $this->assertEquals('Username \"unknown\" does not exist.', $app['security.last_error']($client->getRequest()));\n        $client->getRequest()->getSession()->save();\n    }\n\n    public function testFakeRoutesAreSerializable()\n    {\n        $app = new Application();\n\n        $app->register(new SecurityServiceProvider(), array(\n            'security.firewalls' => array(\n                'admin' => array(\n                    'logout' => true,\n                ),\n            ),\n        ));\n\n        $app->boot();\n        $app->flush();\n\n        $this->assertCount(1, unserialize(serialize($app['routes'])));\n    }\n\n    public function testUser()\n    {\n        $app = new Application();\n        $app->register(new SecurityServiceProvider(), array(\n            'security.firewalls' => array(\n                'default' => array(\n                    'http' => true,\n                    'users' => array(\n                        'fabien' => array('ROLE_ADMIN', '$2y$15$lzUNsTegNXvZW3qtfucV0erYBcEqWVeyOmjolB7R1uodsAVJ95vvu'),\n                    ),\n                ),\n            ),\n        ));\n        $app->get('/', function () { return 'foo'; });\n\n        $request = Request::create('/');\n        $app->handle($request);\n        $this->assertNull($app['user']);\n\n        $request->headers->set('PHP_AUTH_USER', 'fabien');\n        $request->headers->set('PHP_AUTH_PW', 'foo');\n        $app->handle($request);\n        $this->assertInstanceOf('Symfony\\Component\\Security\\Core\\User\\UserInterface', $app['user']);\n        $this->assertEquals('fabien', $app['user']->getUsername());\n    }\n\n    public function testUserWithNoToken()\n    {\n        $app = new Application();\n        $app->register(new SecurityServiceProvider(), array(\n            'security.firewalls' => array(\n                'default' => array(\n                    'http' => true,\n                ),\n            ),\n        ));\n\n        $request = Request::create('/');\n\n        $app->get('/', function () { return 'foo'; });\n        $app->handle($request);\n        $this->assertNull($app['user']);\n    }\n\n    public function testUserWithInvalidUser()\n    {\n        $app = new Application();\n        $app->register(new SecurityServiceProvider(), array(\n            'security.firewalls' => array(\n                'default' => array(\n                    'http' => true,\n                ),\n            ),\n        ));\n\n        $request = Request::create('/');\n        $app->boot();\n        $app['security.token_storage']->setToken(new UsernamePasswordToken('foo', 'foo', 'foo'));\n\n        $app->get('/', function () { return 'foo'; });\n        $app->handle($request);\n        $this->assertNull($app['user']);\n    }\n\n    public function testAccessRulePathArray()\n    {\n        $app = new Application();\n        $app->register(new SecurityServiceProvider(), array(\n            'security.firewalls' => array(\n                'default' => array(\n                    'http' => true,\n                ),\n            ),\n            'security.access_rules' => array(\n                array(array(\n                    'path' => '^/admin',\n                ), 'ROLE_ADMIN'),\n            ),\n        ));\n\n        $request = Request::create('/admin');\n        $app->boot();\n        $accessMap = $app['security.access_map'];\n        $this->assertEquals($accessMap->getPatterns($request), array(\n            array('ROLE_ADMIN'),\n            '',\n        ));\n    }\n\n    public function createApplication($authenticationMethod = 'form')\n    {\n        $app = new Application();\n        $app->register(new SessionServiceProvider());\n\n        $app = call_user_func(array($this, 'add'.ucfirst($authenticationMethod).'Authentication'), $app);\n\n        $app['session.test'] = true;\n\n        return $app;\n    }\n\n    private function addFormAuthentication($app)\n    {\n        $app->register(new SecurityServiceProvider(), array(\n            'security.firewalls' => array(\n                'login' => array(\n                    'pattern' => '^/login$',\n                ),\n                'default' => array(\n                    'pattern' => '^.*$',\n                    'anonymous' => true,\n                    'form' => array(\n                        'require_previous_session' => false,\n                    ),\n                    'logout' => true,\n                    'users' => array(\n                        // password is foo\n                        'fabien' => array('ROLE_USER', '$2y$15$lzUNsTegNXvZW3qtfucV0erYBcEqWVeyOmjolB7R1uodsAVJ95vvu'),\n                        'admin' => array('ROLE_ADMIN', '$2y$15$lzUNsTegNXvZW3qtfucV0erYBcEqWVeyOmjolB7R1uodsAVJ95vvu'),\n                    ),\n                ),\n            ),\n            'security.access_rules' => array(\n                array('^/admin', 'ROLE_ADMIN'),\n            ),\n            'security.role_hierarchy' => array(\n                'ROLE_ADMIN' => array('ROLE_USER'),\n            ),\n        ));\n\n        $app->get('/login', function (Request $request) use ($app) {\n            $app['session']->start();\n\n            return $app['security.last_error']($request);\n        });\n\n        $app->get('/', function () use ($app) {\n            $user = $app['security.token_storage']->getToken()->getUser();\n\n            $content = is_object($user) ? $user->getUsername() : 'ANONYMOUS';\n\n            if ($app['security.authorization_checker']->isGranted('IS_AUTHENTICATED_FULLY')) {\n                $content .= 'AUTHENTICATED';\n            }\n\n            if ($app['security.authorization_checker']->isGranted('ROLE_ADMIN')) {\n                $content .= 'ADMIN';\n            }\n\n            return $content;\n        });\n\n        $app->get('/admin', function () use ($app) {\n            return 'admin';\n        });\n\n        return $app;\n    }\n\n    private function addHttpAuthentication($app)\n    {\n        $app->register(new SecurityServiceProvider(), array(\n            'security.firewalls' => array(\n                'http-auth' => array(\n                    'pattern' => '^.*$',\n                    'http' => true,\n                    'users' => array(\n                        // password is foo\n                        'dennis' => array('ROLE_USER', '$2y$15$lzUNsTegNXvZW3qtfucV0erYBcEqWVeyOmjolB7R1uodsAVJ95vvu'),\n                        'admin' => array('ROLE_ADMIN', '$2y$15$lzUNsTegNXvZW3qtfucV0erYBcEqWVeyOmjolB7R1uodsAVJ95vvu'),\n                    ),\n                ),\n            ),\n            'security.access_rules' => array(\n                array('^/admin', 'ROLE_ADMIN'),\n            ),\n            'security.role_hierarchy' => array(\n                'ROLE_ADMIN' => array('ROLE_USER'),\n            ),\n        ));\n\n        $app->get('/', function () use ($app) {\n            $user = $app['security.token_storage']->getToken()->getUser();\n            $content = is_object($user) ? $user->getUsername() : 'ANONYMOUS';\n\n            if ($app['security.authorization_checker']->isGranted('IS_AUTHENTICATED_FULLY')) {\n                $content .= 'AUTHENTICATED';\n            }\n\n            if ($app['security.authorization_checker']->isGranted('ROLE_ADMIN')) {\n                $content .= 'ADMIN';\n            }\n\n            return $content;\n        });\n\n        $app->get('/admin', function () use ($app) {\n            return 'admin';\n        });\n\n        return $app;\n    }\n\n    private function addGuardAuthentication($app)\n    {\n        $app['app.authenticator.token'] = function ($app) {\n            return new SecurityServiceProviderTest\\TokenAuthenticator($app);\n        };\n\n        $app->register(new SecurityServiceProvider(), array(\n            'security.firewalls' => array(\n                'guard' => array(\n                    'pattern' => '^.*$',\n                    'form' => true,\n                    'guard' => array(\n                        'authenticators' => array(\n                            'app.authenticator.token',\n                        ),\n                    ),\n                    'users' => array(\n                        'victoria' => array('ROLE_USER', 'victoriasecret'),\n                    ),\n                ),\n            ),\n        ));\n\n        $app->get('/', function () use ($app) {\n            $user = $app['security.token_storage']->getToken()->getUser();\n\n            $content = is_object($user) ? $user->getUsername() : 'ANONYMOUS';\n\n            return $content;\n        })->bind('homepage');\n\n        return $app;\n    }\n}\n"
  },
  {
    "path": "tests/Silex/Tests/Provider/SerializerServiceProviderTest.php",
    "content": "<?php\n\n/*\n * This file is part of the Silex framework.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * This source file is subject to the MIT license that is bundled\n * with this source code in the file LICENSE.\n */\n\nnamespace Silex\\Tests\\Provider;\n\nuse Silex\\Application;\nuse Silex\\Provider\\SerializerServiceProvider;\n\n/**\n * SerializerServiceProvider test cases.\n *\n * @author Fabien Potencier <fabien@symfony.com>\n */\nclass SerializerServiceProviderTest extends \\PHPUnit_Framework_TestCase\n{\n    public function testRegister()\n    {\n        $app = new Application();\n\n        $app->register(new SerializerServiceProvider());\n\n        $this->assertInstanceOf(\"Symfony\\Component\\Serializer\\Serializer\", $app['serializer']);\n        $this->assertTrue($app['serializer']->supportsEncoding('xml'));\n        $this->assertTrue($app['serializer']->supportsEncoding('json'));\n        $this->assertTrue($app['serializer']->supportsDecoding('xml'));\n        $this->assertTrue($app['serializer']->supportsDecoding('json'));\n    }\n}\n"
  },
  {
    "path": "tests/Silex/Tests/Provider/SessionServiceProviderTest.php",
    "content": "<?php\n\n/*\n * This file is part of the Silex framework.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * This source file is subject to the MIT license that is bundled\n * with this source code in the file LICENSE.\n */\n\nnamespace Silex\\Tests\\Provider;\n\nuse Silex\\Application;\nuse Silex\\WebTestCase;\nuse Silex\\Provider\\SessionServiceProvider;\nuse Symfony\\Component\\HttpKernel\\Client;\nuse Symfony\\Component\\HttpFoundation\\Session;\n\n/**\n * SessionProvider test cases.\n *\n * @author Igor Wiedler <igor@wiedler.ch>\n * @author Fabien Potencier <fabien@symfony.com>\n */\nclass SessionServiceProviderTest extends WebTestCase\n{\n    public function testRegister()\n    {\n        /*\n         * Smoke test\n         */\n        $defaultStorage = $this->app['session.storage.native'];\n\n        $client = $this->createClient();\n\n        $client->request('get', '/login');\n        $this->assertEquals('Logged in successfully.', $client->getResponse()->getContent());\n\n        $client->request('get', '/account');\n        $this->assertEquals('This is your account.', $client->getResponse()->getContent());\n\n        $client->request('get', '/logout');\n        $this->assertEquals('Logged out successfully.', $client->getResponse()->getContent());\n\n        $client->request('get', '/account');\n        $this->assertEquals('You are not logged in.', $client->getResponse()->getContent());\n    }\n\n    public function createApplication()\n    {\n        $app = new Application();\n\n        $app->register(new SessionServiceProvider(), array(\n            'session.test' => true,\n        ));\n\n        $app->get('/login', function () use ($app) {\n            $app['session']->set('logged_in', true);\n\n            return 'Logged in successfully.';\n        });\n\n        $app->get('/account', function () use ($app) {\n            if (!$app['session']->get('logged_in')) {\n                return 'You are not logged in.';\n            }\n\n            return 'This is your account.';\n        });\n\n        $app->get('/logout', function () use ($app) {\n            $app['session']->invalidate();\n\n            return 'Logged out successfully.';\n        });\n\n        return $app;\n    }\n\n    public function testWithRoutesThatDoesNotUseSession()\n    {\n        $app = new Application();\n\n        $app->register(new SessionServiceProvider(), array(\n            'session.test' => true,\n        ));\n\n        $app->get('/', function () {\n            return 'A welcome page.';\n        });\n\n        $app->get('/robots.txt', function () {\n            return 'Informations for robots.';\n        });\n\n        $app['debug'] = true;\n        unset($app['exception_handler']);\n\n        $client = new Client($app);\n\n        $client->request('get', '/');\n        $this->assertEquals('A welcome page.', $client->getResponse()->getContent());\n\n        $client->request('get', '/robots.txt');\n        $this->assertEquals('Informations for robots.', $client->getResponse()->getContent());\n    }\n\n    public function testSessionRegister()\n    {\n        $app = new Application();\n\n        $attrs = new Session\\Attribute\\AttributeBag();\n        $flash = new Session\\Flash\\FlashBag();\n        $app->register(new SessionServiceProvider(), array(\n            'session.attribute_bag' => $attrs,\n            'session.flash_bag' => $flash,\n            'session.test' => true,\n        ));\n\n        $session = $app['session'];\n\n        $this->assertSame($flash, $session->getBag('flashes'));\n        $this->assertSame($attrs, $session->getBag('attributes'));\n    }\n}\n"
  },
  {
    "path": "tests/Silex/Tests/Provider/SpoolStub.php",
    "content": "<?php\n\n/*\n * This file is part of the Silex framework.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * This source file is subject to the MIT license that is bundled\n * with this source code in the file LICENSE.\n */\n\nnamespace Silex\\Tests\\Provider;\n\nclass SpoolStub implements \\Swift_Spool\n{\n    private $messages = array();\n    public $hasFlushed = false;\n\n    public function getMessages()\n    {\n        return $this->messages;\n    }\n\n    public function start()\n    {\n    }\n\n    public function stop()\n    {\n    }\n\n    public function isStarted()\n    {\n        return count($this->messages) > 0;\n    }\n\n    public function queueMessage(\\Swift_Mime_Message $message)\n    {\n        $this->messages[] = $message;\n    }\n\n    public function flushQueue(\\Swift_Transport $transport, &$failedRecipients = null)\n    {\n        $this->hasFlushed = true;\n        $this->messages = array();\n    }\n}\n"
  },
  {
    "path": "tests/Silex/Tests/Provider/SwiftmailerServiceProviderTest.php",
    "content": "<?php\n\n/*\n * This file is part of the Silex framework.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * This source file is subject to the MIT license that is bundled\n * with this source code in the file LICENSE.\n */\n\nnamespace Silex\\Tests\\Provider;\n\nuse Silex\\Application;\nuse Silex\\Provider\\SwiftmailerServiceProvider;\nuse Symfony\\Component\\HttpFoundation\\Request;\n\nclass SwiftmailerServiceProviderTest extends \\PHPUnit_Framework_TestCase\n{\n    public function testSwiftMailerServiceIsSwiftMailer()\n    {\n        $app = new Application();\n\n        $app->register(new SwiftmailerServiceProvider());\n        $app->boot();\n\n        $this->assertInstanceOf('Swift_Mailer', $app['mailer']);\n    }\n\n    public function testSwiftMailerIgnoresSpoolIfDisabled()\n    {\n        $app = new Application();\n\n        $app->register(new SwiftmailerServiceProvider());\n        $app->boot();\n\n        $app['swiftmailer.use_spool'] = false;\n\n        $app['swiftmailer.spooltransport'] = function () {\n            throw new \\Exception('Should not be instantiated');\n        };\n\n        $this->assertInstanceOf('Swift_Mailer', $app['mailer']);\n    }\n\n    public function testSwiftMailerSendsMailsOnFinish()\n    {\n        $app = new Application();\n\n        $app->register(new SwiftmailerServiceProvider());\n        $app->boot();\n\n        $app['swiftmailer.spool'] = function () {\n            return new SpoolStub();\n        };\n\n        $app->get('/', function () use ($app) {\n            $app['mailer']->send(\\Swift_Message::newInstance());\n        });\n\n        $this->assertCount(0, $app['swiftmailer.spool']->getMessages());\n\n        $request = Request::create('/');\n        $response = $app->handle($request);\n        $this->assertCount(1, $app['swiftmailer.spool']->getMessages());\n\n        $app->terminate($request, $response);\n        $this->assertTrue($app['swiftmailer.spool']->hasFlushed);\n        $this->assertCount(0, $app['swiftmailer.spool']->getMessages());\n    }\n\n    public function testSwiftMailerAvoidsFlushesIfMailerIsUnused()\n    {\n        $app = new Application();\n\n        $app->register(new SwiftmailerServiceProvider());\n        $app->boot();\n\n        $app['swiftmailer.spool'] = function () {\n            return new SpoolStub();\n        };\n\n        $app->get('/', function () use ($app) { });\n\n        $request = Request::create('/');\n        $response = $app->handle($request);\n        $this->assertCount(0, $app['swiftmailer.spool']->getMessages());\n\n        $app->terminate($request, $response);\n        $this->assertFalse($app['swiftmailer.spool']->hasFlushed);\n    }\n}\n"
  },
  {
    "path": "tests/Silex/Tests/Provider/TranslationServiceProviderTest.php",
    "content": "<?php\n\n/*\n * This file is part of the Silex framework.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * This source file is subject to the MIT license that is bundled\n * with this source code in the file LICENSE.\n */\n\nnamespace Silex\\Tests\\Provider;\n\nuse Silex\\Application;\nuse Silex\\Provider\\TranslationServiceProvider;\nuse Silex\\Provider\\LocaleServiceProvider;\nuse Symfony\\Component\\HttpFoundation\\Request;\nuse Symfony\\Component\\HttpKernel\\HttpKernelInterface;\n\n/**\n * TranslationProvider test cases.\n *\n * @author Daniel Tschinder <daniel@tschinder.de>\n */\nclass TranslationServiceProviderTest extends \\PHPUnit_Framework_TestCase\n{\n    /**\n     * @return Application\n     */\n    protected function getPreparedApp()\n    {\n        $app = new Application();\n\n        $app->register(new LocaleServiceProvider());\n        $app->register(new TranslationServiceProvider());\n        $app['translator.domains'] = array(\n            'messages' => array(\n                'en' => array(\n                    'key1' => 'The translation',\n                    'key_only_english' => 'Foo',\n                    'key2' => 'One apple|%count% apples',\n                    'test' => array(\n                        'key' => 'It works',\n                    ),\n                ),\n                'de' => array(\n                    'key1' => 'The german translation',\n                    'key2' => 'One german apple|%count% german apples',\n                    'test' => array(\n                        'key' => 'It works in german',\n                    ),\n                ),\n            ),\n        );\n\n        return $app;\n    }\n\n    public function transChoiceProvider()\n    {\n        return array(\n            array('key2', 0, null, '0 apples'),\n            array('key2', 1, null, 'One apple'),\n            array('key2', 2, null, '2 apples'),\n            array('key2', 0, 'de', '0 german apples'),\n            array('key2', 1, 'de', 'One german apple'),\n            array('key2', 2, 'de', '2 german apples'),\n            array('key2', 0, 'ru', '0 apples'), // fallback\n            array('key2', 1, 'ru', 'One apple'), // fallback\n            array('key2', 2, 'ru', '2 apples'), // fallback\n        );\n    }\n\n    public function transProvider()\n    {\n        return array(\n            array('key1', null, 'The translation'),\n            array('key1', 'de', 'The german translation'),\n            array('key1', 'ru', 'The translation'), // fallback\n            array('test.key', null, 'It works'),\n            array('test.key', 'de', 'It works in german'),\n            array('test.key', 'ru', 'It works'), // fallback\n        );\n    }\n\n    /**\n     * @dataProvider transProvider\n     */\n    public function testTransForDefaultLanguage($key, $locale, $expected)\n    {\n        $app = $this->getPreparedApp();\n\n        $result = $app['translator']->trans($key, array(), null, $locale);\n\n        $this->assertEquals($expected, $result);\n    }\n\n    /**\n     * @dataProvider transChoiceProvider\n     */\n    public function testTransChoiceForDefaultLanguage($key, $number, $locale, $expected)\n    {\n        $app = $this->getPreparedApp();\n\n        $result = $app['translator']->transChoice($key, $number, array('%count%' => $number), null, $locale);\n        $this->assertEquals($expected, $result);\n    }\n\n    public function testFallbacks()\n    {\n        $app = $this->getPreparedApp();\n        $app['locale_fallbacks'] = array('de', 'en');\n\n        // fallback to english\n        $result = $app['translator']->trans('key_only_english', array(), null, 'ru');\n        $this->assertEquals('Foo', $result);\n\n        // fallback to german\n        $result = $app['translator']->trans('key1', array(), null, 'ru');\n        $this->assertEquals('The german translation', $result);\n    }\n\n    public function testLocale()\n    {\n        $app = $this->getPreparedApp();\n        $app->get('/', function () use ($app) { return $app['translator']->getLocale(); });\n        $response = $app->handle(Request::create('/'));\n        $this->assertEquals('en', $response->getContent());\n\n        $app = $this->getPreparedApp();\n        $app->get('/', function () use ($app) { return $app['translator']->getLocale(); });\n        $request = Request::create('/');\n        $request->setLocale('fr');\n        $response = $app->handle($request);\n        $this->assertEquals('fr', $response->getContent());\n\n        $app = $this->getPreparedApp();\n        $app->get('/{_locale}', function () use ($app) { return $app['translator']->getLocale(); });\n        $response = $app->handle(Request::create('/es'));\n        $this->assertEquals('es', $response->getContent());\n    }\n\n    public function testLocaleInSubRequests()\n    {\n        $app = $this->getPreparedApp();\n        $app->get('/embed/{_locale}', function () use ($app) { return $app['translator']->getLocale(); });\n        $app->get('/{_locale}', function () use ($app) {\n            return $app['translator']->getLocale().\n                   $app->handle(Request::create('/embed/es'), HttpKernelInterface::SUB_REQUEST)->getContent().\n                   $app['translator']->getLocale();\n        });\n        $response = $app->handle(Request::create('/fr'));\n        $this->assertEquals('fresfr', $response->getContent());\n\n        $app = $this->getPreparedApp();\n        $app->get('/embed', function () use ($app) { return $app['translator']->getLocale(); });\n        $app->get('/{_locale}', function () use ($app) {\n            return $app['translator']->getLocale().\n                   $app->handle(Request::create('/embed'), HttpKernelInterface::SUB_REQUEST)->getContent().\n                   $app['translator']->getLocale();\n        });\n        $response = $app->handle(Request::create('/fr'));\n        // locale in sub-request must be \"en\" as this is the value if the sub-request is converted to an ESI\n        $this->assertEquals('frenfr', $response->getContent());\n    }\n\n    public function testLocaleWithBefore()\n    {\n        $app = $this->getPreparedApp();\n        $app->before(function (Request $request) { $request->setLocale('fr'); }, Application::EARLY_EVENT);\n        $app->get('/embed', function () use ($app) { return $app['translator']->getLocale(); });\n        $app->get('/', function () use ($app) {\n            return $app['translator']->getLocale().\n                $app->handle(Request::create('/embed'), HttpKernelInterface::SUB_REQUEST)->getContent().\n                $app['translator']->getLocale();\n        });\n        $response = $app->handle(Request::create('/'));\n        // locale in sub-request is \"en\" as the before filter is only executed for the main request\n        $this->assertEquals('frenfr', $response->getContent());\n    }\n}\n"
  },
  {
    "path": "tests/Silex/Tests/Provider/TwigServiceProviderTest.php",
    "content": "<?php\n\n/*\n * This file is part of the Silex framework.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * This source file is subject to the MIT license that is bundled\n * with this source code in the file LICENSE.\n */\n\nnamespace Silex\\Tests\\Provider;\n\nuse Silex\\Application;\nuse Silex\\Provider\\CsrfServiceProvider;\nuse Silex\\Provider\\FormServiceProvider;\nuse Silex\\Provider\\TwigServiceProvider;\nuse Silex\\Provider\\AssetServiceProvider;\nuse Symfony\\Component\\HttpFoundation\\Request;\n\n/**\n * TwigProvider test cases.\n *\n * @author Igor Wiedler <igor@wiedler.ch>\n */\nclass TwigServiceProviderTest extends \\PHPUnit_Framework_TestCase\n{\n    public function testRegisterAndRender()\n    {\n        $app = new Application();\n\n        $app->register(new TwigServiceProvider(), array(\n            'twig.templates' => array('hello' => 'Hello {{ name }}!'),\n        ));\n\n        $app->get('/hello/{name}', function ($name) use ($app) {\n            return $app['twig']->render('hello', array('name' => $name));\n        });\n\n        $request = Request::create('/hello/john');\n        $response = $app->handle($request);\n        $this->assertEquals('Hello john!', $response->getContent());\n    }\n\n    public function testLoaderPriority()\n    {\n        $app = new Application();\n        $app->register(new TwigServiceProvider(), array(\n            'twig.templates' => array('foo' => 'foo'),\n        ));\n        $loader = $this->getMockBuilder('\\Twig_LoaderInterface')->getMock();\n        $loader->expects($this->never())->method('getSource');\n        $app['twig.loader.filesystem'] = function ($app) use ($loader) {\n            return $loader;\n        };\n        $this->assertEquals('foo', $app['twig.loader']->getSource('foo'));\n    }\n\n    public function testHttpFoundationIntegration()\n    {\n        $app = new Application();\n        $app['request_stack']->push(Request::create('/dir1/dir2/file'));\n        $app->register(new TwigServiceProvider(), array(\n            'twig.templates' => array(\n                'absolute' => '{{ absolute_url(\"foo.css\") }}',\n                'relative' => '{{ relative_path(\"/dir1/foo.css\") }}',\n            ),\n        ));\n\n        $this->assertEquals('http://localhost/dir1/dir2/foo.css', $app['twig']->render('absolute'));\n        $this->assertEquals('../foo.css', $app['twig']->render('relative'));\n    }\n\n    public function testAssetIntegration()\n    {\n        $app = new Application();\n        $app->register(new TwigServiceProvider(), array(\n            'twig.templates' => array('hello' => '{{ asset(\"/foo.css\") }}'),\n        ));\n        $app->register(new AssetServiceProvider(), array(\n            'assets.version' => 1,\n        ));\n\n        $this->assertEquals('/foo.css?1', $app['twig']->render('hello'));\n    }\n\n    public function testGlobalVariable()\n    {\n        $app = new Application();\n        $app['request_stack']->push(Request::create('/?name=Fabien'));\n\n        $app->register(new TwigServiceProvider(), array(\n            'twig.templates' => array('hello' => '{{ global.request.get(\"name\") }}'),\n        ));\n\n        $this->assertEquals('Fabien', $app['twig']->render('hello'));\n    }\n\n    public function testFormFactory()\n    {\n        $app = new Application();\n        $app->register(new FormServiceProvider());\n        $app->register(new CsrfServiceProvider());\n        $app->register(new TwigServiceProvider());\n\n        $this->assertInstanceOf('Twig_Environment', $app['twig'], 'Service twig is created successful.');\n        $this->assertInstanceOf('Symfony\\Bridge\\Twig\\Form\\TwigRendererEngine', $app['twig.form.engine'], 'Service twig.form.engine is created successful.');\n        $this->assertInstanceOf('Symfony\\Bridge\\Twig\\Form\\TwigRenderer', $app['twig.form.renderer'], 'Service twig.form.renderer is created successful.');\n    }\n\n    public function testFormWithoutCsrf()\n    {\n        $app = new Application();\n        $app->register(new FormServiceProvider());\n        $app->register(new TwigServiceProvider());\n\n        $this->assertInstanceOf('Twig_Environment', $app['twig']);\n    }\n}\n"
  },
  {
    "path": "tests/Silex/Tests/Provider/ValidatorServiceProviderTest/Constraint/Custom.php",
    "content": "<?php\n\n/*\n * This file is part of the Silex framework.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * This source file is subject to the MIT license that is bundled\n * with this source code in the file LICENSE.\n */\n\nnamespace Silex\\Tests\\Provider\\ValidatorServiceProviderTest\\Constraint;\n\nuse Symfony\\Component\\Validator\\Constraint;\n\n/**\n * @author Alex Kalyvitis <alex.kalyvitis@gmail.com>\n */\nclass Custom extends Constraint\n{\n    public $message = 'This field must be ...';\n    public $table;\n    public $field;\n\n    public function validatedBy()\n    {\n        return 'test.custom.validator';\n    }\n}\n"
  },
  {
    "path": "tests/Silex/Tests/Provider/ValidatorServiceProviderTest/Constraint/CustomValidator.php",
    "content": "<?php\n\n/*\n * This file is part of the Silex framework.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * This source file is subject to the MIT license that is bundled\n * with this source code in the file LICENSE.\n */\n\nnamespace Silex\\Tests\\Provider\\ValidatorServiceProviderTest\\Constraint;\n\nuse Symfony\\Component\\Validator\\Constraint;\nuse Symfony\\Component\\Validator\\ConstraintValidator;\n\n/**\n * @author Alex Kalyvitis <alex.kalyvitis@gmail.com>\n */\nclass CustomValidator extends ConstraintValidator\n{\n    public function isValid($value, Constraint $constraint)\n    {\n        // Validate...\n        return true;\n    }\n\n    public function validate($value, Constraint $constraint)\n    {\n        return $this->isValid($value, $constraint);\n    }\n}\n"
  },
  {
    "path": "tests/Silex/Tests/Provider/ValidatorServiceProviderTest.php",
    "content": "<?php\n\n/*\n * This file is part of the Silex framework.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * This source file is subject to the MIT license that is bundled\n * with this source code in the file LICENSE.\n */\n\nnamespace Silex\\Tests\\Provider;\n\nuse Silex\\Application;\nuse Silex\\Provider\\TranslationServiceProvider;\nuse Silex\\Provider\\ValidatorServiceProvider;\nuse Silex\\Provider\\FormServiceProvider;\nuse Symfony\\Component\\Translation\\Exception\\NotFoundResourceException;\nuse Symfony\\Component\\Validator\\Constraints as Assert;\nuse Silex\\Tests\\Provider\\ValidatorServiceProviderTest\\Constraint\\Custom;\nuse Silex\\Tests\\Provider\\ValidatorServiceProviderTest\\Constraint\\CustomValidator;\nuse Symfony\\Component\\Validator\\ValidatorInterface as LegacyValidatorInterface;\nuse Symfony\\Component\\Validator\\Validator\\ValidatorInterface;\n\n/**\n * ValidatorServiceProvider.\n *\n * Javier Lopez <f12loalf@gmail.com>\n */\nclass ValidatorServiceProviderTest extends \\PHPUnit_Framework_TestCase\n{\n    public function testRegister()\n    {\n        $app = new Application();\n        $app->register(new ValidatorServiceProvider());\n        $app->register(new FormServiceProvider());\n\n        return $app;\n    }\n\n    public function testRegisterWithCustomValidators()\n    {\n        $app = new Application();\n\n        $app['custom.validator'] = function () {\n            return new CustomValidator();\n        };\n\n        $app->register(new ValidatorServiceProvider(), array(\n            'validator.validator_service_ids' => array(\n                'test.custom.validator' => 'custom.validator',\n            ),\n        ));\n\n        return $app;\n    }\n\n    /**\n     * @depends testRegisterWithCustomValidators\n     */\n    public function testConstraintValidatorFactory($app)\n    {\n        $this->assertInstanceOf('Silex\\Provider\\Validator\\ConstraintValidatorFactory', $app['validator.validator_factory']);\n\n        $validator = $app['validator.validator_factory']->getInstance(new Custom());\n        $this->assertInstanceOf('Silex\\Tests\\Provider\\ValidatorServiceProviderTest\\Constraint\\CustomValidator', $validator);\n    }\n\n    /**\n     * @depends testRegister\n     */\n    public function testConstraintValidatorFactoryWithExpression($app)\n    {\n        $constraint = new Assert\\Expression('true');\n        $validator = $app['validator.validator_factory']->getInstance($constraint);\n        $this->assertInstanceOf('Symfony\\Component\\Validator\\Constraints\\ExpressionValidator', $validator);\n    }\n\n    /**\n     * @depends testRegister\n     */\n    public function testValidatorServiceIsAValidator($app)\n    {\n        $this->assertTrue($app['validator'] instanceof ValidatorInterface || $app['validator'] instanceof LegacyValidatorInterface );\n    }\n\n    /**\n     * @depends testRegister\n     * @dataProvider getTestValidatorConstraintProvider\n     */\n    public function testValidatorConstraint($email, $isValid, $nbGlobalError, $nbEmailError, $app)\n    {\n        $constraints = new Assert\\Collection(array(\n            'email' => array(\n                new Assert\\NotBlank(),\n                new Assert\\Email(),\n            ),\n        ));\n\n        $builder = $app['form.factory']->createBuilder('Symfony\\Component\\Form\\Extension\\Core\\Type\\FormType', array(), array(\n            'constraints' => $constraints,\n        ));\n\n        $form = $builder\n            ->add('email', 'Symfony\\Component\\Form\\Extension\\Core\\Type\\EmailType', array('label' => 'Email'))\n            ->getForm()\n        ;\n\n        $form->submit(array('email' => $email));\n\n        $this->assertEquals($isValid, $form->isValid());\n        $this->assertEquals($nbGlobalError, count($form->getErrors()));\n        $this->assertEquals($nbEmailError, count($form->offsetGet('email')->getErrors()));\n    }\n\n    public function testValidatorWillNotAddNonexistentTranslationFiles()\n    {\n        $app = new Application(array(\n            'locale' => 'nonexistent',\n        ));\n\n        $app->register(new ValidatorServiceProvider());\n        $app->register(new TranslationServiceProvider(), array(\n            'locale_fallbacks' => array(),\n        ));\n\n        $app['validator'];\n        $translator = $app['translator'];\n\n        try {\n            $translator->trans('test');\n        } catch (NotFoundResourceException $e) {\n            $this->fail('Validator should not add a translation resource that does not exist');\n        }\n    }\n\n    public function getTestValidatorConstraintProvider()\n    {\n        // Email, form is valid, nb global error, nb email error\n        return array(\n            array('', false, 0, 1),\n            array('not an email', false, 0, 1),\n            array('email@sample.com', true, 0, 0),\n        );\n    }\n\n    /**\n     * @dataProvider getAddResourceData\n     */\n    public function testAddResource($registerValidatorFirst)\n    {\n        $app = new Application();\n        $app['locale'] = 'fr';\n\n        $app->register(new ValidatorServiceProvider());\n        $app->register(new TranslationServiceProvider());\n        $app['translator'] = $app->extend('translator', function ($translator, $app) {\n            $translator->addResource('array', array('This value should not be blank.' => 'Pas vide'), 'fr', 'validators');\n\n            return $translator;\n        });\n\n        if ($registerValidatorFirst) {\n            $app['validator'];\n        }\n\n        $this->assertEquals('Pas vide', $app['translator']->trans('This value should not be blank.', array(), 'validators', 'fr'));\n    }\n\n    public function getAddResourceData()\n    {\n        return array(array(false), array(true));\n    }\n\n    public function testAddResourceAlternate()\n    {\n        $app = new Application();\n        $app['locale'] = 'fr';\n\n        $app->register(new ValidatorServiceProvider());\n        $app->register(new TranslationServiceProvider());\n        $app->factory($app->extend('translator.resources', function ($resources, $app) {\n            $resources = array_merge($resources, array(\n                array('array', array('This value should not be blank.' => 'Pas vide'), 'fr', 'validators'),\n            ));\n\n            return $resources;\n        }));\n\n        $app['validator'];\n\n        $this->assertEquals('Pas vide', $app['translator']->trans('This value should not be blank.', array(), 'validators', 'fr'));\n    }\n}\n"
  },
  {
    "path": "tests/Silex/Tests/Route/SecurityRoute.php",
    "content": "<?php\n\n/*\n * This file is part of the Silex framework.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * This source file is subject to the MIT license that is bundled\n * with this source code in the file LICENSE.\n */\n\nnamespace Silex\\Tests\\Route;\n\nuse Silex\\Route;\n\nclass SecurityRoute extends Route\n{\n    use Route\\SecurityTrait;\n}\n"
  },
  {
    "path": "tests/Silex/Tests/Route/SecurityTraitTest.php",
    "content": "<?php\n\n/*\n * This file is part of the Silex framework.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * This source file is subject to the MIT license that is bundled\n * with this source code in the file LICENSE.\n */\n\nnamespace Silex\\Tests\\Route;\n\nuse Silex\\Application;\nuse Silex\\Provider\\SecurityServiceProvider;\nuse Symfony\\Component\\HttpFoundation\\Request;\n\n/**\n * SecurityTrait test cases.\n *\n * @author Fabien Potencier <fabien@symfony.com>\n */\nclass SecurityTraitTest extends \\PHPUnit_Framework_TestCase\n{\n    public function testSecureWithNoAuthenticatedUser()\n    {\n        $app = $this->createApplication();\n\n        $app->get('/', function () { return 'foo'; })\n            ->secure('ROLE_ADMIN')\n        ;\n\n        $request = Request::create('/');\n        $response = $app->handle($request);\n        $this->assertEquals(401, $response->getStatusCode());\n    }\n\n    public function testSecureWithAuthorizedRoles()\n    {\n        $app = $this->createApplication();\n\n        $app->get('/', function () { return 'foo'; })\n            ->secure('ROLE_ADMIN')\n        ;\n\n        $request = Request::create('/');\n        $request->headers->set('PHP_AUTH_USER', 'fabien');\n        $request->headers->set('PHP_AUTH_PW', 'foo');\n        $response = $app->handle($request);\n        $this->assertEquals(200, $response->getStatusCode());\n    }\n\n    public function testSecureWithUnauthorizedRoles()\n    {\n        $app = $this->createApplication();\n\n        $app->get('/', function () { return 'foo'; })\n            ->secure('ROLE_SUPER_ADMIN')\n        ;\n\n        $request = Request::create('/');\n        $request->headers->set('PHP_AUTH_USER', 'fabien');\n        $request->headers->set('PHP_AUTH_PW', 'foo');\n        $response = $app->handle($request);\n        $this->assertEquals(403, $response->getStatusCode());\n    }\n\n    private function createApplication()\n    {\n        $app = new Application();\n        $app['route_class'] = 'Silex\\Tests\\Route\\SecurityRoute';\n        $app->register(new SecurityServiceProvider(), array(\n            'security.firewalls' => array(\n                'default' => array(\n                    'http' => true,\n                    'users' => array(\n                        'fabien' => array('ROLE_ADMIN', '$2y$15$lzUNsTegNXvZW3qtfucV0erYBcEqWVeyOmjolB7R1uodsAVJ95vvu'),\n                    ),\n                ),\n            ),\n        ));\n\n        return $app;\n    }\n}\n"
  },
  {
    "path": "tests/Silex/Tests/RouterTest.php",
    "content": "<?php\n\n/*\n * This file is part of the Silex framework.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * This source file is subject to the MIT license that is bundled\n * with this source code in the file LICENSE.\n */\n\nnamespace Silex\\Tests;\n\nuse Silex\\Application;\nuse Symfony\\Component\\HttpFoundation\\Request;\nuse Symfony\\Component\\HttpFoundation\\Response;\nuse Symfony\\Component\\HttpFoundation\\RedirectResponse;\n\n/**\n * Router test cases.\n *\n * @author Igor Wiedler <igor@wiedler.ch>\n */\nclass RouterTest extends \\PHPUnit_Framework_TestCase\n{\n    public function testMapRouting()\n    {\n        $app = new Application();\n\n        $app->match('/foo', function () {\n            return 'foo';\n        });\n\n        $app->match('/bar', function () {\n            return 'bar';\n        });\n\n        $app->match('/', function () {\n            return 'root';\n        });\n\n        $this->checkRouteResponse($app, '/foo', 'foo');\n        $this->checkRouteResponse($app, '/bar', 'bar');\n        $this->checkRouteResponse($app, '/', 'root');\n    }\n\n    public function testStatusCode()\n    {\n        $app = new Application();\n\n        $app->put('/created', function () {\n            return new Response('', 201);\n        });\n\n        $app->match('/forbidden', function () {\n            return new Response('', 403);\n        });\n\n        $app->match('/not_found', function () {\n            return new Response('', 404);\n        });\n\n        $request = Request::create('/created', 'put');\n        $response = $app->handle($request);\n        $this->assertEquals(201, $response->getStatusCode());\n\n        $request = Request::create('/forbidden');\n        $response = $app->handle($request);\n        $this->assertEquals(403, $response->getStatusCode());\n\n        $request = Request::create('/not_found');\n        $response = $app->handle($request);\n        $this->assertEquals(404, $response->getStatusCode());\n    }\n\n    public function testRedirect()\n    {\n        $app = new Application();\n\n        $app->match('/redirect', function () {\n            return new RedirectResponse('/target');\n        });\n\n        $app->match('/redirect2', function () use ($app) {\n            return $app->redirect('/target2');\n        });\n\n        $request = Request::create('/redirect');\n        $response = $app->handle($request);\n        $this->assertTrue($response->isRedirect('/target'));\n\n        $request = Request::create('/redirect2');\n        $response = $app->handle($request);\n        $this->assertTrue($response->isRedirect('/target2'));\n    }\n\n    /**\n     * @expectedException \\Symfony\\Component\\HttpKernel\\Exception\\NotFoundHttpException\n     */\n    public function testMissingRoute()\n    {\n        $app = new Application();\n        unset($app['exception_handler']);\n\n        $request = Request::create('/baz');\n        $app->handle($request);\n    }\n\n    public function testMethodRouting()\n    {\n        $app = new Application();\n\n        $app->match('/foo', function () {\n            return 'foo';\n        });\n\n        $app->match('/bar', function () {\n            return 'bar';\n        })->method('GET|POST');\n\n        $app->get('/resource', function () {\n            return 'get resource';\n        });\n\n        $app->post('/resource', function () {\n            return 'post resource';\n        });\n\n        $app->put('/resource', function () {\n            return 'put resource';\n        });\n\n        $app->patch('/resource', function () {\n            return 'patch resource';\n        });\n\n        $app->delete('/resource', function () {\n            return 'delete resource';\n        });\n\n        $this->checkRouteResponse($app, '/foo', 'foo');\n        $this->checkRouteResponse($app, '/bar', 'bar');\n        $this->checkRouteResponse($app, '/bar', 'bar', 'post');\n        $this->checkRouteResponse($app, '/resource', 'get resource');\n        $this->checkRouteResponse($app, '/resource', 'post resource', 'post');\n        $this->checkRouteResponse($app, '/resource', 'put resource', 'put');\n        $this->checkRouteResponse($app, '/resource', 'patch resource', 'patch');\n        $this->checkRouteResponse($app, '/resource', 'delete resource', 'delete');\n    }\n\n    public function testRequestShouldBeStoredRegardlessOfRouting()\n    {\n        $app = new Application();\n\n        $app->get('/foo', function (Request $request) use ($app) {\n            return new Response($request->getRequestUri());\n        });\n\n        $app->error(function ($e, Request $request, $code) use ($app) {\n            return new Response($request->getRequestUri());\n        });\n\n        foreach (array('/foo', '/bar') as $path) {\n            $request = Request::create($path);\n            $response = $app->handle($request);\n            $this->assertContains($path, $response->getContent());\n        }\n    }\n\n    public function testTrailingSlashBehavior()\n    {\n        $app = new Application();\n\n        $app->get('/foo/', function () use ($app) {\n            return new Response('ok');\n        });\n\n        $request = Request::create('/foo');\n        $response = $app->handle($request);\n\n        $this->assertEquals(301, $response->getStatusCode());\n        $this->assertEquals('/foo/', $response->getTargetUrl());\n    }\n\n    public function testHostSpecification()\n    {\n        $route = new \\Silex\\Route();\n\n        $this->assertSame($route, $route->host('{locale}.example.com'));\n        $this->assertEquals('{locale}.example.com', $route->getHost());\n    }\n\n    public function testRequireHttpRedirect()\n    {\n        $app = new Application();\n\n        $app->match('/secured', function () {\n            return 'secured content';\n        })\n        ->requireHttp();\n\n        $request = Request::create('https://example.com/secured');\n        $response = $app->handle($request);\n        $this->assertTrue($response->isRedirect('http://example.com/secured'));\n    }\n\n    public function testRequireHttpsRedirect()\n    {\n        $app = new Application();\n\n        $app->match('/secured', function () {\n            return 'secured content';\n        })\n        ->requireHttps();\n\n        $request = Request::create('http://example.com/secured');\n        $response = $app->handle($request);\n        $this->assertTrue($response->isRedirect('https://example.com/secured'));\n    }\n\n    public function testRequireHttpsRedirectIncludesQueryString()\n    {\n        $app = new Application();\n\n        $app->match('/secured', function () {\n            return 'secured content';\n        })\n        ->requireHttps();\n\n        $request = Request::create('http://example.com/secured?query=string');\n        $response = $app->handle($request);\n        $this->assertTrue($response->isRedirect('https://example.com/secured?query=string'));\n    }\n\n    public function testConditionOnRoute()\n    {\n        $app = new Application();\n        $app->match('/secured', function () {\n            return 'secured content';\n        })\n        ->when('request.isSecure() == true');\n\n        $request = Request::create('http://example.com/secured');\n        $response = $app->handle($request);\n        $this->assertEquals(404, $response->getStatusCode());\n    }\n\n    public function testClassNameControllerSyntax()\n    {\n        $app = new Application();\n\n        $app->get('/foo', 'Silex\\Tests\\MyController::getFoo');\n\n        $this->checkRouteResponse($app, '/foo', 'foo');\n    }\n\n    public function testClassNameControllerSyntaxWithStaticMethod()\n    {\n        $app = new Application();\n\n        $app->get('/bar', 'Silex\\Tests\\MyController::getBar');\n\n        $this->checkRouteResponse($app, '/bar', 'bar');\n    }\n\n    protected function checkRouteResponse(Application $app, $path, $expectedContent, $method = 'get', $message = null)\n    {\n        $request = Request::create($path, $method);\n        $response = $app->handle($request);\n        $this->assertEquals($expectedContent, $response->getContent(), $message);\n    }\n}\n\nclass MyController\n{\n    public function getFoo()\n    {\n        return 'foo';\n    }\n\n    public static function getBar()\n    {\n        return 'bar';\n    }\n}\n"
  },
  {
    "path": "tests/Silex/Tests/ServiceControllerResolverRouterTest.php",
    "content": "<?php\n\n/*\n * This file is part of the Silex framework.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * This source file is subject to the MIT license that is bundled\n * with this source code in the file LICENSE.\n */\n\nnamespace Silex\\Tests;\n\nuse Silex\\Application;\nuse Silex\\Provider\\ServiceControllerServiceProvider;\nuse Symfony\\Component\\HttpFoundation\\Request;\n\n/**\n * Router test cases, using the ServiceControllerResolver.\n */\nclass ServiceControllerResolverRouterTest extends RouterTest\n{\n    public function testServiceNameControllerSyntax()\n    {\n        $app = new Application();\n        $app->register(new ServiceControllerServiceProvider());\n\n        $app['service_name'] = function () {\n            return new MyController();\n        };\n\n        $app->get('/bar', 'service_name:getBar');\n\n        $this->checkRouteResponse($app, '/bar', 'bar');\n    }\n\n    protected function checkRouteResponse(Application $app, $path, $expectedContent, $method = 'get', $message = null)\n    {\n        $request = Request::create($path, $method);\n        $response = $app->handle($request);\n        $this->assertEquals($expectedContent, $response->getContent(), $message);\n    }\n}\n"
  },
  {
    "path": "tests/Silex/Tests/ServiceControllerResolverTest.php",
    "content": "<?php\n\n/*\n * This file is part of the Silex framework.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Silex\\Tests;\n\nuse Silex\\ServiceControllerResolver;\nuse Silex\\Application;\nuse Symfony\\Component\\HttpFoundation\\Request;\n\n/**\n * Unit tests for ServiceControllerResolver, see ServiceControllerResolverRouterTest for some\n * integration tests.\n */\nclass ServiceControllerResolverTest extends \\PHPUnit_Framework_Testcase\n{\n    private $app;\n    private $mockCallbackResolver;\n    private $mockResolver;\n    private $resolver;\n\n    public function setup()\n    {\n        $this->mockResolver = $this->getMockBuilder('Symfony\\Component\\HttpKernel\\Controller\\ControllerResolverInterface')\n            ->disableOriginalConstructor()\n            ->getMock();\n        $this->mockCallbackResolver = $this->getMockBuilder('Silex\\CallbackResolver')\n            ->disableOriginalConstructor()\n            ->getMock();\n\n        $this->app = new Application();\n        $this->resolver = new ServiceControllerResolver($this->mockResolver, $this->mockCallbackResolver);\n    }\n\n    public function testShouldResolveServiceController()\n    {\n        $this->mockCallbackResolver->expects($this->once())\n            ->method('isValid')\n            ->will($this->returnValue(true));\n\n        $this->mockCallbackResolver->expects($this->once())\n            ->method('convertCallback')\n            ->with('some_service:methodName')\n            ->will($this->returnValue(array('callback')));\n\n        $this->app['some_service'] = function () { return new \\stdClass(); };\n\n        $req = Request::create('/');\n        $req->attributes->set('_controller', 'some_service:methodName');\n\n        $this->assertEquals(array('callback'), $this->resolver->getController($req));\n    }\n\n    public function testShouldUnresolvedControllerNames()\n    {\n        $req = Request::create('/');\n        $req->attributes->set('_controller', 'some_class::methodName');\n\n        $this->mockCallbackResolver->expects($this->once())\n            ->method('isValid')\n            ->with('some_class::methodName')\n            ->will($this->returnValue(false));\n\n        $this->mockResolver->expects($this->once())\n            ->method('getController')\n            ->with($req)\n            ->will($this->returnValue(123));\n\n        $this->assertEquals(123, $this->resolver->getController($req));\n    }\n\n    public function testShouldDelegateGetArguments()\n    {\n        $req = Request::create('/');\n        $this->mockResolver->expects($this->once())\n            ->method('getArguments')\n            ->with($req)\n            ->will($this->returnValue(123));\n\n        $this->assertEquals(123, $this->resolver->getArguments($req, function () {}));\n    }\n}\n"
  },
  {
    "path": "tests/Silex/Tests/StreamTest.php",
    "content": "<?php\n\n/*\n * This file is part of the Silex framework.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * This source file is subject to the MIT license that is bundled\n * with this source code in the file LICENSE.\n */\n\nnamespace Silex\\Tests;\n\nuse Silex\\Application;\nuse Symfony\\Component\\HttpFoundation\\Request;\n\n/**\n * Stream test cases.\n *\n * @author Igor Wiedler <igor@wiedler.ch>\n */\nclass StreamTest extends \\PHPUnit_Framework_TestCase\n{\n    public function testStreamReturnsStreamingResponse()\n    {\n        $app = new Application();\n\n        $response = $app->stream();\n        $this->assertInstanceOf('Symfony\\Component\\HttpFoundation\\StreamedResponse', $response);\n        $this->assertSame(false, $response->getContent());\n    }\n\n    public function testStreamActuallyStreams()\n    {\n        $i = 0;\n\n        $stream = function () use (&$i) {\n            ++$i;\n        };\n\n        $app = new Application();\n        $response = $app->stream($stream);\n\n        $this->assertEquals(0, $i);\n\n        $request = Request::create('/stream');\n        $response->prepare($request);\n        $response->sendContent();\n\n        $this->assertEquals(1, $i);\n    }\n}\n"
  },
  {
    "path": "tests/Silex/Tests/WebTestCaseTest.php",
    "content": "<?php\n\n/*\n * This file is part of the Silex framework.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * This source file is subject to the MIT license that is bundled\n * with this source code in the file LICENSE.\n */\n\nnamespace Silex\\Tests;\n\nuse Silex\\Application;\nuse Silex\\WebTestCase;\nuse Symfony\\Component\\HttpFoundation\\Request;\n\n/**\n * Functional test cases.\n *\n * @author Igor Wiedler <igor@wiedler.ch>\n */\nclass WebTestCaseTest extends WebTestCase\n{\n    public function createApplication()\n    {\n        $app = new Application();\n\n        $app->match('/hello', function () {\n            return 'world';\n        });\n\n        $app->match('/html', function () {\n            return '<h1>title</h1>';\n        });\n\n        $app->match('/server', function (Request $request) use ($app) {\n            $user = $request->server->get('PHP_AUTH_USER');\n            $pass = $request->server->get('PHP_AUTH_PW');\n\n            return \"<h1>$user:$pass</h1>\";\n        });\n\n        return $app;\n    }\n\n    public function testGetHello()\n    {\n        $client = $this->createClient();\n\n        $client->request('GET', '/hello');\n        $response = $client->getResponse();\n        $this->assertTrue($response->isSuccessful());\n        $this->assertEquals('world', $response->getContent());\n    }\n\n    public function testCrawlerFilter()\n    {\n        $client = $this->createClient();\n\n        $crawler = $client->request('GET', '/html');\n        $this->assertEquals('title', $crawler->filter('h1')->text());\n    }\n\n    public function testServerVariables()\n    {\n        $user = 'klaus';\n        $pass = '123456';\n\n        $client = $this->createClient(array(\n            'PHP_AUTH_USER' => $user,\n            'PHP_AUTH_PW' => $pass,\n        ));\n\n        $crawler = $client->request('GET', '/server');\n        $this->assertEquals(\"$user:$pass\", $crawler->filter('h1')->text());\n    }\n}\n"
  }
]