diff --git a/bin/compile b/bin/compile deleted file mode 100755 index f0986edc9..000000000 --- a/bin/compile +++ /dev/null @@ -1,9 +0,0 @@ -#!/usr/bin/env php -compile(); diff --git a/composer.json b/composer.json index 5c509700f..9460fdde8 100644 --- a/composer.json +++ b/composer.json @@ -17,29 +17,29 @@ ], "require": { "php": ">=5.3.3", - "pimple/pimple": "~1.0", - "symfony/event-dispatcher": ">=2.3,<2.6-dev", - "symfony/http-foundation": ">=2.3,<2.6-dev", - "symfony/http-kernel": ">=2.3,<2.6-dev", - "symfony/routing": ">=2.3,<2.6-dev" + "pimple/pimple": "~2.1@dev", + "symfony/event-dispatcher": ">=2.4,<2.6-dev", + "symfony/http-foundation": ">=2.4,<2.6-dev", + "symfony/http-kernel": ">=2.4,<2.6-dev", + "symfony/routing": ">=2.4,<2.6-dev" }, "require-dev": { - "symfony/security": ">=2.3,<2.6-dev", - "symfony/config": ">=2.3,<2.6-dev", - "symfony/locale": ">=2.3,<2.6-dev", - "symfony/form": ">=2.3,<2.6-dev", - "symfony/browser-kit": ">=2.3,<2.6-dev", - "symfony/css-selector": ">=2.3,<2.6-dev", - "symfony/debug": ">=2.3,<2.6-dev", - "symfony/dom-crawler": ">=2.3,<2.6-dev", - "symfony/finder": ">=2.3,<2.6-dev", - "symfony/monolog-bridge": ">=2.3,<2.6-dev", - "symfony/options-resolver": ">=2.3,<2.6-dev", - "symfony/process": ">=2.3,<2.6-dev", - "symfony/serializer": ">=2.3,<2.6-dev", - "symfony/translation": ">=2.3,<2.6-dev", - "symfony/twig-bridge": ">=2.3,<2.6-dev", - "symfony/validator": ">=2.3,<2.6-dev", + "symfony/security": ">=2.4,<2.6-dev", + "symfony/config": ">=2.4,<2.6-dev", + "symfony/locale": ">=2.4,<2.6-dev", + "symfony/form": ">=2.4,<2.6-dev", + "symfony/browser-kit": ">=2.4,<2.6-dev", + "symfony/css-selector": ">=2.4,<2.6-dev", + "symfony/debug": ">=2.4,<2.6-dev", + "symfony/dom-crawler": ">=2.4,<2.6-dev", + "symfony/finder": ">=2.4,<2.6-dev", + "symfony/monolog-bridge": ">=2.4,<2.6-dev", + "symfony/options-resolver": ">=2.4,<2.6-dev", + "symfony/process": ">=2.4,<2.6-dev", + "symfony/serializer": ">=2.4,<2.6-dev", + "symfony/translation": ">=2.4,<2.6-dev", + "symfony/twig-bridge": ">=2.4,<2.6-dev", + "symfony/validator": ">=2.4,<2.6-dev", "twig/twig": ">=1.8.0,<2.0-dev", "doctrine/dbal": "~2.2", "swiftmailer/swiftmailer": "5.*", @@ -47,17 +47,21 @@ "phpunit/phpunit": "~3.7" }, "suggest": { - "symfony/browser-kit": ">=2.3,<2.6-dev", - "symfony/css-selector": ">=2.3,<2.6-dev", - "symfony/dom-crawler": ">=2.3,<2.6-dev", - "symfony/form": ">=2.3,<2.6-dev" + "symfony/browser-kit": ">=2.4,<2.6-dev", + "symfony/css-selector": ">=2.4,<2.6-dev", + "symfony/dom-crawler": ">=2.4,<2.6-dev", + "symfony/form": ">=2.4,<2.6-dev" + }, + "replace": { + "silex/api": "self.version", + "silex/providers": "self.version" }, "autoload": { "psr-0": { "Silex": "src/" } }, "extra": { "branch-alias": { - "dev-master": "1.2.x-dev" + "dev-master": "2.0.x-dev" } } } diff --git a/doc/changelog.rst b/doc/changelog.rst index 716b2d270..56a8452f8 100644 --- a/doc/changelog.rst +++ b/doc/changelog.rst @@ -1,6 +1,14 @@ Changelog ========= +2.0.0 (2013-XX-XX) +------------------ + +* Updated Pimple to 2.1 +* Updated session listeners to extends HttpKernel ones +* [BC BREAK] Locale management has been moved to LocaleServiceProvider which must be registered + if you want Silex to manage your locale (must also be registered for the translation service provider) + 1.2.0 (2014-03-29) ------------------ diff --git a/doc/cookbook/assets.rst b/doc/cookbook/assets.rst index 41c75793c..ed34a1a65 100644 --- a/doc/cookbook/assets.rst +++ b/doc/cookbook/assets.rst @@ -34,11 +34,11 @@ Using it in a template is as easy as before: If you need to implement some logic independently of the asset, define a service instead:: - $app['asset_path'] = $app->share(function () { + $app['asset_path'] = function () { // implement whatever logic you need to determine the asset path return 'http://assets.examples.com'; - }); + }; Usage is exactly the same as before: @@ -49,7 +49,7 @@ Usage is exactly the same as before: If the asset location depends on the asset type or path, you will need more abstraction; here is one way to do that with a Twig function:: - $app['twig'] = $app->share($app->extend('twig', function($twig, $app) { + $app->extend('twig', function($twig, $app) { $twig->addFunction(new \Twig_SimpleFunction('asset', function ($asset) { // implement whatever logic you need to determine the asset path @@ -57,7 +57,7 @@ abstraction; here is one way to do that with a Twig function:: })); return $twig; - })); + }); The ``asset`` function can then be used in your templates: diff --git a/doc/cookbook/multiple_loggers.rst b/doc/cookbook/multiple_loggers.rst index 83b91faa6..c75a3d587 100644 --- a/doc/cookbook/multiple_loggers.rst +++ b/doc/cookbook/multiple_loggers.rst @@ -18,9 +18,9 @@ using the bundled handler, but each with a different channel. }); foreach (array('auth', 'payments', 'stats') as $channel) { - $app['monolog.'.$channel] = $app->share(function ($app) use ($channel) { + $app['monolog.'.$channel] = function ($app) use ($channel) { return $app['monolog.factory']($channel); - }); + }; } As your application grows, or your logging needs for certain areas of the @@ -31,13 +31,13 @@ particular service separately, including your customizations. use Monolog\Handler\StreamHandler; - $app['monolog.payments'] = $app->share(function ($app) { + $app['monolog.payments'] = function ($app) { $log = new $app['monolog.logger.class']('payments'); $handler = new StreamHandler($app['monolog.payments.logfile'], $app['monolog.payment.level']); $log->pushHandler($handler); return $log; - }); + }; Alternatively, you could attempt to make the factory more complicated, and rely on some conventions, such as checking for an array of handlers registered with @@ -62,10 +62,8 @@ the container with the channel name, defaulting to the bundled handler. return $log; }); - $app['monolog.payments.handlers'] = $app->share(function ($app) { + $app['monolog.payments.handlers'] = function ($app) { return array( new StreamHandler(__DIR__.'/../payments.log', Logger::DEBUG), ); - }); - - + }; diff --git a/doc/cookbook/session_storage.rst b/doc/cookbook/session_storage.rst index 6f20f3f58..6b3828ff6 100644 --- a/doc/cookbook/session_storage.rst +++ b/doc/cookbook/session_storage.rst @@ -35,21 +35,21 @@ With a dedicated PDO service 'db_time_col' => 'session_time', ); - $app['pdo'] = $app->share(function () use ($app) { + $app['pdo'] = function () use ($app) { return new PDO( $app['pdo.dsn'], $app['pdo.user'], $app['pdo.password'] ); - }); + }; - $app['session.storage.handler'] = $app->share(function () use ($app) { + $app['session.storage.handler'] = function () use ($app) { return new PdoSessionHandler( $app['pdo'], $app['session.db_options'], $app['session.storage.options'] ); - }); + }; Using the DoctrineServiceProvider --------------------------------- @@ -70,13 +70,13 @@ have to make another database connection, simply pass the getWrappedConnection m 'db_time_col' => 'session_time', ); - $app['session.storage.handler'] = $app->share(function () use ($app) { + $app['session.storage.handler'] = function () use ($app) { return new PdoSessionHandler( $app['db']->getWrappedConnection(), $app['session.db_options'], $app['session.storage.options'] ); - }); + }; Database structure ------------------ diff --git a/doc/index.rst b/doc/index.rst index 938623c4e..ec7cd5d4b 100644 --- a/doc/index.rst +++ b/doc/index.rst @@ -17,4 +17,3 @@ Silex providers/index web_servers changelog - phar diff --git a/doc/phar.rst b/doc/phar.rst deleted file mode 100644 index 1ef72a13f..000000000 --- a/doc/phar.rst +++ /dev/null @@ -1,109 +0,0 @@ -Phar File -========= - -.. caution:: - - Using the Silex ``phar`` file is deprecated. You should use Composer - instead to install Silex and its dependencies or download one of the - archives. - -Installing ----------- - -Installing Silex is as easy as downloading the `phar -`_ and storing it somewhere on -the disk. Then, require it in your script:: - - get('/hello/{name}', function ($name) use ($app) { - return 'Hello '.$app->escape($name); - }); - - $app->run(); - -Console -------- - -Silex includes a lightweight console for updating to the latest version. - -To find out which version of Silex you are using, invoke ``silex.phar`` on the -command-line with ``version`` as an argument: - -.. code-block:: text - - $ php silex.phar version - Silex version 0a243d3 2011-04-17 14:49:31 +0200 - -To check that your are using the latest version, run the ``check`` command: - -.. code-block:: text - - $ php silex.phar check - -To update ``silex.phar`` to the latest version, invoke the ``update`` -command: - -.. code-block:: text - - $ php silex.phar update - -This will automatically download a new ``silex.phar`` from -``silex.sensiolabs.org`` and replace the existing one. - -Pitfalls --------- - -There are some things that can go wrong. Here we will try and outline the -most frequent ones. - -PHP configuration -~~~~~~~~~~~~~~~~~ - -Certain PHP distributions have restrictive default Phar settings. Setting -the following may help. - -.. code-block:: ini - - detect_unicode = Off - phar.readonly = Off - phar.require_hash = Off - -If you are on Suhosin you will also have to set this: - -.. code-block:: ini - - suhosin.executor.include.whitelist = phar - -.. note:: - - Ubuntu's PHP ships with Suhosin, so if you are using Ubuntu, you will need - this change. - -Phar-Stub bug -~~~~~~~~~~~~~ - -Some PHP installations have a bug that throws a ``PharException`` when trying -to include the Phar. It will also tell you that ``Silex\Application`` could not -be found. A workaround is using the following include line:: - - require_once 'phar://'.__DIR__.'/silex.phar/autoload.php'; - -The exact cause of this issue could not be determined yet. - -ioncube loader bug -~~~~~~~~~~~~~~~~~~ - -Ioncube loader is an extension that can decode PHP encoded file. -Unfortunately, old versions (prior to version 4.0.9) are not working well -with phar archives. -You must either upgrade Ioncube loader to version 4.0.9 or newer or disable it -by commenting or removing this line in your php.ini file: - -.. code-block:: ini - - zend_extension = /usr/lib/php5/20090626+lfs/ioncube_loader_lin_5.3.so diff --git a/doc/providers.rst b/doc/providers.rst index 9cd071fac..392eccde9 100644 --- a/doc/providers.rst +++ b/doc/providers.rst @@ -80,7 +80,7 @@ You are encouraged to share yours. Creating a provider ~~~~~~~~~~~~~~~~~~~ -Providers must implement the ``Silex\ServiceProviderInterface``:: +Providers must implement the ``Silex\Api\ServiceProviderInterface``:: interface ServiceProviderInterface { @@ -100,7 +100,7 @@ Here is an example of such a provider:: namespace Acme; use Silex\Application; - use Silex\ServiceProviderInterface; + use Silex\Api\ServiceProviderInterface; class HelloServiceProvider implements ServiceProviderInterface { @@ -161,7 +161,7 @@ All controllers defined by the provider will now be available under the Creating a provider ~~~~~~~~~~~~~~~~~~~ -Providers must implement the ``Silex\ControllerProviderInterface``:: +Providers must implement the ``Silex\Api\ControllerProviderInterface``:: interface ControllerProviderInterface { @@ -173,7 +173,7 @@ Here is an example of such a provider:: namespace Acme; use Silex\Application; - use Silex\ControllerProviderInterface; + use Silex\Api\ControllerProviderInterface; class HelloControllerProvider implements ControllerProviderInterface { diff --git a/doc/providers/form.rst b/doc/providers/form.rst index 697b95387..83606e552 100644 --- a/doc/providers/form.rst +++ b/doc/providers/form.rst @@ -168,28 +168,28 @@ form by adding constraints on the fields:: You can register form extensions by extending ``form.extensions``:: - $app['form.extensions'] = $app->share($app->extend('form.extensions', function ($extensions) use ($app) { + $app->extend('form.extensions', function ($extensions) use ($app) { $extensions[] = new YourTopFormExtension(); return $extensions; - })); + }); You can register form type extensions by extending ``form.type.extensions``:: - $app['form.type.extensions'] = $app->share($app->extend('form.type.extensions', function ($extensions) use ($app) { + $app->extend('form.type.extensions', function ($extensions) use ($app) { $extensions[] = new YourFormTypeExtension(); return $extensions; - })); + }); You can register form type guessers by extending ``form.type.guessers``:: - $app['form.type.guessers'] = $app->share($app->extend('form.type.guessers', function ($guessers) use ($app) { + $app->extend('form.type.guessers', function ($guessers) use ($app) { $guessers[] = new YourFormTypeGuesser(); return $guessers; - })); + }); Traits ------ diff --git a/doc/providers/locale.rst b/doc/providers/locale.rst new file mode 100644 index 000000000..b6e9d6ed1 --- /dev/null +++ b/doc/providers/locale.rst @@ -0,0 +1,24 @@ +LocaleServiceProvider +===================== + +The *LocaleServiceProvider* manages the locale of an application. + +Parameters +---------- + +* **locale**: The locale of the user. When set before any request handling, it + defines the default locale (``en`` by default). When a request is being + handled, it is automatically set according to the ``_locale`` request + attribute of the current route. + +Services +-------- + +* n/a + +Registering +----------- + +.. code-block:: php + + $app->register(new Silex\Provider\LocaleServiceProvider()); diff --git a/doc/providers/monolog.rst b/doc/providers/monolog.rst index 91d53652e..d1c7312fc 100644 --- a/doc/providers/monolog.rst +++ b/doc/providers/monolog.rst @@ -81,11 +81,11 @@ Customization You can configure Monolog (like adding or changing the handlers) before using it by extending the ``monolog`` service:: - $app['monolog'] = $app->share($app->extend('monolog', function($monolog, $app) { + $app->extend('monolog', function($monolog, $app) { $monolog->pushHandler(...); return $monolog; - })); + }); By default, all requests, responses and errors are logged by an event listener registered as a service called `monolog.listener`. You can replace or remove diff --git a/doc/providers/security.rst b/doc/providers/security.rst index 2db92491d..954ab0665 100644 --- a/doc/providers/security.rst +++ b/doc/providers/security.rst @@ -432,9 +432,9 @@ The ``users`` setting can be defined as a service that returns an instance of `UserProviderInterface `_:: - 'users' => $app->share(function () use ($app) { + 'users' => function () use ($app) { return new UserProvider($app['db']); - }), + }, Here is a simple example of a user provider, where Doctrine DBAL is used to store the users:: @@ -532,12 +532,12 @@ service:: use Symfony\Component\Security\Core\Encoder\MessageDigestPasswordEncoder; - $app['security.encoder.digest'] = $app->share(function ($app) { + $app['security.encoder.digest'] = function ($app) { // use the sha1 algorithm // don't base64 encode the password // use only 1 iteration return new MessageDigestPasswordEncoder('sha1', false, 1); - }); + }; Defining a custom Authentication Provider ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -550,14 +550,14 @@ use in your configuration:: $app['security.authentication_listener.factory.wsse'] = $app->protect(function ($name, $options) use ($app) { // define the authentication provider object - $app['security.authentication_provider.'.$name.'.wsse'] = $app->share(function () use ($app) { + $app['security.authentication_provider.'.$name.'.wsse'] = function () use ($app) { return new WsseProvider($app['security.user_provider.default'], __DIR__.'/security_cache'); - }); + }; // define the authentication listener object - $app['security.authentication_listener.'.$name.'.wsse'] = $app->share(function () use ($app) { + $app['security.authentication_listener.'.$name.'.wsse'] = function () use ($app) { return new WsseListener($app['security'], $app['security.authentication_manager']); - }); + }; return array( // the authentication provider id diff --git a/doc/providers/service_controller.rst b/doc/providers/service_controller.rst index 92d4343bd..ed89a64a7 100644 --- a/doc/providers/service_controller.rst +++ b/doc/providers/service_controller.rst @@ -58,9 +58,9 @@ In this slightly contrived example of a blog API, we're going to change the $app = new Application(); - $app['posts.repository'] = $app->share(function() { + $app['posts.repository'] = function() { return new PostRepository; - }); + }; $app->get('/posts.json', function() use ($app) { return $app->json($app['posts.repository']->findAll()); @@ -109,8 +109,8 @@ followed by a single colon (:), followed by the method name. .. code-block:: php - $app['posts.controller'] = $app->share(function() use ($app) { + $app['posts.controller'] = function() use ($app) { return new PostController($app['posts.repository']); - }); + }; $app->get('/posts.json', "posts.controller:indexJsonAction"); diff --git a/doc/providers/translation.rst b/doc/providers/translation.rst index c43720d7a..f4944d91a 100644 --- a/doc/providers/translation.rst +++ b/doc/providers/translation.rst @@ -37,6 +37,7 @@ Registering .. code-block:: php + $app->register(new Silex\Provider\LocaleServiceProvider()); $app->register(new Silex\Provider\TranslationServiceProvider(), array( 'locale_fallbacks' => array('en'), )); @@ -143,7 +144,7 @@ translation files:: use Symfony\Component\Translation\Loader\YamlFileLoader; - $app['translator'] = $app->share($app->extend('translator', function($translator, $app) { + $app->extend('translator', function($translator, $app) { $translator->addLoader('yaml', new YamlFileLoader()); $translator->addResource('yaml', __DIR__.'/locales/en.yml', 'en'); @@ -151,7 +152,7 @@ translation files:: $translator->addResource('yaml', __DIR__.'/locales/fr.yml', 'fr'); return $translator; - })); + }); XLIFF-based language files ~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/doc/providers/twig.rst b/doc/providers/twig.rst index ed0e1160e..8e70e7a12 100644 --- a/doc/providers/twig.rst +++ b/doc/providers/twig.rst @@ -156,12 +156,12 @@ Customization You can configure the Twig environment before using it by extending the ``twig`` service:: - $app['twig'] = $app->share($app->extend('twig', function($twig, $app) { + $app->extend('twig', function($twig, $app) { $twig->addGlobal('pi', 3.14); $twig->addFilter('levenshtein', new \Twig_Filter_Function('levenshtein')); return $twig; - })); + }); For more information, check out the `official Twig documentation `_. diff --git a/doc/providers/url_generator.rst b/doc/providers/url_generator.rst index b8d1d57cb..e7670f2ca 100644 --- a/doc/providers/url_generator.rst +++ b/doc/providers/url_generator.rst @@ -64,6 +64,14 @@ Moreover, if you have ``twig-bridge`` in your ``composer.json``, you will have a {{ path('hello', {name: 'Fabien'}) }} {{ url('hello', {name: 'Fabien'}) }} {# generates the absolute url http://example.org/hello/Fabien #} +.. warning:: + + If you try to use the ``url_generator`` service outside the handling of a + request, you must explicitly flush routes first:: + + $app->flush(); + $url = $app['url_generator']->generate('homepage'); + Traits ------ diff --git a/doc/services.rst b/doc/services.rst index ec8a88c3d..59e102fdb 100644 --- a/doc/services.rst +++ b/doc/services.rst @@ -63,10 +63,10 @@ Pimple is probably the simplest service container out there. It makes strong use of closures and implements the ArrayAccess interface. We will start off by creating a new instance of Pimple -- and because -``Silex\Application`` extends ``Pimple`` all of this applies to Silex as -well:: +``Silex\Application`` extends ``Pimple\Container`` all of this applies to Silex +as well:: - $container = new Pimple(); + $container = new Pimple\Container(); or:: @@ -107,19 +107,6 @@ And to retrieve the service, use:: Every time you call ``$app['some_service']``, a new instance of the service is created. -Shared services -~~~~~~~~~~~~~~~ - -You may want to use the same instance of a service across all of your code. In -order to do that you can make a *shared* service:: - - $app['some_service'] = $app->share(function () { - return new Service(); - }); - -This will create the service on first invocation, and then return the existing -instance on any subsequent access. - Access container from closure ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -139,17 +126,13 @@ options. The dependency is only created when ``some_service`` is accessed, and it is possible to replace either of the dependencies by simply overriding those definitions. -.. note:: - - This also works for shared services. - Going back to our initial example, here's how we could use the container to manage its dependencies:: $app['user.persist_path'] = '/tmp/users'; - $app['user.persister'] = $app->share(function ($app) { + $app['user.persister'] = function ($app) { return new JsonUserPersister($app['user.persist_path']); - }); + }; Protected closures @@ -230,13 +213,6 @@ don't want to mess with most of them. the ``MonologServiceProvider`` or define your own ``logger`` service that conforms to the PSR logger interface. - In versions of Silex before 1.1 this must be a - ``Symfony\Component\HttpKernel\Log\LoggerInterface``. - -.. note:: - - All of these Silex core services are shared. - Core parameters --------------- @@ -256,11 +232,6 @@ Core parameters This parameter can be used by the ``UrlGeneratorProvider``. -* **locale** (optional): The locale of the user. When set before any request - handling, it defines the default locale (``en`` by default). When a request - is being handled, it is automatically set according to the ``_locale`` - request attribute of the current route. - * **debug** (optional): Returns whether or not the application is running in debug mode. diff --git a/doc/usage.rst b/doc/usage.rst index 03727409f..7988f45dd 100644 --- a/doc/usage.rst +++ b/doc/usage.rst @@ -25,7 +25,7 @@ If you want more flexibility, use Composer_ instead. Create a { "require": { - "silex/silex": "~1.1" + "silex/silex": "~2.0" } } @@ -375,9 +375,9 @@ converter based on Doctrine ObjectManager:: The service will now be registered in the application, and the convert method will be used as converter:: - $app['converter.user'] = $app->share(function () { + $app['converter.user'] = function () { return new UserConverter(); - }); + }; $app->get('/user/{user}', function (User $user) { // ... diff --git a/src/Silex/ServiceProviderInterface.php b/src/Silex/Api/BootableProviderInterface.php similarity index 58% rename from src/Silex/ServiceProviderInterface.php rename to src/Silex/Api/BootableProviderInterface.php index 88f1f959b..a16b9448b 100644 --- a/src/Silex/ServiceProviderInterface.php +++ b/src/Silex/Api/BootableProviderInterface.php @@ -9,25 +9,17 @@ * file that was distributed with this source code. */ -namespace Silex; +namespace Silex\Api; + +use Silex\Application; /** - * Interface that all Silex service providers must implement. + * Interface that must implement all Silex service providers. * * @author Fabien Potencier */ -interface ServiceProviderInterface +interface BootableProviderInterface { - /** - * Registers services on the given app. - * - * This method should only be used to configure services and parameters. - * It should not get services. - * - * @param Application $app An Application instance - */ - public function register(Application $app); - /** * Bootstraps the application. * diff --git a/src/Silex/ControllerProviderInterface.php b/src/Silex/Api/ControllerProviderInterface.php similarity index 93% rename from src/Silex/ControllerProviderInterface.php rename to src/Silex/Api/ControllerProviderInterface.php index 2e1f7e6aa..dcd92a6a4 100644 --- a/src/Silex/ControllerProviderInterface.php +++ b/src/Silex/Api/ControllerProviderInterface.php @@ -9,7 +9,9 @@ * file that was distributed with this source code. */ -namespace Silex; +namespace Silex\Api; + +use Silex\Application; /** * Interface for controller providers. diff --git a/src/Silex/Api/EventListenerProviderInterface.php b/src/Silex/Api/EventListenerProviderInterface.php new file mode 100644 index 000000000..f3e625557 --- /dev/null +++ b/src/Silex/Api/EventListenerProviderInterface.php @@ -0,0 +1,25 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Silex\Api; + +use Symfony\Component\EventDispatcher\EventDispatcherInterface; +use Pimple\Container; + +/** + * Interface for event listener providers. + * + * @author Fabien Potencier + */ +interface EventListenerProviderInterface +{ + public function subscribe(Container $app, EventDispatcherInterface $dispatcher); +} diff --git a/src/Silex/Api/LICENSE b/src/Silex/Api/LICENSE new file mode 100644 index 000000000..ff727f4b5 --- /dev/null +++ b/src/Silex/Api/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2010-2013 Fabien Potencier + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/src/Silex/Api/composer.json b/src/Silex/Api/composer.json new file mode 100644 index 000000000..502219058 --- /dev/null +++ b/src/Silex/Api/composer.json @@ -0,0 +1,35 @@ +{ + "minimum-stability": "dev", + "name": "silex/api", + "description": "The Silex interfaces", + "keywords": ["microframework"], + "homepage": "http://silex.sensiolabs.org", + "license": "MIT", + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Igor Wiedler", + "email": "igor@wiedler.ch" + } + ], + "require": { + "php": ">=5.3.3", + "pimple/pimple": "~1.0" + }, + "suggest": { + "symfony/event-dispatcher": "For EventListenerProviderInterface", + "silex/silex": "For BootableProviderInterface and ControllerProviderInterface" + }, + "autoload": { + "psr-0": { "Silex\\Api": "" } + }, + "target-dir": "Silex/Api", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + } +} diff --git a/src/Silex/Application.php b/src/Silex/Application.php index 374e28407..ef3070ec2 100644 --- a/src/Silex/Application.php +++ b/src/Silex/Application.php @@ -11,6 +11,8 @@ namespace Silex; +use Pimple\Container; +use Pimple\ServiceProviderInterface; use Symfony\Component\HttpFoundation\BinaryFileResponse; use Symfony\Component\HttpKernel\HttpKernel; use Symfony\Component\HttpKernel\HttpKernelInterface; @@ -19,7 +21,6 @@ use Symfony\Component\HttpKernel\Event\GetResponseEvent; use Symfony\Component\HttpKernel\Event\PostResponseEvent; use Symfony\Component\HttpKernel\EventListener\ResponseListener; -use Symfony\Component\HttpKernel\EventListener\RouterListener; use Symfony\Component\HttpKernel\Exception\HttpException; use Symfony\Component\HttpKernel\KernelEvents; use Symfony\Component\HttpFoundation\Request; @@ -29,20 +30,22 @@ use Symfony\Component\HttpFoundation\StreamedResponse; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\Routing\RouteCollection; -use Symfony\Component\Routing\RequestContext; -use Silex\EventListener\LocaleListener; +use Silex\Api\BootableProviderInterface; +use Silex\Api\EventListenerProviderInterface; +use Silex\Api\ControllerProviderInterface; use Silex\EventListener\MiddlewareListener; use Silex\EventListener\ConverterListener; use Silex\EventListener\StringToResponseListener; +use Silex\Provider\RoutingServiceProvider; /** * The Silex framework class. * * @author Fabien Potencier */ -class Application extends \Pimple implements HttpKernelInterface, TerminableInterface +class Application extends Container implements HttpKernelInterface, TerminableInterface { - const VERSION = '1.2.0'; + const VERSION = '2.0.0-DEV'; const EARLY_EVENT = 512; const LATE_EVENT = -512; @@ -63,38 +66,31 @@ public function __construct(array $values = array()) $app = $this; - $this['logger'] = null; - - $this['routes'] = $this->share(function () { + $this['routes'] = function () { return new RouteCollection(); - }); + }; - $this['controllers'] = $this->share(function () use ($app) { + $this['controllers'] = function () use ($app) { return $app['controllers_factory']; - }); + }; - $this['controllers_factory'] = function () use ($app) { + $this['controllers_factory'] = $this->factory(function () use ($app) { return new ControllerCollection($app['route_factory']); - }; + }); $this['route_class'] = 'Silex\\Route'; - $this['route_factory'] = function () use ($app) { + $this['route_factory'] = $this->factory(function () use ($app) { return new $app['route_class'](); - }; + }); - $this['exception_handler'] = $this->share(function () use ($app) { + $this['exception_handler'] = function () use ($app) { return new ExceptionHandler($app['debug']); - }); + }; $this['dispatcher_class'] = 'Symfony\\Component\\EventDispatcher\\EventDispatcher'; - $this['dispatcher'] = $this->share(function () use ($app) { + $this['dispatcher'] = function () use ($app) { $dispatcher = new $app['dispatcher_class'](); - $urlMatcher = new LazyUrlMatcher(function () use ($app) { - return $app['url_matcher']; - }); - $dispatcher->addSubscriber(new RouterListener($urlMatcher, $app['request_context'], $app['logger'], $app['request_stack'])); - $dispatcher->addSubscriber(new LocaleListener($app, $urlMatcher, $app['request_stack'])); if (isset($app['exception_handler'])) { $dispatcher->addSubscriber($app['exception_handler']); } @@ -104,50 +100,31 @@ public function __construct(array $values = array()) $dispatcher->addSubscriber(new StringToResponseListener()); return $dispatcher; - }); + }; - $this['callback_resolver'] = $this->share(function () use ($app) { + $this['callback_resolver'] = function () use ($app) { return new CallbackResolver($app); - }); + }; - $this['resolver'] = $this->share(function () use ($app) { + $this['resolver'] = function () use ($app) { return new ControllerResolver($app, $app['logger']); - }); + }; - $this['kernel'] = $this->share(function () use ($app) { + $this['kernel'] = function () use ($app) { return new HttpKernel($app['dispatcher'], $app['resolver'], $app['request_stack']); - }); - - $this['request_stack'] = $this->share(function () use ($app) { - if (class_exists('Symfony\Component\HttpFoundation\RequestStack')) { - return new RequestStack(); - } - }); - - $this['request_context'] = $this->share(function () use ($app) { - $context = new RequestContext(); - - $context->setHttpPort($app['request.http_port']); - $context->setHttpsPort($app['request.https_port']); - - return $context; - }); - - $this['url_matcher'] = $this->share(function () use ($app) { - return new RedirectableUrlMatcher($app['routes'], $app['request_context']); - }); - - $this['request_error'] = $this->protect(function () { - throw new \RuntimeException('Accessed request service outside of request scope. Try moving that call to a before handler or controller.'); - }); + }; - $this['request'] = $this['request_error']; + $this['request_stack'] = function () use ($app) { + return new RequestStack(); + }; $this['request.http_port'] = 80; $this['request.https_port'] = 443; $this['debug'] = false; $this['charset'] = 'UTF-8'; - $this['locale'] = 'en'; + $this['logger'] = null; + + $this->register(new RoutingServiceProvider()); foreach ($values as $key => $value) { $this[$key] = $value; @@ -184,11 +161,17 @@ public function register(ServiceProviderInterface $provider, array $values = arr public function boot() { if (!$this->booted) { + $this->booted = true; + foreach ($this->providers as $provider) { - $provider->boot($this); - } + if ($provider instanceof EventListenerProviderInterface) { + $provider->subscribe($this, $this['dispatcher']); + } - $this->booted = true; + if ($provider instanceof BootableProviderInterface) { + $provider->boot($this); + } + } } } @@ -288,11 +271,11 @@ public function on($eventName, $callback, $priority = 0) return; } - $this['dispatcher'] = $this->share($this->extend('dispatcher', function ($dispatcher, $app) use ($callback, $priority, $eventName) { + $this->extend('dispatcher', function ($dispatcher, $app) use ($callback, $priority, $eventName) { $dispatcher->addListener($eventName, $app['callback_resolver']->resolveCallback($callback), $priority); return $dispatcher; - })); + }); } /** @@ -470,8 +453,6 @@ public function json($data = array(), $status = 200, array $headers = array()) * @param null|string $contentDisposition The type of Content-Disposition to set automatically with the filename * * @return BinaryFileResponse - * - * @throws \RuntimeException When the feature is not supported, before http-foundation v2.2 */ public function sendFile($file, $status = 200, array $headers = array(), $contentDisposition = null) { @@ -529,17 +510,9 @@ public function handle(Request $request, $type = HttpKernelInterface::MASTER_REQ $this->boot(); } - $current = HttpKernelInterface::SUB_REQUEST === $type ? $this['request'] : $this['request_error']; - - $this['request'] = $request; - $this->flush(); - $response = $this['kernel']->handle($request, $type, $catch); - - $this['request'] = $current; - - return $response; + return $this['kernel']->handle($request, $type, $catch); } /** diff --git a/src/Silex/CallbackResolver.php b/src/Silex/CallbackResolver.php index 859d86e24..72f3675bc 100644 --- a/src/Silex/CallbackResolver.php +++ b/src/Silex/CallbackResolver.php @@ -11,13 +11,15 @@ namespace Silex; +use Pimple\Container; + class CallbackResolver { const SERVICE_PATTERN = "/[A-Za-z0-9\._\-]+:[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*/"; private $app; - public function __construct(\Pimple $app) + public function __construct(Container $app) { $this->app = $app; } diff --git a/src/Silex/ExceptionListenerWrapper.php b/src/Silex/ExceptionListenerWrapper.php index 40fb6370d..10f99a5f0 100644 --- a/src/Silex/ExceptionListenerWrapper.php +++ b/src/Silex/ExceptionListenerWrapper.php @@ -49,7 +49,7 @@ public function __invoke(GetResponseForExceptionEvent $event) $code = $exception instanceof HttpExceptionInterface ? $exception->getStatusCode() : 500; - $response = call_user_func($this->callback, $exception, $code); + $response = call_user_func($this->callback, $exception, $event->getRequest(), $code); $this->ensureResponse($response, $event); } diff --git a/src/Silex/Provider/DoctrineServiceProvider.php b/src/Silex/Provider/DoctrineServiceProvider.php index a657fbed4..3846e5b48 100644 --- a/src/Silex/Provider/DoctrineServiceProvider.php +++ b/src/Silex/Provider/DoctrineServiceProvider.php @@ -11,8 +11,8 @@ namespace Silex\Provider; -use Silex\Application; -use Silex\ServiceProviderInterface; +use Pimple\Container; +use Pimple\ServiceProviderInterface; use Doctrine\DBAL\DriverManager; use Doctrine\DBAL\Configuration; use Doctrine\Common\EventManager; @@ -25,7 +25,7 @@ */ class DoctrineServiceProvider implements ServiceProviderInterface { - public function register(Application $app) + public function register(Container $app) { $app['db.default_options'] = array( 'driver' => 'pdo_mysql', @@ -60,10 +60,10 @@ public function register(Application $app) $app['dbs.options'] = $tmp; }); - $app['dbs'] = $app->share(function ($app) { + $app['dbs'] = function ($app) { $app['dbs.options.initializer'](); - $dbs = new \Pimple(); + $dbs = new Container(); foreach ($app['dbs.options'] as $name => $options) { if ($app['dbs.default'] === $name) { // we use shortcuts here in case the default has been overridden @@ -74,18 +74,18 @@ public function register(Application $app) $manager = $app['dbs.event_manager'][$name]; } - $dbs[$name] = $dbs->share(function ($dbs) use ($options, $config, $manager) { + $dbs[$name] = function ($dbs) use ($options, $config, $manager) { return DriverManager::getConnection($options, $config, $manager); - }); + }; } return $dbs; - }); + }; - $app['dbs.config'] = $app->share(function ($app) { + $app['dbs.config'] = function ($app) { $app['dbs.options.initializer'](); - $configs = new \Pimple(); + $configs = new Container(); foreach ($app['dbs.options'] as $name => $options) { $configs[$name] = new Configuration(); @@ -95,40 +95,36 @@ public function register(Application $app) } return $configs; - }); + }; - $app['dbs.event_manager'] = $app->share(function ($app) { + $app['dbs.event_manager'] = function ($app) { $app['dbs.options.initializer'](); - $managers = new \Pimple(); + $managers = new Container(); foreach ($app['dbs.options'] as $name => $options) { $managers[$name] = new EventManager(); } return $managers; - }); + }; // shortcuts for the "first" DB - $app['db'] = $app->share(function ($app) { + $app['db'] = function ($app) { $dbs = $app['dbs']; return $dbs[$app['dbs.default']]; - }); + }; - $app['db.config'] = $app->share(function ($app) { + $app['db.config'] = function ($app) { $dbs = $app['dbs.config']; return $dbs[$app['dbs.default']]; - }); + }; - $app['db.event_manager'] = $app->share(function ($app) { + $app['db.event_manager'] = function ($app) { $dbs = $app['dbs.event_manager']; return $dbs[$app['dbs.default']]; - }); - } - - public function boot(Application $app) - { + }; } } diff --git a/src/Silex/Provider/FormServiceProvider.php b/src/Silex/Provider/FormServiceProvider.php index b8d97d2ab..989215c6d 100644 --- a/src/Silex/Provider/FormServiceProvider.php +++ b/src/Silex/Provider/FormServiceProvider.php @@ -11,8 +11,8 @@ namespace Silex\Provider; -use Silex\Application; -use Silex\ServiceProviderInterface; +use Pimple\Container; +use Pimple\ServiceProviderInterface; use Symfony\Component\Form\Extension\Csrf\CsrfExtension; use Symfony\Component\Form\Extension\Csrf\CsrfProvider\DefaultCsrfProvider; use Symfony\Component\Form\Extension\Csrf\CsrfProvider\SessionCsrfProvider; @@ -28,7 +28,7 @@ */ class FormServiceProvider implements ServiceProviderInterface { - public function register(Application $app) + public function register(Container $app) { if (!class_exists('Locale') && !class_exists('Symfony\Component\Locale\Stub\StubLocale')) { throw new \RuntimeException('You must either install the PHP intl extension or the Symfony Locale Component to use the Form extension.'); @@ -47,23 +47,23 @@ public function register(Application $app) $app['form.secret'] = md5(__DIR__); - $app['form.type.extensions'] = $app->share(function ($app) { + $app['form.type.extensions'] = function ($app) { return array(); - }); + }; - $app['form.type.guessers'] = $app->share(function ($app) { + $app['form.type.guessers'] = function ($app) { return array(); - }); + }; - $app['form.extension.csrf'] = $app->share(function ($app) { + $app['form.extension.csrf'] = function ($app) { if (isset($app['translator'])) { return new CsrfExtension($app['form.csrf_provider'], $app['translator']); } return new CsrfExtension($app['form.csrf_provider']); - }); + }; - $app['form.extensions'] = $app->share(function ($app) { + $app['form.extensions'] = function ($app) { $extensions = array( $app['form.extension.csrf'], new HttpFoundationExtension(), @@ -79,9 +79,9 @@ public function register(Application $app) } return $extensions; - }); + }; - $app['form.factory'] = $app->share(function ($app) { + $app['form.factory'] = function ($app) { return Forms::createFormFactoryBuilder() ->addExtensions($app['form.extensions']) ->addTypeExtensions($app['form.type.extensions']) @@ -89,22 +89,18 @@ public function register(Application $app) ->setResolvedTypeFactory($app['form.resolved_type_factory']) ->getFormFactory() ; - }); + }; - $app['form.resolved_type_factory'] = $app->share(function ($app) { + $app['form.resolved_type_factory'] = function ($app) { return new ResolvedFormTypeFactory(); - }); + }; - $app['form.csrf_provider'] = $app->share(function ($app) { + $app['form.csrf_provider'] = function ($app) { if (isset($app['session'])) { return new SessionCsrfProvider($app['session'], $app['form.secret']); } return new DefaultCsrfProvider($app['form.secret']); - }); - } - - public function boot(Application $app) - { + }; } } diff --git a/src/Silex/HttpCache.php b/src/Silex/Provider/HttpCache/HttpCache.php similarity index 96% rename from src/Silex/HttpCache.php rename to src/Silex/Provider/HttpCache/HttpCache.php index ebd65dd92..b0ebb5ccb 100644 --- a/src/Silex/HttpCache.php +++ b/src/Silex/Provider/HttpCache/HttpCache.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace Silex; +namespace Silex\Provider\HttpCache; use Symfony\Component\HttpKernel\HttpCache\HttpCache as BaseHttpCache; use Symfony\Component\HttpFoundation\Request; diff --git a/src/Silex/Provider/HttpCacheServiceProvider.php b/src/Silex/Provider/HttpCacheServiceProvider.php index 18217e9eb..df0d0280a 100644 --- a/src/Silex/Provider/HttpCacheServiceProvider.php +++ b/src/Silex/Provider/HttpCacheServiceProvider.php @@ -11,9 +11,11 @@ namespace Silex\Provider; -use Silex\Application; -use Silex\ServiceProviderInterface; -use Silex\HttpCache; +use Pimple\Container; +use Pimple\ServiceProviderInterface; +use Silex\Provider\HttpCache\HttpCache; +use Silex\Api\EventListenerProviderInterface; +use Symfony\Component\EventDispatcher\EventDispatcherInterface; use Symfony\Component\HttpKernel\HttpCache\Esi; use Symfony\Component\HttpKernel\HttpCache\Store; use Symfony\Component\HttpKernel\EventListener\EsiListener; @@ -23,37 +25,37 @@ * * @author Fabien Potencier */ -class HttpCacheServiceProvider implements ServiceProviderInterface +class HttpCacheServiceProvider implements ServiceProviderInterface, EventListenerProviderInterface { - public function register(Application $app) + public function register(Container $app) { - $app['http_cache'] = $app->share(function ($app) { + $app['http_cache'] = function ($app) { $app['http_cache.options'] = array_replace( array( - 'debug' => $app['debug'], + 'debug' => isset($app['debug']) ? $app['debug'] : false, ), $app['http_cache.options'] ); return new HttpCache($app, $app['http_cache.store'], $app['http_cache.esi'], $app['http_cache.options']); - }); + }; - $app['http_cache.esi'] = $app->share(function ($app) { + $app['http_cache.esi'] = function ($app) { return new Esi(); - }); + }; - $app['http_cache.store'] = $app->share(function ($app) { + $app['http_cache.store'] = function ($app) { return new Store($app['http_cache.cache_dir']); - }); + }; - $app['http_cache.esi_listener'] = $app->share(function ($app) { + $app['http_cache.esi_listener'] = function ($app) { return new EsiListener($app['http_cache.esi']); - }); + }; $app['http_cache.options'] = array(); } - public function boot(Application $app) + public function subscribe(Container $app, EventDispatcherInterface $dispatcher) { - $app['dispatcher']->addSubscriber($app['http_cache.esi_listener']); + $dispatcher->addSubscriber($app['http_cache.esi_listener']); } } diff --git a/src/Silex/Provider/HttpFragmentServiceProvider.php b/src/Silex/Provider/HttpFragmentServiceProvider.php index f72a97b62..784604c63 100644 --- a/src/Silex/Provider/HttpFragmentServiceProvider.php +++ b/src/Silex/Provider/HttpFragmentServiceProvider.php @@ -11,8 +11,10 @@ namespace Silex\Provider; -use Silex\Application; -use Silex\ServiceProviderInterface; +use Pimple\Container; +use Pimple\ServiceProviderInterface; +use Silex\Api\EventListenerProviderInterface; +use Symfony\Component\EventDispatcher\EventDispatcherInterface; use Symfony\Component\HttpKernel\Fragment\FragmentHandler; use Symfony\Component\HttpKernel\Fragment\InlineFragmentRenderer; use Symfony\Component\HttpKernel\Fragment\EsiFragmentRenderer; @@ -23,55 +25,49 @@ /** * HttpKernel Fragment integration for Silex. * - * This service provider requires Symfony 2.4+. - * * @author Fabien Potencier */ -class HttpFragmentServiceProvider implements ServiceProviderInterface +class HttpFragmentServiceProvider implements ServiceProviderInterface, EventListenerProviderInterface { - public function register(Application $app) + public function register(Container $app) { - if (!class_exists('Symfony\Component\HttpFoundation\RequestStack')) { - throw new \LogicException('The HTTP Fragment service provider only works with Symfony 2.4+.'); - } - - $app['fragment.handler'] = $app->share(function ($app) { - return new FragmentHandler($app['fragment.renderers'], $app['debug'], $app['request_stack']); - }); + $app['fragment.handler'] = function ($app) { + return new FragmentHandler($app['fragment.renderers'], isset($app['debug']) ? $app['debug'] : false, $app['request_stack']); + }; - $app['fragment.renderer.inline'] = $app->share(function ($app) { + $app['fragment.renderer.inline'] = function ($app) { $renderer = new InlineFragmentRenderer($app['kernel'], $app['dispatcher']); $renderer->setFragmentPath($app['fragment.path']); return $renderer; - }); + }; - $app['fragment.renderer.hinclude'] = $app->share(function ($app) { - $renderer = new HIncludeFragmentRenderer(null, $app['uri_signer'], $app['fragment.renderer.hinclude.global_template'], $app['charset']); + $app['fragment.renderer.hinclude'] = function ($app) { + $renderer = new HIncludeFragmentRenderer(null, $app['uri_signer'], $app['fragment.renderer.hinclude.global_template'], isset($app['charset']) ? $app['charset'] : 'UTF-8'); $renderer->setFragmentPath($app['fragment.path']); return $renderer; - }); + }; - $app['fragment.renderer.esi'] = $app->share(function ($app) { + $app['fragment.renderer.esi'] = function ($app) { $renderer = new EsiFragmentRenderer($app['http_cache.esi'], $app['fragment.renderer.inline']); $renderer->setFragmentPath($app['fragment.path']); return $renderer; - }); + }; - $app['fragment.listener'] = $app->share(function ($app) { + $app['fragment.listener'] = function ($app) { return new FragmentListener($app['uri_signer'], $app['fragment.path']); - }); + }; - $app['uri_signer'] = $app->share(function ($app) { + $app['uri_signer'] = function ($app) { return new UriSigner($app['uri_signer.secret']); - }); + }; $app['uri_signer.secret'] = md5(__DIR__); $app['fragment.path'] = '/_fragment'; $app['fragment.renderer.hinclude.global_template'] = null; - $app['fragment.renderers'] = $app->share(function ($app) { + $app['fragment.renderers'] = function ($app) { $renderers = array($app['fragment.renderer.inline'], $app['fragment.renderer.hinclude']); if (isset($app['http_cache.esi'])) { @@ -79,11 +75,11 @@ public function register(Application $app) } return $renderers; - }); + }; } - public function boot(Application $app) + public function subscribe(Container $app, EventDispatcherInterface $dispatcher) { - $app['dispatcher']->addSubscriber($app['fragment.listener']); + $dispatcher->addSubscriber($app['fragment.listener']); } } diff --git a/src/Silex/Provider/LICENSE b/src/Silex/Provider/LICENSE new file mode 100644 index 000000000..ff727f4b5 --- /dev/null +++ b/src/Silex/Provider/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2010-2013 Fabien Potencier + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/src/Silex/EventListener/LocaleListener.php b/src/Silex/Provider/Locale/LocaleListener.php similarity index 84% rename from src/Silex/EventListener/LocaleListener.php rename to src/Silex/Provider/Locale/LocaleListener.php index 60dd624c0..8bafb14f4 100644 --- a/src/Silex/EventListener/LocaleListener.php +++ b/src/Silex/Provider/Locale/LocaleListener.php @@ -9,13 +9,13 @@ * file that was distributed with this source code. */ -namespace Silex\EventListener; +namespace Silex\Provider\Locale; +use Pimple\Container; use Symfony\Component\HttpKernel\Event\GetResponseEvent; use Symfony\Component\HttpKernel\EventListener\LocaleListener as BaseLocaleListener; use Symfony\Component\HttpFoundation\RequestStack; use Symfony\Component\Routing\RequestContextAwareInterface; -use Silex\Application; /** * Initializes the locale based on the current request. @@ -26,7 +26,7 @@ class LocaleListener extends BaseLocaleListener { protected $app; - public function __construct(Application $app, RequestContextAwareInterface $router = null, RequestStack $requestStack = null) + public function __construct(Container $app, RequestContextAwareInterface $router = null, RequestStack $requestStack = null) { parent::__construct($app['locale'], $router, $requestStack); diff --git a/src/Silex/Provider/LocaleServiceProvider.php b/src/Silex/Provider/LocaleServiceProvider.php new file mode 100644 index 000000000..82c07d378 --- /dev/null +++ b/src/Silex/Provider/LocaleServiceProvider.php @@ -0,0 +1,48 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Silex\Provider; + +use Pimple\Container; +use Pimple\ServiceProviderInterface; +use Silex\Api\EventListenerProviderInterface; +use Silex\Provider\Locale\LocaleListener; +use Silex\Provider\Routing\LazyUrlMatcher; +use Symfony\Component\EventDispatcher\EventDispatcherInterface; + +/** + * Locale Provider. + * + * @author Fabien Potencier + */ +class LocaleServiceProvider implements ServiceProviderInterface, EventListenerProviderInterface +{ + public function register(Container $app) + { + $app['locale.listener'] = function ($app) { + $urlMatcher = null; + if (isset($app['url_matcher'])) { + $urlMatcher = new LazyUrlMatcher(function () use ($app) { + return $app['url_matcher']; + }); + } + + return new LocaleListener($app, $urlMatcher, $app['request_stack']); + }; + + $app['locale'] = 'en'; + } + + public function subscribe(Container $app, EventDispatcherInterface $dispatcher) + { + $dispatcher->addSubscriber($app['locale.listener']); + } +} diff --git a/src/Silex/Provider/MonologServiceProvider.php b/src/Silex/Provider/MonologServiceProvider.php index 46676e4c4..a6d27ec9b 100644 --- a/src/Silex/Provider/MonologServiceProvider.php +++ b/src/Silex/Provider/MonologServiceProvider.php @@ -11,10 +11,15 @@ namespace Silex\Provider; +use Pimple\Container; +use Pimple\ServiceProviderInterface; use Monolog\Logger; use Monolog\Handler\StreamHandler; use Silex\Application; -use Silex\ServiceProviderInterface; +use Silex\Api\BootableProviderInterface; +use Symfony\Component\HttpFoundation\RedirectResponse; +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; use Symfony\Bridge\Monolog\Handler\DebugHandler; use Silex\EventListener\LogListener; @@ -23,9 +28,9 @@ * * @author Fabien Potencier */ -class MonologServiceProvider implements ServiceProviderInterface +class MonologServiceProvider implements ServiceProviderInterface, BootableProviderInterface { - public function register(Application $app) + public function register(Container $app) { $app['logger'] = function () use ($app) { return $app['monolog']; @@ -41,17 +46,17 @@ public function register(Application $app) $app['monolog.logger.class'] = $bridge ? 'Symfony\Bridge\Monolog\Logger' : 'Monolog\Logger'; - $app['monolog'] = $app->share(function ($app) { + $app['monolog'] = function ($app) { $log = new $app['monolog.logger.class']($app['monolog.name']); $log->pushHandler($app['monolog.handler']); - if ($app['debug'] && isset($app['monolog.handler.debug'])) { + if (isset($app['debug']) && $app['debug'] && isset($app['monolog.handler.debug'])) { $log->pushHandler($app['monolog.handler.debug']); } return $log; - }); + }; $app['monolog.handler'] = function () use ($app) { $level = MonologServiceProvider::translateLevel($app['monolog.level']); @@ -63,9 +68,9 @@ public function register(Application $app) return Logger::DEBUG; }; - $app['monolog.listener'] = $app->share(function () use ($app) { + $app['monolog.listener'] = function () use ($app) { return new LogListener($app['logger']); - }); + }; $app['monolog.name'] = 'myapp'; } diff --git a/src/Silex/Provider/RememberMeServiceProvider.php b/src/Silex/Provider/RememberMeServiceProvider.php index 07d30f7f5..98a0db3ae 100644 --- a/src/Silex/Provider/RememberMeServiceProvider.php +++ b/src/Silex/Provider/RememberMeServiceProvider.php @@ -11,8 +11,10 @@ namespace Silex\Provider; -use Silex\Application; -use Silex\ServiceProviderInterface; +use Pimple\Container; +use Pimple\ServiceProviderInterface; +use Silex\Api\EventListenerProviderInterface; +use Symfony\Component\EventDispatcher\EventDispatcherInterface; use Symfony\Component\Security\Core\Authentication\Provider\RememberMeAuthenticationProvider; use Symfony\Component\Security\Http\Firewall\RememberMeListener; use Symfony\Component\Security\Http\RememberMe\TokenBasedRememberMeServices; @@ -23,13 +25,17 @@ * * @author Jérôme Tamarelle */ -class RememberMeServiceProvider implements ServiceProviderInterface +class RememberMeServiceProvider implements ServiceProviderInterface, EventListenerProviderInterface { - public function register(Application $app) + public function register(Container $app) { - $app['security.remember_me.response_listener'] = $app->share(function () { + $app['security.remember_me.response_listener'] = function ($app) { + if (!isset($app['security'])) { + throw new \LogicException('You must register the SecurityServiceProvider to use the RememberMeServiceProvider'); + } + return new ResponseListener(); - }); + }; $app['security.authentication_listener.factory.remember_me'] = $app->protect(function ($name, $options) use ($app) { if (empty($options['key'])) { @@ -57,7 +63,7 @@ public function register(Application $app) }); $app['security.remember_me.service._proto'] = $app->protect(function ($providerKey, $options) use ($app) { - return $app->share(function () use ($providerKey, $options, $app) { + return function () use ($providerKey, $options, $app) { $options = array_replace(array( 'name' => 'REMEMBERME', 'lifetime' => 31536000, @@ -69,36 +75,32 @@ public function register(Application $app) 'remember_me_parameter' => '_remember_me', ), $options); - return new TokenBasedRememberMeServices(array($app['security.user_provider.'.$providerKey]), $options['key'], $providerKey, $options, $app['logger']); - }); + return new TokenBasedRememberMeServices(array($app['security.user_provider.'.$providerKey]), $options['key'], $providerKey, $options, isset($app['logger']) ? $app['logger'] : null); + }; }); $app['security.authentication_listener.remember_me._proto'] = $app->protect(function ($providerKey) use ($app) { - return $app->share(function () use ($app, $providerKey) { + return function () use ($app, $providerKey) { $listener = new RememberMeListener( $app['security'], $app['security.remember_me.service.'.$providerKey], $app['security.authentication_manager'], - $app['logger'] + isset($app['logger']) ? $app['logger'] : null ); return $listener; - }); + }; }); $app['security.authentication_provider.remember_me._proto'] = $app->protect(function ($name, $options) use ($app) { - return $app->share(function () use ($app, $name, $options) { + return function () use ($app, $name, $options) { return new RememberMeAuthenticationProvider($app['security.user_checker'], $options['key'], $name); - }); + }; }); } - public function boot(Application $app) + public function subscribe(Container $app, EventDispatcherInterface $dispatcher) { - if (!isset($app['security'])) { - throw new \LogicException('You must register the SecurityServiceProvider to use the RememberMeServiceProvider'); - } - - $app['dispatcher']->addSubscriber($app['security.remember_me.response_listener']); + $dispatcher->addSubscriber($app['security.remember_me.response_listener']); } } diff --git a/src/Silex/LazyUrlMatcher.php b/src/Silex/Provider/Routing/LazyUrlMatcher.php similarity index 97% rename from src/Silex/LazyUrlMatcher.php rename to src/Silex/Provider/Routing/LazyUrlMatcher.php index 9cdd3bdd5..6701b6883 100644 --- a/src/Silex/LazyUrlMatcher.php +++ b/src/Silex/Provider/Routing/LazyUrlMatcher.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace Silex; +namespace Silex\Provider\Routing; use Symfony\Component\Routing\RequestContext as SymfonyRequestContext; use Symfony\Component\Routing\Matcher\UrlMatcherInterface; diff --git a/src/Silex/RedirectableUrlMatcher.php b/src/Silex/Provider/Routing/RedirectableUrlMatcher.php similarity index 97% rename from src/Silex/RedirectableUrlMatcher.php rename to src/Silex/Provider/Routing/RedirectableUrlMatcher.php index c0373c1cd..357bcbd1e 100644 --- a/src/Silex/RedirectableUrlMatcher.php +++ b/src/Silex/Provider/Routing/RedirectableUrlMatcher.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace Silex; +namespace Silex\Provider\Routing; use Symfony\Component\HttpFoundation\RedirectResponse; use Symfony\Component\Routing\Matcher\RedirectableUrlMatcher as BaseRedirectableUrlMatcher; diff --git a/src/Silex/Provider/RoutingServiceProvider.php b/src/Silex/Provider/RoutingServiceProvider.php new file mode 100644 index 000000000..5d286f2ff --- /dev/null +++ b/src/Silex/Provider/RoutingServiceProvider.php @@ -0,0 +1,63 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Silex\Provider; + +use Pimple\Container; +use Pimple\ServiceProviderInterface; +use Silex\Api\EventListenerProviderInterface; +use Silex\Provider\Routing\RedirectableUrlMatcher; +use Silex\Provider\Routing\LazyUrlMatcher; +use Symfony\Component\Routing\Generator\UrlGenerator; +use Symfony\Component\Routing\RequestContext; +use Symfony\Component\HttpKernel\EventListener\RouterListener; +use Symfony\Component\EventDispatcher\EventDispatcherInterface; + +/** + * Symfony Routing component Provider. + * + * @author Fabien Potencier + */ +class RoutingServiceProvider implements ServiceProviderInterface, EventListenerProviderInterface +{ + public function register(Container $app) + { + $app['url_generator'] = function ($app) { + return new UrlGenerator($app['routes'], $app['request_context']); + }; + + $app['url_matcher'] = function () use ($app) { + return new RedirectableUrlMatcher($app['routes'], $app['request_context']); + }; + + $app['request_context'] = function () use ($app) { + $context = new RequestContext(); + + $context->setHttpPort(isset($app['request.http_port']) ? $app['request.http_port'] : 80); + $context->setHttpsPort(isset($app['request.https_port']) ? $app['request.https_port'] : 443); + + return $context; + }; + + $app['routing.listener'] = function () use ($app) { + $urlMatcher = new LazyUrlMatcher(function () use ($app) { + return $app['url_matcher']; + }); + + return new RouterListener($urlMatcher, $app['request_context'], isset($app['logger']) ? $app['logger'] : null, $app['request_stack']); + }; + } + + public function subscribe(Container $app, EventDispatcherInterface $dispatcher) + { + $dispatcher->addSubscriber($app['routing.listener']); + } +} diff --git a/src/Silex/Provider/SecurityServiceProvider.php b/src/Silex/Provider/SecurityServiceProvider.php index 4ed7c385d..8bcfc4300 100644 --- a/src/Silex/Provider/SecurityServiceProvider.php +++ b/src/Silex/Provider/SecurityServiceProvider.php @@ -11,8 +11,13 @@ namespace Silex\Provider; +use Pimple\Container; +use Pimple\ServiceProviderInterface; use Silex\Application; -use Silex\ServiceProviderInterface; +use Silex\Api\BootableProviderInterface; +use Silex\Api\ControllerProviderInterface; +use Silex\Api\EventListenerProviderInterface; +use Symfony\Component\EventDispatcher\EventDispatcherInterface; use Symfony\Component\HttpFoundation\RequestMatcher; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\Security\Core\SecurityContext; @@ -57,11 +62,11 @@ * * @author Fabien Potencier */ -class SecurityServiceProvider implements ServiceProviderInterface +class SecurityServiceProvider implements ServiceProviderInterface, EventListenerProviderInterface, ControllerProviderInterface, BootableProviderInterface { protected $fakeRoutes; - public function register(Application $app) + public function register(Container $app) { // used to register routes for login_check and logout $this->fakeRoutes = array(); @@ -72,54 +77,57 @@ public function register(Application $app) $app['security.access_rules'] = array(); $app['security.hide_user_not_found'] = true; - $app['security'] = $app->share(function ($app) { + $app['security'] = function ($app) { return new SecurityContext($app['security.authentication_manager'], $app['security.access_manager']); - }); + }; - $app['security.authentication_manager'] = $app->share(function ($app) { + $app['security.authentication_manager'] = function ($app) { $manager = new AuthenticationProviderManager($app['security.authentication_providers']); $manager->setEventDispatcher($app['dispatcher']); return $manager; - }); + }; // by default, all users use the digest encoder - $app['security.encoder_factory'] = $app->share(function ($app) { + $app['security.encoder_factory'] = function ($app) { return new EncoderFactory(array( 'Symfony\Component\Security\Core\User\UserInterface' => $app['security.encoder.digest'], )); - }); + }; - $app['security.encoder.digest'] = $app->share(function ($app) { + $app['security.encoder.digest'] = function ($app) { return new MessageDigestPasswordEncoder(); - }); + }; - $app['security.user_checker'] = $app->share(function ($app) { + $app['security.user_checker'] = function ($app) { return new UserChecker(); - }); + }; - $app['security.access_manager'] = $app->share(function ($app) { + $app['security.access_manager'] = function ($app) { return new AccessDecisionManager($app['security.voters']); - }); + }; - $app['security.voters'] = $app->share(function ($app) { + $app['security.voters'] = function ($app) { return array( new RoleHierarchyVoter(new RoleHierarchy($app['security.role_hierarchy'])), new AuthenticatedVoter($app['security.trust_resolver']), ); - }); + }; - $app['security.firewall'] = $app->share(function ($app) { + $app['security.firewall'] = function ($app) { return new Firewall($app['security.firewall_map'], $app['dispatcher']); - }); + }; - $app['security.channel_listener'] = $app->share(function ($app) { + $app['security.channel_listener'] = function ($app) { return new ChannelListener( $app['security.access_map'], - new RetryAuthenticationEntryPoint($app['request.http_port'], $app['request.https_port']), - $app['logger'] + new RetryAuthenticationEntryPoint( + isset($app['request.http_port']) ? $app['request.http_port'] : 80, + isset($app['request.https_port']) ? $app['request.https_port'] : 443 + ), + isset($app['logger']) ? $app['logger'] : null ); - }); + }; // generate the build-in authentication factories foreach (array('logout', 'pre_auth', 'form', 'http', 'remember_me', 'anonymous') as $type) { @@ -153,7 +161,7 @@ public function register(Application $app) }); } - $app['security.firewall_map'] = $app->share(function ($app) { + $app['security.firewall_map'] = function ($app) { $positions = array('logout', 'pre_auth', 'form', 'http', 'remember_me', 'anonymous'); $providers = array(); $configs = array(); @@ -267,19 +275,19 @@ public function register(Application $app) } return $map; - }); + }; - $app['security.access_listener'] = $app->share(function ($app) { + $app['security.access_listener'] = function ($app) { return new AccessListener( $app['security'], $app['security.access_manager'], $app['security.access_map'], $app['security.authentication_manager'], - $app['logger'] + isset($app['logger']) ? $app['logger'] : null ); - }); + }; - $app['security.access_map'] = $app->share(function ($app) { + $app['security.access_map'] = function ($app) { $map = new AccessMap(); foreach ($app['security.access_rules'] as $rule) { @@ -291,19 +299,19 @@ public function register(Application $app) } return $map; - }); + }; - $app['security.trust_resolver'] = $app->share(function ($app) { + $app['security.trust_resolver'] = function ($app) { return new AuthenticationTrustResolver('Symfony\Component\Security\Core\Authentication\Token\AnonymousToken', 'Symfony\Component\Security\Core\Authentication\Token\RememberMeToken'); - }); + }; - $app['security.session_strategy'] = $app->share(function ($app) { + $app['security.session_strategy'] = function ($app) { return new SessionAuthenticationStrategy('migrate'); - }); + }; - $app['security.http_utils'] = $app->share(function ($app) { + $app['security.http_utils'] = function ($app) { return new HttpUtils(isset($app['url_generator']) ? $app['url_generator'] : null, $app['url_matcher']); - }); + }; $app['security.last_error'] = $app->protect(function (Request $request) { if ($request->attributes->has(SecurityContextInterface::AUTHENTICATION_ERROR)) { @@ -322,30 +330,30 @@ public function register(Application $app) // prototypes (used by the Firewall Map) $app['security.context_listener._proto'] = $app->protect(function ($providerKey, $userProviders) use ($app) { - return $app->share(function () use ($app, $userProviders, $providerKey) { + return function () use ($app, $userProviders, $providerKey) { return new ContextListener( $app['security'], $userProviders, $providerKey, - $app['logger'], + isset($app['logger']) ? $app['logger'] : null, $app['dispatcher'] ); - }); + }; }); $app['security.user_provider.inmemory._proto'] = $app->protect(function ($params) use ($app) { - return $app->share(function () use ($app, $params) { + return function () use ($app, $params) { $users = array(); foreach ($params as $name => $user) { $users[$name] = array('roles' => (array) $user[0], 'password' => $user[1]); } return new InMemoryUserProvider($users); - }); + }; }); $app['security.exception_listener._proto'] = $app->protect(function ($entryPoint, $name) use ($app) { - return $app->share(function () use ($app, $entryPoint, $name) { + return function () use ($app, $entryPoint, $name) { return new ExceptionListener( $app['security'], $app['security.trust_resolver'], @@ -354,13 +362,13 @@ public function register(Application $app) $app[$entryPoint], null, // errorPage null, // AccessDeniedHandlerInterface - $app['logger'] + isset($app['logger']) ? $app['logger'] : null ); - }); + }; }); $app['security.authentication.success_handler._proto'] = $app->protect(function ($name, $options) use ($app) { - return $app->share(function () use ($name, $options, $app) { + return function () use ($name, $options, $app) { $handler = new DefaultAuthenticationSuccessHandler( $app['security.http_utils'], $options @@ -368,22 +376,22 @@ public function register(Application $app) $handler->setProviderKey($name); return $handler; - }); + }; }); $app['security.authentication.failure_handler._proto'] = $app->protect(function ($name, $options) use ($app) { - return $app->share(function () use ($name, $options, $app) { + return function () use ($name, $options, $app) { return new DefaultAuthenticationFailureHandler( $app, $app['security.http_utils'], $options, - $app['logger'] + isset($app['logger']) ? $app['logger'] : null ); - }); + }; }); $app['security.authentication_listener.form._proto'] = $app->protect(function ($name, $options) use ($app, $that) { - return $app->share(function () use ($app, $name, $options, $that) { + return function () use ($app, $name, $options, $that) { $that->addFakeRoute( 'match', $tmp = isset($options['check_path']) ? $options['check_path'] : '/login_check', @@ -409,46 +417,46 @@ public function register(Application $app) $app['security.authentication.success_handler.'.$name], $app['security.authentication.failure_handler.'.$name], $options, - $app['logger'], + isset($app['logger']) ? $app['logger'] : null, $app['dispatcher'], isset($options['with_csrf']) && $options['with_csrf'] && isset($app['form.csrf_provider']) ? $app['form.csrf_provider'] : null ); - }); + }; }); $app['security.authentication_listener.http._proto'] = $app->protect(function ($providerKey, $options) use ($app) { - return $app->share(function () use ($app, $providerKey, $options) { + return function () use ($app, $providerKey, $options) { return new BasicAuthenticationListener( $app['security'], $app['security.authentication_manager'], $providerKey, $app['security.entry_point.'.$providerKey.'.http'], - $app['logger'] + isset($app['logger']) ? $app['logger'] : null ); - }); + }; }); $app['security.authentication_listener.anonymous._proto'] = $app->protect(function ($providerKey, $options) use ($app) { - return $app->share(function () use ($app, $providerKey, $options) { + return function () use ($app, $providerKey, $options) { return new AnonymousAuthenticationListener( $app['security'], $providerKey, - $app['logger'] + isset($app['logger']) ? $app['logger'] : null ); - }); + }; }); $app['security.authentication.logout_handler._proto'] = $app->protect(function ($name, $options) use ($app) { - return $app->share(function () use ($name, $options, $app) { + return function () use ($name, $options, $app) { return new DefaultLogoutSuccessHandler( $app['security.http_utils'], isset($options['target_url']) ? $options['target_url'] : '/' ); - }); + }; }); $app['security.authentication_listener.logout._proto'] = $app->protect(function ($name, $options) use ($app, $that) { - return $app->share(function () use ($app, $name, $options, $that) { + return function () use ($app, $name, $options, $that) { $that->addFakeRoute( 'get', $tmp = isset($options['logout_path']) ? $options['logout_path'] : '/logout', @@ -470,42 +478,42 @@ public function register(Application $app) $listener->addHandler(new SessionLogoutHandler()); return $listener; - }); + }; }); $app['security.authentication_listener.switch_user._proto'] = $app->protect(function ($name, $options) use ($app, $that) { - return $app->share(function () use ($app, $name, $options, $that) { + return function () use ($app, $name, $options, $that) { return new SwitchUserListener( $app['security'], $app['security.user_provider.'.$name], $app['security.user_checker'], $name, $app['security.access_manager'], - $app['logger'], + isset($app['logger']) ? $app['logger'] : null, isset($options['parameter']) ? $options['parameter'] : '_switch_user', isset($options['role']) ? $options['role'] : 'ROLE_ALLOWED_TO_SWITCH', $app['dispatcher'] ); - }); + }; }); $app['security.entry_point.form._proto'] = $app->protect(function ($name, array $options) use ($app) { - return $app->share(function () use ($app, $options) { + return function () use ($app, $options) { $loginPath = isset($options['login_path']) ? $options['login_path'] : '/login'; $useForward = isset($options['use_forward']) ? $options['use_forward'] : false; return new FormAuthenticationEntryPoint($app, $app['security.http_utils'], $loginPath, $useForward); - }); + }; }); $app['security.entry_point.http._proto'] = $app->protect(function ($name, array $options) use ($app) { - return $app->share(function () use ($app, $name, $options) { + return function () use ($app, $name, $options) { return new BasicAuthenticationEntryPoint(isset($options['real_name']) ? $options['real_name'] : 'Secured'); - }); + }; }); $app['security.authentication_provider.dao._proto'] = $app->protect(function ($name) use ($app) { - return $app->share(function () use ($app, $name) { + return function () use ($app, $name) { return new DaoAuthenticationProvider( $app['security.user_provider.'.$name], $app['security.user_checker'], @@ -513,19 +521,19 @@ public function register(Application $app) $app['security.encoder_factory'], $app['security.hide_user_not_found'] ); - }); + }; }); $app['security.authentication_provider.anonymous._proto'] = $app->protect(function ($name) use ($app) { - return $app->share(function () use ($app, $name) { + return function () use ($app, $name) { return new AnonymousAuthenticationProvider($name); - }); + }; }); if (isset($app['validator'])) { - $app['security.validator.user_password_validator'] = $app->share(function ($app) { + $app['security.validator.user_password_validator'] = function ($app) { return new UserPasswordValidator($app['security'], $app['security.encoder_factory']); - }); + }; if (!isset($app['validator.validator_service_ids'])) { $app['validator.validator_service_ids'] = array(); @@ -535,15 +543,26 @@ public function register(Application $app) } } - public function boot(Application $app) + public function subscribe(Container $app, EventDispatcherInterface $dispatcher) { - $app['dispatcher']->addSubscriber($app['security.firewall']); + $dispatcher->addSubscriber($app['security.firewall']); + } + public function connect(Application $app) + { + $controllers = $app['controllers_factory']; foreach ($this->fakeRoutes as $route) { list($method, $pattern, $name) = $route; - $app->$method($pattern)->run(null)->bind($name); + $controllers->$method($pattern)->run(null)->bind($name); } + + return $controllers; + } + + public function boot(Application $app) + { + $app->mount('/', $this->connect($app)); } public function addFakeRoute($method, $pattern, $name) diff --git a/src/Silex/Provider/SerializerServiceProvider.php b/src/Silex/Provider/SerializerServiceProvider.php index 09d2ee698..a8aec3449 100644 --- a/src/Silex/Provider/SerializerServiceProvider.php +++ b/src/Silex/Provider/SerializerServiceProvider.php @@ -11,8 +11,8 @@ namespace Silex\Provider; -use Silex\Application; -use Silex\ServiceProviderInterface; +use Pimple\Container; +use Pimple\ServiceProviderInterface; use Symfony\Component\Serializer\Serializer; use Symfony\Component\Serializer\Encoder\JsonEncoder; use Symfony\Component\Serializer\Encoder\XmlEncoder; @@ -33,31 +33,20 @@ class SerializerServiceProvider implements ServiceProviderInterface * This method registers a serializer service. {@link http://api.symfony.com/master/Symfony/Component/Serializer/Serializer.html * The service is provided by the Symfony Serializer component}. * - * @param Silex\Application $app + * @param Pimple $app */ - public function register(Application $app) + public function register(Container $app) { - $app['serializer'] = $app->share(function () use ($app) { + $app['serializer'] = function () use ($app) { return new Serializer($app['serializer.normalizers'], $app['serializer.encoders']); - }); + }; - $app['serializer.encoders'] = $app->share(function () { + $app['serializer.encoders'] = function () { return array(new JsonEncoder(), new XmlEncoder()); - }); + }; - $app['serializer.normalizers'] = $app->share(function () { + $app['serializer.normalizers'] = function () { return array(new CustomNormalizer(), new GetSetMethodNormalizer()); - }); - } - - /** - * {@inheritDoc} - * - * This provider does not execute any code when booting. - * - * @param Silex\Application $app - */ - public function boot(Application $app) - { + }; } } diff --git a/src/Silex/Provider/ServiceControllerServiceProvider.php b/src/Silex/Provider/ServiceControllerServiceProvider.php index a35a0344c..1c38adc9c 100644 --- a/src/Silex/Provider/ServiceControllerServiceProvider.php +++ b/src/Silex/Provider/ServiceControllerServiceProvider.php @@ -11,21 +11,16 @@ namespace Silex\Provider; -use Silex\Application; -use Silex\ServiceProviderInterface; +use Pimple\Container; +use Pimple\ServiceProviderInterface; use Silex\ServiceControllerResolver; class ServiceControllerServiceProvider implements ServiceProviderInterface { - public function register(Application $app) + public function register(Container $app) { - $app['resolver'] = $app->share($app->extend('resolver', function ($resolver, $app) { + $app->extend('resolver', function ($resolver, $app) { return new ServiceControllerResolver($resolver, $app['callback_resolver']); - })); - } - - public function boot(Application $app) - { - // noop + }); } } diff --git a/src/Silex/Provider/Session/SessionListener.php b/src/Silex/Provider/Session/SessionListener.php new file mode 100644 index 000000000..5827a9da7 --- /dev/null +++ b/src/Silex/Provider/Session/SessionListener.php @@ -0,0 +1,39 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Silex\Provider\Session; + +use Pimple\Container; +use Symfony\Component\HttpKernel\EventListener\SessionListener as BaseSessionListener; + +/** + * Sets the session in the request. + * + * @author Fabien Potencier + */ +class SessionListener extends BaseSessionListener +{ + private $app; + + public function __construct(Container $app) + { + $this->app = $app; + } + + protected function getSession() + { + if (!isset($this->app['session'])) { + return null; + } + + return $this->app['session']; + } +} diff --git a/src/Silex/Provider/Session/TestSessionListener.php b/src/Silex/Provider/Session/TestSessionListener.php new file mode 100644 index 000000000..d82a3ddb6 --- /dev/null +++ b/src/Silex/Provider/Session/TestSessionListener.php @@ -0,0 +1,39 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Silex\Provider\Session; + +use Pimple\Container; +use Symfony\Component\HttpKernel\EventListener\TestSessionListener as BaseTestSessionListener; + +/** + * Simulates sessions for testing purpose. + * + * @author Fabien Potencier + */ +class TestSessionListener extends BaseTestSessionListener +{ + private $app; + + public function __construct(Container $app) + { + $this->app = $app; + } + + protected function getSession() + { + if (!isset($this->app['session'])) { + return null; + } + + return $this->app['session']; + } +} diff --git a/src/Silex/Provider/SessionServiceProvider.php b/src/Silex/Provider/SessionServiceProvider.php index dcd94c026..4c0846197 100644 --- a/src/Silex/Provider/SessionServiceProvider.php +++ b/src/Silex/Provider/SessionServiceProvider.php @@ -11,34 +11,33 @@ namespace Silex\Provider; -use Silex\Application; -use Silex\ServiceProviderInterface; +use Pimple\Container; +use Pimple\ServiceProviderInterface; +use Silex\Api\EventListenerProviderInterface; +use Silex\Provider\Session\SessionListener; +use Silex\Provider\Session\TestSessionListener; +use Symfony\Component\EventDispatcher\EventDispatcherInterface; use Symfony\Component\HttpFoundation\Session\Storage\Handler\NativeFileSessionHandler; use Symfony\Component\HttpFoundation\Session\Storage\NativeSessionStorage; use Symfony\Component\HttpFoundation\Session\Storage\MockFileSessionStorage; use Symfony\Component\HttpFoundation\Session\Session; -use Symfony\Component\HttpFoundation\Cookie; -use Symfony\Component\HttpKernel\HttpKernelInterface; -use Symfony\Component\HttpKernel\KernelEvents; -use Symfony\Component\HttpKernel\Event\FilterResponseEvent; -use Symfony\Component\HttpKernel\Event\GetResponseEvent; /** * Symfony HttpFoundation component Provider for sessions. * * @author Fabien Potencier */ -class SessionServiceProvider implements ServiceProviderInterface +class SessionServiceProvider implements ServiceProviderInterface, EventListenerProviderInterface { private $app; - public function register(Application $app) + public function register(Container $app) { $this->app = $app; $app['session.test'] = false; - $app['session'] = $app->share(function ($app) { + $app['session'] = function ($app) { if (!isset($app['session.storage'])) { if ($app['session.test']) { $app['session.storage'] = $app['session.storage.test']; @@ -48,77 +47,42 @@ public function register(Application $app) } return new Session($app['session.storage']); - }); + }; - $app['session.storage.handler'] = $app->share(function ($app) { + $app['session.storage.handler'] = function ($app) { return new NativeFileSessionHandler($app['session.storage.save_path']); - }); + }; - $app['session.storage.native'] = $app->share(function ($app) { + $app['session.storage.native'] = function ($app) { return new NativeSessionStorage( $app['session.storage.options'], $app['session.storage.handler'] ); - }); + }; - $app['session.storage.test'] = $app->share(function () { + $app['session.listener'] = function ($app) { + return new SessionListener($app); + }; + + $app['session.storage.test'] = function () { return new MockFileSessionStorage(); - }); + }; + + $app['session.listener.test'] = function ($app) { + return new TestSessionListener($app); + }; $app['session.storage.options'] = array(); $app['session.default_locale'] = 'en'; $app['session.storage.save_path'] = null; } - public function onEarlyKernelRequest(GetResponseEvent $event) - { - $event->getRequest()->setSession($this->app['session']); - } - - public function onKernelRequest(GetResponseEvent $event) - { - if (HttpKernelInterface::MASTER_REQUEST !== $event->getRequestType()) { - return; - } - - // bootstrap the session - if (!isset($this->app['session'])) { - return; - } - - $session = $this->app['session']; - $cookies = $event->getRequest()->cookies; - - if ($cookies->has($session->getName())) { - $session->setId($cookies->get($session->getName())); - } else { - $session->migrate(false); - } - } - - public function onKernelResponse(FilterResponseEvent $event) - { - if (HttpKernelInterface::MASTER_REQUEST !== $event->getRequestType()) { - return; - } - - $session = $event->getRequest()->getSession(); - if ($session && $session->isStarted()) { - $session->save(); - - $params = session_get_cookie_params(); - - $event->getResponse()->headers->setCookie(new Cookie($session->getName(), $session->getId(), 0 === $params['lifetime'] ? 0 : time() + $params['lifetime'], $params['path'], $params['domain'], $params['secure'], $params['httponly'])); - } - } - - public function boot(Application $app) + public function subscribe(Container $app, EventDispatcherInterface $dispatcher) { - $app['dispatcher']->addListener(KernelEvents::REQUEST, array($this, 'onEarlyKernelRequest'), 128); + $dispatcher->addSubscriber($app['session.listener']); if ($app['session.test']) { - $app['dispatcher']->addListener(KernelEvents::REQUEST, array($this, 'onKernelRequest'), 192); - $app['dispatcher']->addListener(KernelEvents::RESPONSE, array($this, 'onKernelResponse'), -128); + $app['dispatcher']->addSubscriber($app['session.listener.test']); } } } diff --git a/src/Silex/Provider/SwiftmailerServiceProvider.php b/src/Silex/Provider/SwiftmailerServiceProvider.php index 7ca88c638..dad82f791 100644 --- a/src/Silex/Provider/SwiftmailerServiceProvider.php +++ b/src/Silex/Provider/SwiftmailerServiceProvider.php @@ -11,37 +11,41 @@ namespace Silex\Provider; -use Silex\Application; -use Silex\ServiceProviderInterface; +use Pimple\Container; +use Pimple\ServiceProviderInterface; +use Silex\Api\EventListenerProviderInterface; +use Symfony\Component\EventDispatcher\EventDispatcherInterface; +use Symfony\Component\HttpKernel\KernelEvents; +use Symfony\Component\HttpKernel\Event\PostResponseEvent; /** * Swiftmailer Provider. * * @author Fabien Potencier */ -class SwiftmailerServiceProvider implements ServiceProviderInterface +class SwiftmailerServiceProvider implements ServiceProviderInterface, EventListenerProviderInterface { - public function register(Application $app) + public function register(Container $app) { $app['swiftmailer.options'] = array(); $app['mailer.initialized'] = false; - $app['mailer'] = $app->share(function ($app) { + $app['mailer'] = function ($app) { $app['mailer.initialized'] = true; return new \Swift_Mailer($app['swiftmailer.spooltransport']); - }); + }; - $app['swiftmailer.spooltransport'] = $app->share(function ($app) { + $app['swiftmailer.spooltransport'] = function ($app) { return new \Swift_SpoolTransport($app['swiftmailer.spool']); - }); + }; - $app['swiftmailer.spool'] = $app->share(function ($app) { + $app['swiftmailer.spool'] = function ($app) { return new \Swift_MemorySpool(); - }); + }; - $app['swiftmailer.transport'] = $app->share(function ($app) { + $app['swiftmailer.transport'] = function ($app) { $transport = new \Swift_Transport_EsmtpTransport( $app['swiftmailer.transport.buffer'], array($app['swiftmailer.transport.authhandler']), @@ -65,28 +69,28 @@ public function register(Application $app) $transport->setAuthMode($options['auth_mode']); return $transport; - }); + }; - $app['swiftmailer.transport.buffer'] = $app->share(function () { + $app['swiftmailer.transport.buffer'] = function () { return new \Swift_Transport_StreamBuffer(new \Swift_StreamFilters_StringReplacementFilterFactory()); - }); + }; - $app['swiftmailer.transport.authhandler'] = $app->share(function () { + $app['swiftmailer.transport.authhandler'] = function () { return new \Swift_Transport_Esmtp_AuthHandler(array( new \Swift_Transport_Esmtp_Auth_CramMd5Authenticator(), new \Swift_Transport_Esmtp_Auth_LoginAuthenticator(), new \Swift_Transport_Esmtp_Auth_PlainAuthenticator(), )); - }); + }; - $app['swiftmailer.transport.eventdispatcher'] = $app->share(function () { + $app['swiftmailer.transport.eventdispatcher'] = function () { return new \Swift_Events_SimpleEventDispatcher(); - }); + }; } - public function boot(Application $app) + public function subscribe(Container $app, EventDispatcherInterface $dispatcher) { - $app->finish(function () use ($app) { + $dispatcher->addListener(KernelEvents::TERMINATE, function (PostResponseEvent $event) use ($app) { // To speed things up (by avoiding Swift Mailer initialization), flush // messages only if our mailer has been created (potentially used) if ($app['mailer.initialized']) { diff --git a/src/Silex/Translator.php b/src/Silex/Provider/Translation/Translator.php similarity index 76% rename from src/Silex/Translator.php rename to src/Silex/Provider/Translation/Translator.php index bc7eef82a..c7bff0388 100644 --- a/src/Silex/Translator.php +++ b/src/Silex/Provider/Translation/Translator.php @@ -9,13 +9,14 @@ * file that was distributed with this source code. */ -namespace Silex; +namespace Silex\Provider\Translation; +use Pimple\Container; use Symfony\Component\Translation\Translator as BaseTranslator; use Symfony\Component\Translation\MessageSelector; /** - * Translator that gets the current locale from the Silex application. + * Translator that gets the current locale from the container. * * @author Fabien Potencier */ @@ -23,7 +24,7 @@ class Translator extends BaseTranslator { protected $app; - public function __construct(Application $app, MessageSelector $selector) + public function __construct(Container $app, MessageSelector $selector) { $this->app = $app; diff --git a/src/Silex/Provider/TranslationServiceProvider.php b/src/Silex/Provider/TranslationServiceProvider.php index 730e82370..575cdc9c9 100644 --- a/src/Silex/Provider/TranslationServiceProvider.php +++ b/src/Silex/Provider/TranslationServiceProvider.php @@ -11,9 +11,9 @@ namespace Silex\Provider; -use Silex\Application; -use Silex\ServiceProviderInterface; -use Silex\Translator; +use Pimple\Container; +use Pimple\ServiceProviderInterface; +use Silex\Provider\Translation\Translator; use Symfony\Component\Translation\MessageSelector; use Symfony\Component\Translation\Loader\ArrayLoader; use Symfony\Component\Translation\Loader\XliffFileLoader; @@ -25,18 +25,15 @@ */ class TranslationServiceProvider implements ServiceProviderInterface { - public function register(Application $app) + public function register(Container $app) { - $app['translator'] = $app->share(function ($app) { - $translator = new Translator($app, $app['translator.message_selector']); - - // Handle deprecated 'locale_fallback' - if (isset($app['locale_fallback'])) { - $app['locale_fallbacks'] = (array) $app['locale_fallback']; + $app['translator'] = function ($app) { + if (!isset($app['locale'])) { + throw new \LogicException('You must register the LocaleServiceProvider to use the TranslationServiceProvider'); } + $translator = new Translator($app, $app['translator.message_selector']); $translator->setFallbackLocales($app['locale_fallbacks']); - $translator->addLoader('array', new ArrayLoader()); $translator->addLoader('xliff', new XliffFileLoader()); @@ -47,17 +44,13 @@ public function register(Application $app) } return $translator; - }); + }; - $app['translator.message_selector'] = $app->share(function () { + $app['translator.message_selector'] = function () { return new MessageSelector(); - }); + }; $app['translator.domains'] = array(); $app['locale_fallbacks'] = array('en'); } - - public function boot(Application $app) - { - } } diff --git a/src/Silex/Provider/TwigCoreExtension.php b/src/Silex/Provider/TwigCoreExtension.php deleted file mode 100644 index 06e41a0cc..000000000 --- a/src/Silex/Provider/TwigCoreExtension.php +++ /dev/null @@ -1,56 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Silex\Provider; - -use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\HttpKernel\HttpKernelInterface; - -/** - * Twig extension. - * - * @author Fabien Potencier - * - * @deprecated deprecated since 1.2, will be removed in 1.3. Use HttpFragmentServiceProvider instead - */ -class TwigCoreExtension extends \Twig_Extension -{ - public function getFunctions() - { - return array( - 'render' => new \Twig_Function_Method($this, 'render', array('needs_environment' => true, 'is_safe' => array('html'))), - ); - } - - public function render(\Twig_Environment $twig, $uri) - { - $globals = $twig->getGlobals(); - $request = $globals['app']['request']; - - $subRequest = Request::create($uri, 'get', array(), $request->cookies->all(), array(), $request->server->all()); - if ($request->getSession()) { - $subRequest->setSession($request->getSession()); - } - - $response = $globals['app']->handle($subRequest, HttpKernelInterface::SUB_REQUEST, false); - - if (!$response->isSuccessful()) { - throw new \RuntimeException(sprintf('Error when rendering "%s" (Status code is %s).', $request->getUri(), $response->getStatusCode())); - } - - return $response->getContent(); - } - - public function getName() - { - return 'silex'; - } -} diff --git a/src/Silex/Provider/TwigServiceProvider.php b/src/Silex/Provider/TwigServiceProvider.php index 1a4351927..948e1822c 100644 --- a/src/Silex/Provider/TwigServiceProvider.php +++ b/src/Silex/Provider/TwigServiceProvider.php @@ -11,8 +11,8 @@ namespace Silex\Provider; -use Silex\Application; -use Silex\ServiceProviderInterface; +use Pimple\Container; +use Pimple\ServiceProviderInterface; use Symfony\Bridge\Twig\Extension\RoutingExtension; use Symfony\Bridge\Twig\Extension\TranslationExtension; use Symfony\Bridge\Twig\Extension\FormExtension; @@ -28,26 +28,26 @@ */ class TwigServiceProvider implements ServiceProviderInterface { - public function register(Application $app) + public function register(Container $app) { $app['twig.options'] = array(); $app['twig.form.templates'] = array('form_div_layout.html.twig'); $app['twig.path'] = array(); $app['twig.templates'] = array(); - $app['twig'] = $app->share(function ($app) { + $app['twig'] = function ($app) { $app['twig.options'] = array_replace( array( - 'charset' => $app['charset'], - 'debug' => $app['debug'], - 'strict_variables' => $app['debug'], + 'charset' => isset($app['charset']) ? $app['charset'] : 'UTF-8', + 'debug' => isset($app['debug']) ? $app['debug'] : false, + 'strict_variables' => isset($app['debug']) ? $app['debug'] : false, ), $app['twig.options'] ); $twig = new \Twig_Environment($app['twig.loader'], $app['twig.options']); $twig->addGlobal('app', $app); - if ($app['debug']) { + if (isset($app['debug']) && $app['debug']) { $twig->addExtension(new \Twig_Extension_Debug()); } @@ -68,19 +68,16 @@ public function register(Application $app) $app['fragment.renderer.hinclude']->setTemplating($twig); $twig->addExtension(new HttpKernelExtension($app['fragment.handler'])); - } else { - // fallback for BC, to be removed in 1.3 - $twig->addExtension(new TwigCoreExtension()); } if (isset($app['form.factory'])) { - $app['twig.form.engine'] = $app->share(function ($app) { + $app['twig.form.engine'] = function ($app) { return new TwigRendererEngine($app['twig.form.templates']); - }); + }; - $app['twig.form.renderer'] = $app->share(function ($app) { + $app['twig.form.renderer'] = function ($app) { return new TwigRenderer($app['twig.form.engine'], $app['form.csrf_provider']); - }); + }; $twig->addExtension(new FormExtension($app['twig.form.renderer'])); @@ -92,25 +89,21 @@ public function register(Application $app) } return $twig; - }); + }; - $app['twig.loader.filesystem'] = $app->share(function ($app) { + $app['twig.loader.filesystem'] = function ($app) { return new \Twig_Loader_Filesystem($app['twig.path']); - }); + }; - $app['twig.loader.array'] = $app->share(function ($app) { + $app['twig.loader.array'] = function ($app) { return new \Twig_Loader_Array($app['twig.templates']); - }); + }; - $app['twig.loader'] = $app->share(function ($app) { + $app['twig.loader'] = function ($app) { return new \Twig_Loader_Chain(array( $app['twig.loader.array'], $app['twig.loader.filesystem'], )); - }); - } - - public function boot(Application $app) - { + }; } } diff --git a/src/Silex/Provider/UrlGeneratorServiceProvider.php b/src/Silex/Provider/UrlGeneratorServiceProvider.php deleted file mode 100644 index ccbd2e7bc..000000000 --- a/src/Silex/Provider/UrlGeneratorServiceProvider.php +++ /dev/null @@ -1,37 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Silex\Provider; - -use Silex\Application; -use Silex\ServiceProviderInterface; -use Symfony\Component\Routing\Generator\UrlGenerator; - -/** - * Symfony Routing component Provider for URL generation. - * - * @author Fabien Potencier - */ -class UrlGeneratorServiceProvider implements ServiceProviderInterface -{ - public function register(Application $app) - { - $app['url_generator'] = $app->share(function ($app) { - $app->flush(); - - return new UrlGenerator($app['routes'], $app['request_context']); - }); - } - - public function boot(Application $app) - { - } -} diff --git a/src/Silex/ConstraintValidatorFactory.php b/src/Silex/Provider/Validator/ConstraintValidatorFactory.php similarity index 87% rename from src/Silex/ConstraintValidatorFactory.php rename to src/Silex/Provider/Validator/ConstraintValidatorFactory.php index 1daf43667..223e1dd0c 100644 --- a/src/Silex/ConstraintValidatorFactory.php +++ b/src/Silex/Provider/Validator/ConstraintValidatorFactory.php @@ -9,8 +9,9 @@ * file that was distributed with this source code. */ -namespace Silex; +namespace Silex\Provider\Validator; +use Pimple\Container; use Symfony\Component\Validator\Constraint; use Symfony\Component\Validator\ConstraintValidatorFactoryInterface; use Symfony\Component\Validator\ConstraintValidator; @@ -24,7 +25,7 @@ class ConstraintValidatorFactory implements ConstraintValidatorFactoryInterface { /** - * @var \Pimple + * @var Container */ protected $container; @@ -41,10 +42,10 @@ class ConstraintValidatorFactory implements ConstraintValidatorFactoryInterface /** * Constructor * - * @param \Pimple $container DI container - * @param array $serviceNames Validator service names + * @param Container $container DI container + * @param array $serviceNames Validator service names */ - public function __construct(\Pimple $container, array $serviceNames = array()) + public function __construct(Container $container, array $serviceNames = array()) { $this->container = $container; $this->serviceNames = $serviceNames; diff --git a/src/Silex/Provider/ValidatorServiceProvider.php b/src/Silex/Provider/ValidatorServiceProvider.php index d670935cb..47ecbdb36 100644 --- a/src/Silex/Provider/ValidatorServiceProvider.php +++ b/src/Silex/Provider/ValidatorServiceProvider.php @@ -11,9 +11,9 @@ namespace Silex\Provider; -use Silex\Application; -use Silex\ServiceProviderInterface; -use Silex\ConstraintValidatorFactory; +use Pimple\Container; +use Pimple\ServiceProviderInterface; +use Silex\Provider\Validator\ConstraintValidatorFactory; use Symfony\Component\Validator\Validator; use Symfony\Component\Validator\DefaultTranslator; use Symfony\Component\Validator\Mapping\ClassMetadataFactory; @@ -26,9 +26,9 @@ */ class ValidatorServiceProvider implements ServiceProviderInterface { - public function register(Application $app) + public function register(Container $app) { - $app['validator'] = $app->share(function ($app) { + $app['validator'] = function ($app) { $r = new \ReflectionClass('Symfony\Component\Validator\Validator'); if (isset($app['translator'])) { @@ -42,24 +42,20 @@ public function register(Application $app) 'validators', $app['validator.object_initializers'] ); - }); + }; - $app['validator.mapping.class_metadata_factory'] = $app->share(function ($app) { + $app['validator.mapping.class_metadata_factory'] = function ($app) { return new ClassMetadataFactory(new StaticMethodLoader()); - }); + }; - $app['validator.validator_factory'] = $app->share(function () use ($app) { + $app['validator.validator_factory'] = function () use ($app) { $validators = isset($app['validator.validator_service_ids']) ? $app['validator.validator_service_ids'] : array(); return new ConstraintValidatorFactory($app, $validators); - }); + }; - $app['validator.object_initializers'] = $app->share(function ($app) { + $app['validator.object_initializers'] = function ($app) { return array(); - }); - } - - public function boot(Application $app) - { + }; } } diff --git a/src/Silex/Provider/composer.json b/src/Silex/Provider/composer.json new file mode 100644 index 000000000..93441c485 --- /dev/null +++ b/src/Silex/Provider/composer.json @@ -0,0 +1,32 @@ +{ + "minimum-stability": "dev", + "name": "silex/providers", + "description": "The Silex providers", + "keywords": ["microframework"], + "homepage": "http://silex.sensiolabs.org", + "license": "MIT", + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Igor Wiedler", + "email": "igor@wiedler.ch" + } + ], + "require": { + "php": ">=5.3.3", + "pimple/pimple": "~1.0", + "silex/api": "*" + }, + "autoload": { + "psr-0": { "Silex\\Provider": "" } + }, + "target-dir": "Silex/Provider", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + } +} diff --git a/src/Silex/Util/Compiler.php b/src/Silex/Util/Compiler.php deleted file mode 100644 index 2d2930d4c..000000000 --- a/src/Silex/Util/Compiler.php +++ /dev/null @@ -1,188 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Silex\Util; - -use Symfony\Component\Finder\Finder; -use Symfony\Component\Process\Process; - -/** - * The Compiler class compiles the Silex framework. - * - * This is deprecated. Use composer instead. - * - * @author Fabien Potencier - */ -class Compiler -{ - protected $version; - - /** - * Compiles the Silex source code into one single Phar file. - * - * @param string $pharFile Name of the output Phar file - */ - public function compile($pharFile = 'silex.phar') - { - if (file_exists($pharFile)) { - unlink($pharFile); - } - - $process = new Process('git log --pretty="%h %ci" -n1 HEAD'); - if ($process->run() > 0) { - throw new \RuntimeException('The git binary cannot be found.'); - } - $this->version = trim($process->getOutput()); - - $phar = new \Phar($pharFile, 0, 'silex.phar'); - $phar->setSignatureAlgorithm(\Phar::SHA1); - - $phar->startBuffering(); - - $root = __DIR__.'/../../..'; - - $finder = new Finder(); - $finder->files() - ->ignoreVCS(true) - ->name('*.php') - ->notName('Compiler.php') - ->exclude('Tests') - ->in($root.'/src') - ->in($root.'/vendor/pimple/pimple/lib') - ->in($root.'/vendor/symfony/event-dispatcher/Symfony/Component/EventDispatcher') - ->in($root.'/vendor/symfony/http-foundation/Symfony/Component/HttpFoundation') - ->in($root.'/vendor/symfony/http-kernel/Symfony/Component/HttpKernel') - ->in($root.'/vendor/symfony/routing/Symfony/Component/Routing') - ->in($root.'/vendor/symfony/browser-kit/Symfony/Component/BrowserKit') - ->in($root.'/vendor/symfony/css-selector/Symfony/Component/CssSelector') - ->in($root.'/vendor/symfony/dom-crawler/Symfony/Component/DomCrawler') - ; - - foreach ($finder as $file) { - $this->addFile($phar, $file); - } - - $this->addFile($phar, new \SplFileInfo($root.'/LICENSE'), false); - $this->addFile($phar, new \SplFileInfo($root.'/vendor/autoload.php')); - $this->addFile($phar, new \SplFileInfo($root.'/vendor/composer/ClassLoader.php')); - $this->addFile($phar, new \SplFileInfo($root.'/vendor/composer/autoload_namespaces.php')); - $this->addFile($phar, new \SplFileInfo($root.'/vendor/composer/autoload_classmap.php')); - - // Stubs - $phar->setStub($this->getStub()); - - $phar->stopBuffering(); - - unset($phar); - } - - protected function addFile(\Phar $phar, \SplFileInfo $file, $strip = true) - { - $path = str_replace(dirname(dirname(dirname(__DIR__))).DIRECTORY_SEPARATOR, '', $file->getRealPath()); - - $content = file_get_contents($file); - if ($strip) { - $content = self::stripWhitespace($content); - } - - $content = preg_replace("/const VERSION = '.*?';/", "const VERSION = '".$this->version."';", $content); - - $phar->addFromString($path, $content); - } - - protected function getStub() - { - return <<<'EOF' - - * - * This source file is subject to the MIT license that is bundled - * with this source code in the file LICENSE. - */ - -Phar::mapPhar('silex.phar'); - -require_once 'phar://silex.phar/vendor/autoload.php'; - -if ('cli' === php_sapi_name() && basename(__FILE__) === basename($_SERVER['argv'][0]) && isset($_SERVER['argv'][1])) { - switch ($_SERVER['argv'][1]) { - case 'update': - $remoteFilename = 'http://silex.sensiolabs.org/get/silex.phar'; - $localFilename = __DIR__.'/silex.phar'; - - file_put_contents($localFilename, file_get_contents($remoteFilename)); - break; - - case 'check': - $latest = trim(file_get_contents('http://silex.sensiolabs.org/get/version')); - - if ($latest != Silex\Application::VERSION) { - printf("A newer Silex version is available (%s).\n", $latest); - } else { - print("You are using the latest Silex version.\n"); - } - break; - - case 'version': - printf("Silex version %s\n", Silex\Application::VERSION); - break; - - default: - printf("Unknown command '%s' (available commands: version, check, and update).\n", $_SERVER['argv'][1]); - } - - exit(0); -} - -__HALT_COMPILER(); -EOF; - } - - /** - * Removes whitespace from a PHP source string while preserving line numbers. - * - * Based on Kernel::stripComments(), but keeps line numbers intact. - * - * @param string $source A PHP string - * - * @return string The PHP string with the whitespace removed - */ - public static function stripWhitespace($source) - { - if (!function_exists('token_get_all')) { - return $source; - } - - $output = ''; - foreach (token_get_all($source) as $token) { - if (is_string($token)) { - $output .= $token; - } elseif (in_array($token[0], array(T_COMMENT, T_DOC_COMMENT))) { - $output .= str_repeat("\n", substr_count($token[1], "\n")); - } elseif (T_WHITESPACE === $token[0]) { - // reduce wide spaces - $whitespace = preg_replace('{[ \t]+}', ' ', $token[1]); - // normalize newlines to \n - $whitespace = preg_replace('{(?:\r\n|\r|\n)}', "\n", $whitespace); - // trim leading spaces - $whitespace = preg_replace('{\n +}', "\n", $whitespace); - $output .= $whitespace; - } else { - $output .= $token[1]; - } - } - - return $output; - } -} diff --git a/tests/Silex/Tests/Application/MonologTraitTest.php b/tests/Silex/Tests/Application/MonologTraitTest.php index 91505c2a7..503e253dd 100644 --- a/tests/Silex/Tests/Application/MonologTraitTest.php +++ b/tests/Silex/Tests/Application/MonologTraitTest.php @@ -39,9 +39,9 @@ public function createApplication() { $app = new MonologApplication(); $app->register(new MonologServiceProvider(), array( - 'monolog.handler' => $app->share(function () use ($app) { + 'monolog.handler' => function () use ($app) { return new TestHandler($app['monolog.level']); - }), + }, )); return $app; diff --git a/tests/Silex/Tests/Application/UrlGeneratorTraitTest.php b/tests/Silex/Tests/Application/UrlGeneratorTraitTest.php index 04ab12c4b..c3359bdd7 100644 --- a/tests/Silex/Tests/Application/UrlGeneratorTraitTest.php +++ b/tests/Silex/Tests/Application/UrlGeneratorTraitTest.php @@ -12,7 +12,7 @@ namespace Silex\Tests\Application; use Silex\Application; -use Silex\Provider\UrlGeneratorServiceProvider; +use Silex\Provider\RoutingServiceProvider; /** * UrlGeneratorTrait test cases. @@ -25,7 +25,7 @@ class UrlGeneratorTraitTest extends \PHPUnit_Framework_TestCase { public function testUrl() { - $app = $this->createApplication(); + $app = new UrlGeneratorApplication(); $app['url_generator'] = $translator = $this->getMockBuilder('Symfony\Component\Routing\Generator\UrlGeneratorInterface')->disableOriginalConstructor()->getMock(); $translator->expects($this->once())->method('generate')->with('foo', array(), true); $app->url('foo'); @@ -33,17 +33,9 @@ public function testUrl() public function testPath() { - $app = $this->createApplication(); + $app = new UrlGeneratorApplication(); $app['url_generator'] = $translator = $this->getMockBuilder('Symfony\Component\Routing\Generator\UrlGeneratorInterface')->disableOriginalConstructor()->getMock(); $translator->expects($this->once())->method('generate')->with('foo', array(), false); $app->path('foo'); } - - public function createApplication() - { - $app = new UrlGeneratorApplication(); - $app->register(new UrlGeneratorServiceProvider()); - - return $app; - } } diff --git a/tests/Silex/Tests/ApplicationTest.php b/tests/Silex/Tests/ApplicationTest.php index 3068a15e0..97886607e 100644 --- a/tests/Silex/Tests/ApplicationTest.php +++ b/tests/Silex/Tests/ApplicationTest.php @@ -416,30 +416,6 @@ public function testNonResponseAndNonNullReturnFromRouteAfterMiddlewareShouldThr $app->handle(Request::create('/'), HttpKernelInterface::MASTER_REQUEST, false); } - /** - * @expectedException \RuntimeException - */ - public function testAccessingRequestOutsideOfScopeShouldThrowRuntimeException() - { - $app = new Application(); - - $request = $app['request']; - } - - /** - * @expectedException \RuntimeException - */ - public function testAccessingRequestOutsideOfScopeShouldThrowRuntimeExceptionAfterHandling() - { - $app = new Application(); - $app->get('/', function () { - return 'hello'; - }); - $app->handle(Request::create('/'), HttpKernelInterface::MASTER_REQUEST, false); - - $request = $app['request']; - } - public function testSubRequest() { $app = new Application(); @@ -453,31 +429,10 @@ public function testSubRequest() $this->assertEquals('foo', $app->handle(Request::create('/'))->getContent()); } - public function testSubRequestDoesNotReplaceMainRequestAfterHandling() - { - $mainRequest = Request::create('/'); - $subRequest = Request::create('/sub'); - - $app = new Application(); - $app->get('/sub', function (Request $request) { - return new Response('foo'); - }); - $app->get('/', function (Request $request) use ($subRequest, $app) { - $response = $app->handle($subRequest, HttpKernelInterface::SUB_REQUEST); - - // request in app must be the main request here - $response->setContent($response->getContent().' '.$app['request']->getPathInfo()); - - return $response; - }); - - $this->assertEquals('foo /', $app->handle($mainRequest)->getContent()); - } - public function testRegisterShouldReturnSelf() { $app = new Application(); - $provider = $this->getMock('Silex\ServiceProviderInterface'); + $provider = $this->getMock('Pimple\ServiceProviderInterface'); $this->assertSame($app, $app->register($provider)); } @@ -542,6 +497,18 @@ public function testRedirectDoesNotRaisePHPNoticesWhenMonologIsRegistered() $response = $app->handle(Request::create('/foo')); $this->assertEquals(301, $response->getStatusCode()); } + + public function testBeforeFilterOnMountedControllerGroupIsolatedToGroup() + { + $app = new Application(); + $app->match('/', function() { return new Response('ok'); }); + $mounted = $app['controllers_factory']; + $mounted->before(function() { return new Response('not ok'); }); + $app->mount('/group', $mounted); + + $response = $app->handle(Request::create('/')); + $this->assertEquals('ok', $response->getContent()); + } } class FooController diff --git a/tests/Silex/Tests/CallbackResolverTest.php b/tests/Silex/Tests/CallbackResolverTest.php index 87673a0fb..9d41ad5a6 100644 --- a/tests/Silex/Tests/CallbackResolverTest.php +++ b/tests/Silex/Tests/CallbackResolverTest.php @@ -11,13 +11,14 @@ namespace Silex\Tests; +use Pimple\Container; use Silex\CallbackResolver; class CallbackResolverTest extends \PHPUnit_Framework_Testcase { public function setup() { - $this->app = new \Pimple(); + $this->app = new Container(); $this->resolver = new CallbackResolver($this->app); } diff --git a/tests/Silex/Tests/CallbackServicesTests.php b/tests/Silex/Tests/CallbackServicesTests.php index c9d6afc9f..c644a925b 100644 --- a/tests/Silex/Tests/CallbackServicesTests.php +++ b/tests/Silex/Tests/CallbackServicesTests.php @@ -28,9 +28,9 @@ public function testCallbacksAsServices() { $app = new Application(); - $app['service'] = $app->share(function () { + $app['service'] = function () { return new self(); - }); + }; $app->before('service:beforeApp'); $app->after('service:afterApp'); diff --git a/tests/Silex/Tests/LazyDispatcherTest.php b/tests/Silex/Tests/LazyDispatcherTest.php index cfe690689..51d21d97f 100644 --- a/tests/Silex/Tests/LazyDispatcherTest.php +++ b/tests/Silex/Tests/LazyDispatcherTest.php @@ -22,11 +22,11 @@ public function beforeMiddlewareShouldNotCreateDispatcherEarly() $dispatcherCreated = false; $app = new Application(); - $app['dispatcher'] = $app->share($app->extend('dispatcher', function ($dispatcher, $app) use (&$dispatcherCreated) { + $app->extend('dispatcher', function ($dispatcher, $app) use (&$dispatcherCreated) { $dispatcherCreated = true; return $dispatcher; - })); + }); $app->before(function () {}); diff --git a/tests/Silex/Tests/LazyUrlMatcherTest.php b/tests/Silex/Tests/LazyUrlMatcherTest.php index fbd3f4ff2..ddb6d5fff 100644 --- a/tests/Silex/Tests/LazyUrlMatcherTest.php +++ b/tests/Silex/Tests/LazyUrlMatcherTest.php @@ -11,7 +11,7 @@ namespace Silex\Tests; -use Silex\LazyUrlMatcher; +use Silex\Provider\Routing\LazyUrlMatcher; /** * LazyUrlMatcher test case. diff --git a/tests/Silex/Tests/LocaleTest.php b/tests/Silex/Tests/LocaleTest.php index 483ea2647..ada57be41 100644 --- a/tests/Silex/Tests/LocaleTest.php +++ b/tests/Silex/Tests/LocaleTest.php @@ -12,6 +12,7 @@ namespace Silex\Tests; use Silex\Application; +use Silex\Provider\LocaleServiceProvider; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpKernel\HttpKernelInterface; @@ -25,17 +26,20 @@ class LocaleTest extends \PHPUnit_Framework_TestCase public function testLocale() { $app = new Application(); + $app->register(new LocaleServiceProvider()); $app->get('/', function (Request $request) { return $request->getLocale(); }); $response = $app->handle(Request::create('/')); $this->assertEquals('en', $response->getContent()); $app = new Application(); + $app->register(new LocaleServiceProvider()); $app['locale'] = 'fr'; $app->get('/', function (Request $request) { return $request->getLocale(); }); $response = $app->handle(Request::create('/')); $this->assertEquals('fr', $response->getContent()); $app = new Application(); + $app->register(new LocaleServiceProvider()); $app->get('/{_locale}', function (Request $request) { return $request->getLocale(); }); $response = $app->handle(Request::create('/es')); $this->assertEquals('es', $response->getContent()); @@ -44,6 +48,7 @@ public function testLocale() public function testLocaleInSubRequests() { $app = new Application(); + $app->register(new LocaleServiceProvider()); $app->get('/embed/{_locale}', function (Request $request) { return $request->getLocale(); }); $app->get('/{_locale}', function (Request $request) use ($app) { return $request->getLocale().$app->handle(Request::create('/embed/es'), HttpKernelInterface::SUB_REQUEST)->getContent().$request->getLocale(); @@ -52,6 +57,7 @@ public function testLocaleInSubRequests() $this->assertEquals('fresfr', $response->getContent()); $app = new Application(); + $app->register(new LocaleServiceProvider()); $app->get('/embed', function (Request $request) { return $request->getLocale(); }); $app->get('/{_locale}', function (Request $request) use ($app) { return $request->getLocale().$app->handle(Request::create('/embed'), HttpKernelInterface::SUB_REQUEST)->getContent().$request->getLocale(); @@ -64,6 +70,7 @@ public function testLocaleInSubRequests() public function testLocaleWithBefore() { $app = new Application(); + $app->register(new LocaleServiceProvider()); $app->before(function (Request $request) use ($app) { $request->setLocale('fr'); }); $app->get('/embed', function (Request $request) { return $request->getLocale(); }); $app->get('/', function (Request $request) use ($app) { diff --git a/tests/Silex/Tests/MiddlewareTest.php b/tests/Silex/Tests/MiddlewareTest.php index 3744fbd27..583cbbf16 100644 --- a/tests/Silex/Tests/MiddlewareTest.php +++ b/tests/Silex/Tests/MiddlewareTest.php @@ -191,8 +191,8 @@ public function testRequestShouldBePopulatedOnBefore() { $app = new Application(); - $app->before(function () use ($app) { - $app['project'] = $app['request']->get('project'); + $app->before(function (Request $request) use ($app) { + $app['project'] = $request->get('project'); }); $app->match('/foo/{project}', function () use ($app) { diff --git a/tests/Silex/Tests/Provider/FormServiceProviderTest.php b/tests/Silex/Tests/Provider/FormServiceProviderTest.php index 6d0f6501f..3759ad05d 100644 --- a/tests/Silex/Tests/Provider/FormServiceProviderTest.php +++ b/tests/Silex/Tests/Provider/FormServiceProviderTest.php @@ -35,11 +35,11 @@ public function testFormServiceProviderWillLoadTypeExtensions() $app->register(new FormServiceProvider()); - $app['form.type.extensions'] = $app->share($app->extend('form.type.extensions', function($extensions) { + $app->extend('form.type.extensions', function($extensions) { $extensions[] = new DummyFormTypeExtension(); return $extensions; - })); + }); $form = $app['form.factory']->createBuilder('form', array()) ->add('file', 'file', array('image_path' => 'webPath')) @@ -54,11 +54,11 @@ public function testFormServiceProviderWillLoadTypeGuessers() $app->register(new FormServiceProvider()); - $app['form.type.guessers'] = $app->share($app->extend('form.type.guessers', function($guessers) { + $app->extend('form.type.guessers', function($guessers) { $guessers[] = new FormTypeGuesserChain(array()); return $guessers; - })); + }); $this->assertInstanceOf('Symfony\Component\Form\FormFactory', $app['form.factory']); } @@ -78,9 +78,9 @@ public function testFormServiceProviderWillUseTranslatorIfAvailable() ); $app['locale'] = 'de'; - $app['form.csrf_provider'] = $app->share(function () { + $app['form.csrf_provider'] = function () { return new FakeCsrfProvider(); - }); + }; $form = $app['form.factory']->createBuilder('form', array()) ->getForm(); diff --git a/tests/Silex/Tests/Provider/HttpCacheServiceProviderTest.php b/tests/Silex/Tests/Provider/HttpCacheServiceProviderTest.php index 6873df2b4..93da4fe90 100644 --- a/tests/Silex/Tests/Provider/HttpCacheServiceProviderTest.php +++ b/tests/Silex/Tests/Provider/HttpCacheServiceProviderTest.php @@ -31,7 +31,7 @@ public function testRegister() 'http_cache.cache_dir' => sys_get_temp_dir().'/silex_http_cache_'.uniqid(), )); - $this->assertInstanceOf('Silex\HttpCache', $app['http_cache']); + $this->assertInstanceOf('Silex\Provider\HttpCache\HttpCache', $app['http_cache']); return $app; } diff --git a/tests/Silex/Tests/Provider/MonologServiceProviderTest.php b/tests/Silex/Tests/Provider/MonologServiceProviderTest.php index f8c091ed3..c327c67bc 100644 --- a/tests/Silex/Tests/Provider/MonologServiceProviderTest.php +++ b/tests/Silex/Tests/Provider/MonologServiceProviderTest.php @@ -185,11 +185,11 @@ protected function getApplication() $app->register(new MonologServiceProvider()); - $app['monolog.handler'] = $app->share(function () use ($app) { + $app['monolog.handler'] = function () use ($app) { $level = MonologServiceProvider::translateLevel($app['monolog.level']); return new TestHandler($level); - }); + }; return $app; } diff --git a/tests/Silex/Tests/Provider/UrlGeneratorServiceProviderTest.php b/tests/Silex/Tests/Provider/RoutingServiceProviderTest.php similarity index 86% rename from tests/Silex/Tests/Provider/UrlGeneratorServiceProviderTest.php rename to tests/Silex/Tests/Provider/RoutingServiceProviderTest.php index 76d8e52f4..aebd2bfa4 100644 --- a/tests/Silex/Tests/Provider/UrlGeneratorServiceProviderTest.php +++ b/tests/Silex/Tests/Provider/RoutingServiceProviderTest.php @@ -12,22 +12,20 @@ namespace Silex\Tests\Provider; use Silex\Application; -use Silex\Provider\UrlGeneratorServiceProvider; +use Silex\Provider\RoutingServiceProvider; use Symfony\Component\HttpFoundation\Request; /** - * UrlGeneratorProvider test cases. + * RoutingProvider test cases. * * @author Igor Wiedler */ -class UrlGeneratorServiceProviderTest extends \PHPUnit_Framework_TestCase +class RoutingServiceProviderTest extends \PHPUnit_Framework_TestCase { public function testRegister() { $app = new Application(); - $app->register(new UrlGeneratorServiceProvider()); - $app->get('/hello/{name}', function ($name) {}) ->bind('hello'); @@ -43,8 +41,6 @@ public function testUrlGeneration() { $app = new Application(); - $app->register(new UrlGeneratorServiceProvider()); - $app->get('/hello/{name}', function ($name) {}) ->bind('hello'); @@ -62,8 +58,6 @@ public function testAbsoluteUrlGeneration() { $app = new Application(); - $app->register(new UrlGeneratorServiceProvider()); - $app->get('/hello/{name}', function ($name) {}) ->bind('hello'); @@ -81,8 +75,6 @@ public function testUrlGenerationWithHttp() { $app = new Application(); - $app->register(new UrlGeneratorServiceProvider()); - $app->get('/insecure', function () {}) ->bind('insecure_page') ->requireHttp(); @@ -101,8 +93,6 @@ public function testUrlGenerationWithHttps() { $app = new Application(); - $app->register(new UrlGeneratorServiceProvider()); - $app->get('/secure', function () {}) ->bind('secure_page') ->requireHttps(); diff --git a/tests/Silex/Tests/Provider/SecurityServiceProviderTest.php b/tests/Silex/Tests/Provider/SecurityServiceProviderTest.php index fe92b8ac9..28e3e774d 100644 --- a/tests/Silex/Tests/Provider/SecurityServiceProviderTest.php +++ b/tests/Silex/Tests/Provider/SecurityServiceProviderTest.php @@ -200,7 +200,9 @@ private function addFormAuthentication($app) 'default' => array( 'pattern' => '^.*$', 'anonymous' => true, - 'form' => true, + 'form' => array( + 'require_previous_session' => false, + ), 'logout' => true, 'users' => array( // password is foo diff --git a/tests/Silex/Tests/Provider/SwiftmailerServiceProviderTest.php b/tests/Silex/Tests/Provider/SwiftmailerServiceProviderTest.php index f0874e5f0..86caa7bd4 100644 --- a/tests/Silex/Tests/Provider/SwiftmailerServiceProviderTest.php +++ b/tests/Silex/Tests/Provider/SwiftmailerServiceProviderTest.php @@ -34,9 +34,9 @@ public function testSwiftMailerSendsMailsOnFinish() $app->register(new SwiftmailerServiceProvider()); $app->boot(); - $app['swiftmailer.spool'] = $app->share(function () { + $app['swiftmailer.spool'] = function () { return new SpoolStub(); - }); + }; $app->get('/', function() use ($app) { $app['mailer']->send(\Swift_Message::newInstance()); @@ -60,9 +60,9 @@ public function testSwiftMailerAvoidsFlushesIfMailerIsUnused() $app->register(new SwiftmailerServiceProvider()); $app->boot(); - $app['swiftmailer.spool'] = $app->share(function () { + $app['swiftmailer.spool'] = function () { return new SpoolStub(); - }); + }; $app->get('/', function() use ($app) { }); diff --git a/tests/Silex/Tests/Provider/TranslationServiceProviderTest.php b/tests/Silex/Tests/Provider/TranslationServiceProviderTest.php index 873acf010..afdc769a0 100644 --- a/tests/Silex/Tests/Provider/TranslationServiceProviderTest.php +++ b/tests/Silex/Tests/Provider/TranslationServiceProviderTest.php @@ -13,6 +13,7 @@ use Silex\Application; use Silex\Provider\TranslationServiceProvider; +use Silex\Provider\LocaleServiceProvider; /** * TranslationProvider test cases. @@ -28,6 +29,7 @@ protected function getPreparedApp() { $app = new Application(); + $app->register(new LocaleServiceProvider()); $app->register(new TranslationServiceProvider()); $app['translator.domains'] = array( 'messages' => array( @@ -102,15 +104,6 @@ public function testTransChoiceForDefaultLanguage($key, $number, $locale, $expec $this->assertEquals($expected, $result); } - public function testBackwardCompatiblityForFallback() - { - $app = $this->getPreparedApp(); - $app['locale_fallback'] = 'de'; - - $result = $app['translator']->trans('key1', array(), null, 'ru'); - $this->assertEquals('The german translation', $result); - } - public function testFallbacks() { $app = $this->getPreparedApp(); diff --git a/tests/Silex/Tests/Provider/TwigServiceProviderTest.php b/tests/Silex/Tests/Provider/TwigServiceProviderTest.php index 474869833..af9870df3 100644 --- a/tests/Silex/Tests/Provider/TwigServiceProviderTest.php +++ b/tests/Silex/Tests/Provider/TwigServiceProviderTest.php @@ -27,7 +27,7 @@ public function testRegisterAndRender() $app = new Application(); $app->register(new TwigServiceProvider(), array( - 'twig.templates' => array('hello' => 'Hello {{ name }}!'), + 'twig.templates' => array('hello' => 'Hello {{ name }}!'), )); $app->get('/hello/{name}', function ($name) use ($app) { @@ -39,30 +39,6 @@ public function testRegisterAndRender() $this->assertEquals('Hello john!', $response->getContent()); } - public function testRenderFunction() - { - $app = new Application(); - - $app->register(new TwigServiceProvider(), array( - 'twig.templates' => array( - 'hello' => '{{ render("/foo") }}', - 'foo' => 'foo', - ), - )); - - $app->get('/hello', function () use ($app) { - return $app['twig']->render('hello'); - }); - - $app->get('/foo', function () use ($app) { - return $app['twig']->render('foo'); - }); - - $request = Request::create('/hello'); - $response = $app->handle($request); - $this->assertEquals('foo', $response->getContent()); - } - public function testLoaderPriority() { $app = new Application(); @@ -71,9 +47,9 @@ public function testLoaderPriority() )); $loader = $this->getMock('\Twig_LoaderInterface'); $loader->expects($this->never())->method('getSource'); - $app['twig.loader.filesystem'] = $app->share(function ($app) use ($loader) { + $app['twig.loader.filesystem'] = function ($app) use ($loader) { return $loader; - }); + }; $this->assertEquals('foo', $app['twig.loader']->getSource('foo')); } } diff --git a/tests/Silex/Tests/Provider/ValidatorServiceProviderTest.php b/tests/Silex/Tests/Provider/ValidatorServiceProviderTest.php index 51f399cf9..ba76030b8 100644 --- a/tests/Silex/Tests/Provider/ValidatorServiceProviderTest.php +++ b/tests/Silex/Tests/Provider/ValidatorServiceProviderTest.php @@ -28,8 +28,8 @@ class ValidatorServiceProviderTest extends \PHPUnit_Framework_TestCase public function testRegister() { $app = new Application(); - $app->register(new ValidatorServiceProvider()); + $app->register(new FormServiceProvider()); return $app; } @@ -38,9 +38,9 @@ public function testRegisterWithCustomValidators() { $app = new Application(); - $app['custom.validator'] = $app->share(function() { + $app['custom.validator'] = function() { return new CustomValidator(); - }); + }; $app->register(new ValidatorServiceProvider(), array( 'validator.validator_service_ids' => array( @@ -56,7 +56,7 @@ public function testRegisterWithCustomValidators() */ public function testConstraintValidatorFactory($app) { - $this->assertInstanceOf('Silex\ConstraintValidatorFactory', $app['validator.validator_factory']); + $this->assertInstanceOf('Silex\Provider\Validator\ConstraintValidatorFactory', $app['validator.validator_factory']); $validator = $app['validator.validator_factory']->getInstance(new Custom()); $this->assertInstanceOf('Silex\Tests\Provider\ValidatorServiceProviderTest\Constraint\CustomValidator', $validator); @@ -76,9 +76,6 @@ public function testValidatorServiceIsAValidator($app) */ public function testValidatorConstraint($email, $isValid, $nbGlobalError, $nbEmailError, $app) { - $app->register(new ValidatorServiceProvider()); - $app->register(new FormServiceProvider()); - $constraints = new Assert\Collection(array( 'email' => array( new Assert\NotBlank(), diff --git a/tests/Silex/Tests/RouterTest.php b/tests/Silex/Tests/RouterTest.php index 682542a8f..7aa39d154 100644 --- a/tests/Silex/Tests/RouterTest.php +++ b/tests/Silex/Tests/RouterTest.php @@ -152,12 +152,12 @@ public function testRequestShouldBeStoredRegardlessOfRouting() { $app = new Application(); - $app->get('/foo', function () use ($app) { - return new Response($app['request']->getRequestUri()); + $app->get('/foo', function (Request $request) use ($app) { + return new Response($request->getRequestUri()); }); - $app->error(function ($e) use ($app) { - return new Response($app['request']->getRequestUri()); + $app->error(function ($e, Request $request, $code) use ($app) { + return new Response($request->getRequestUri()); }); foreach (array('/foo', '/bar') as $path) { diff --git a/tests/Silex/Tests/ServiceControllerResolverRouterTest.php b/tests/Silex/Tests/ServiceControllerResolverRouterTest.php index db708181c..d9bc927a3 100644 --- a/tests/Silex/Tests/ServiceControllerResolverRouterTest.php +++ b/tests/Silex/Tests/ServiceControllerResolverRouterTest.php @@ -23,6 +23,7 @@ class ServiceControllerResolverRouterTest extends RouterTest public function testServiceNameControllerSyntax() { $app = new Application(); + $app->register(new ServiceControllerServiceProvider()); $app['service_name'] = function () { return new MyController(); @@ -35,8 +36,6 @@ public function testServiceNameControllerSyntax() protected function checkRouteResponse(Application $app, $path, $expectedContent, $method = 'get', $message = null) { - $app->register(new ServiceControllerServiceProvider()); - $request = Request::create($path, $method); $response = $app->handle($request); $this->assertEquals($expectedContent, $response->getContent(), $message); diff --git a/tests/Silex/Tests/WebTestCaseTest.php b/tests/Silex/Tests/WebTestCaseTest.php index e26af50f9..6e1b20f56 100644 --- a/tests/Silex/Tests/WebTestCaseTest.php +++ b/tests/Silex/Tests/WebTestCaseTest.php @@ -13,6 +13,7 @@ use Silex\Application; use Silex\WebTestCase; +use Symfony\Component\HttpFoundation\Request; /** * Functional test cases. @@ -33,9 +34,9 @@ public function createApplication() return '

title

'; }); - $app->match('/server', function () use ($app) { - $user = $app['request']->server->get('PHP_AUTH_USER'); - $pass = $app['request']->server->get('PHP_AUTH_PW'); + $app->match('/server', function (Request $request) use ($app) { + $user = $request->server->get('PHP_AUTH_USER'); + $pass = $request->server->get('PHP_AUTH_PW'); return "

$user:$pass

"; });