Commit ae8f9d43 authored by Fabien Potencier's avatar Fabien Potencier

feature #947 Move master to 2.0 (fabpot, jkazimir)

This PR was merged into the 1.2.x-dev branch.

Discussion
----------

Move master to 2.0

This PR moves master to 2.0@dev. As there is a 1.2 branch, that should not be a problem for anyone ... except if you target dev-master in your composer.json, but hey, that's your choice.

Of course, it's not finished yet, but working on master is easier for everyone and future PRs.

TODO:

 - [ ] update documentation
 - [ ] update CHANGELOG

Commits
-------

5a4b265e upgraded to Pimple 2.1
322dbb5d updated route_factory service to use Pimple 2 factory method
fc8bbb62 switched to Pimple 2.0
c2421fab removed the flush call in the url generator service
5f9716d8 made the logger optional in all providers
349dcf97 moved everything related to the routing to a reusable service provider
e96f9be8 removed the request service in favor of the request_stack one
26e85436 changed charset to have a sensible default in all providers
34524a52 changed debug to have a sensible default in all providers
18b6050b fixed stupid typo...
0d10e89e fixed composer.json paths
a4b0b201 simplified composer names
6863b9a0 fixed composer.json files
67802eb2 added composer.json for Api and Provider
c341ca17 moved classes so that Silex\Provider can be used as a sub-tree split independently of eveything else
2d3a96bb changed type-hint to Pimple whenever possible
df568cb2 added BootableProviderInterface
1ba15a17 moved the provider interfaces under Silex\Api
eb5079be moved fake routes for the security service provider to a connect() method (with auto-registration)
3fdfa4be emptied the boot() method of the remember me service provider
27eb5267 moved Swiftmailer finish call to a proper listener
7bee6bfd adding a new interface for providers willing to register event listeners
613c4bfa removed obsolete comment
3b1ba69b removed conditions about the request stack as Symfony 2.4+ is required now
cd044b6f removed the deprecated Compiler class and the doc on the phar
de674e6d removed deprecated locale_fallback setting
24bce51f removed the deprecated TwigCoreExtension class
a4c7c51f fixed visibility
38c84add moved locale management to a locale service provider
88e44ea4 refactored session code to make it more reusable
9a32c0a9 bumped version to 2.0
parents d0b2b9b2 5a4b265e
#!/usr/bin/env php
<?php
require_once __DIR__.'/../vendor/autoload.php';
use Silex\Util\Compiler;
$compiler = new Compiler();
$compiler->compile();
...@@ -17,29 +17,29 @@ ...@@ -17,29 +17,29 @@
], ],
"require": { "require": {
"php": ">=5.3.3", "php": ">=5.3.3",
"pimple/pimple": "~1.0", "pimple/pimple": "~2.1@dev",
"symfony/event-dispatcher": ">=2.3,<2.6-dev", "symfony/event-dispatcher": ">=2.4,<2.6-dev",
"symfony/http-foundation": ">=2.3,<2.6-dev", "symfony/http-foundation": ">=2.4,<2.6-dev",
"symfony/http-kernel": ">=2.3,<2.6-dev", "symfony/http-kernel": ">=2.4,<2.6-dev",
"symfony/routing": ">=2.3,<2.6-dev" "symfony/routing": ">=2.4,<2.6-dev"
}, },
"require-dev": { "require-dev": {
"symfony/security": ">=2.3,<2.6-dev", "symfony/security": ">=2.4,<2.6-dev",
"symfony/config": ">=2.3,<2.6-dev", "symfony/config": ">=2.4,<2.6-dev",
"symfony/locale": ">=2.3,<2.6-dev", "symfony/locale": ">=2.4,<2.6-dev",
"symfony/form": ">=2.3,<2.6-dev", "symfony/form": ">=2.4,<2.6-dev",
"symfony/browser-kit": ">=2.3,<2.6-dev", "symfony/browser-kit": ">=2.4,<2.6-dev",
"symfony/css-selector": ">=2.3,<2.6-dev", "symfony/css-selector": ">=2.4,<2.6-dev",
"symfony/debug": ">=2.3,<2.6-dev", "symfony/debug": ">=2.4,<2.6-dev",
"symfony/dom-crawler": ">=2.3,<2.6-dev", "symfony/dom-crawler": ">=2.4,<2.6-dev",
"symfony/finder": ">=2.3,<2.6-dev", "symfony/finder": ">=2.4,<2.6-dev",
"symfony/monolog-bridge": ">=2.3,<2.6-dev", "symfony/monolog-bridge": ">=2.4,<2.6-dev",
"symfony/options-resolver": ">=2.3,<2.6-dev", "symfony/options-resolver": ">=2.4,<2.6-dev",
"symfony/process": ">=2.3,<2.6-dev", "symfony/process": ">=2.4,<2.6-dev",
"symfony/serializer": ">=2.3,<2.6-dev", "symfony/serializer": ">=2.4,<2.6-dev",
"symfony/translation": ">=2.3,<2.6-dev", "symfony/translation": ">=2.4,<2.6-dev",
"symfony/twig-bridge": ">=2.3,<2.6-dev", "symfony/twig-bridge": ">=2.4,<2.6-dev",
"symfony/validator": ">=2.3,<2.6-dev", "symfony/validator": ">=2.4,<2.6-dev",
"twig/twig": ">=1.8.0,<2.0-dev", "twig/twig": ">=1.8.0,<2.0-dev",
"doctrine/dbal": "~2.2", "doctrine/dbal": "~2.2",
"swiftmailer/swiftmailer": "5.*", "swiftmailer/swiftmailer": "5.*",
...@@ -47,17 +47,21 @@ ...@@ -47,17 +47,21 @@
"phpunit/phpunit": "~3.7" "phpunit/phpunit": "~3.7"
}, },
"suggest": { "suggest": {
"symfony/browser-kit": ">=2.3,<2.6-dev", "symfony/browser-kit": ">=2.4,<2.6-dev",
"symfony/css-selector": ">=2.3,<2.6-dev", "symfony/css-selector": ">=2.4,<2.6-dev",
"symfony/dom-crawler": ">=2.3,<2.6-dev", "symfony/dom-crawler": ">=2.4,<2.6-dev",
"symfony/form": ">=2.3,<2.6-dev" "symfony/form": ">=2.4,<2.6-dev"
},
"replace": {
"silex/api": "self.version",
"silex/providers": "self.version"
}, },
"autoload": { "autoload": {
"psr-0": { "Silex": "src/" } "psr-0": { "Silex": "src/" }
}, },
"extra": { "extra": {
"branch-alias": { "branch-alias": {
"dev-master": "1.2.x-dev" "dev-master": "2.0.x-dev"
} }
} }
} }
Changelog 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) 1.2.0 (2014-03-29)
------------------ ------------------
......
...@@ -34,11 +34,11 @@ Using it in a template is as easy as before: ...@@ -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 If you need to implement some logic independently of the asset, define a
service instead:: service instead::
$app['asset_path'] = $app->share(function () { $app['asset_path'] = function () {
// implement whatever logic you need to determine the asset path // implement whatever logic you need to determine the asset path
return 'http://assets.examples.com'; return 'http://assets.examples.com';
}); };
Usage is exactly the same as before: Usage is exactly the same as before:
...@@ -49,7 +49,7 @@ 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 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:: 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) { $twig->addFunction(new \Twig_SimpleFunction('asset', function ($asset) {
// implement whatever logic you need to determine the asset path // 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:: ...@@ -57,7 +57,7 @@ abstraction; here is one way to do that with a Twig function::
})); }));
return $twig; return $twig;
})); });
The ``asset`` function can then be used in your templates: The ``asset`` function can then be used in your templates:
......
...@@ -18,9 +18,9 @@ using the bundled handler, but each with a different channel. ...@@ -18,9 +18,9 @@ using the bundled handler, but each with a different channel.
}); });
foreach (array('auth', 'payments', 'stats') as $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); return $app['monolog.factory']($channel);
}); };
} }
As your application grows, or your logging needs for certain areas of the As your application grows, or your logging needs for certain areas of the
...@@ -31,13 +31,13 @@ particular service separately, including your customizations. ...@@ -31,13 +31,13 @@ particular service separately, including your customizations.
use Monolog\Handler\StreamHandler; use Monolog\Handler\StreamHandler;
$app['monolog.payments'] = $app->share(function ($app) { $app['monolog.payments'] = function ($app) {
$log = new $app['monolog.logger.class']('payments'); $log = new $app['monolog.logger.class']('payments');
$handler = new StreamHandler($app['monolog.payments.logfile'], $app['monolog.payment.level']); $handler = new StreamHandler($app['monolog.payments.logfile'], $app['monolog.payment.level']);
$log->pushHandler($handler); $log->pushHandler($handler);
return $log; return $log;
}); };
Alternatively, you could attempt to make the factory more complicated, and rely 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 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. ...@@ -62,10 +62,8 @@ the container with the channel name, defaulting to the bundled handler.
return $log; return $log;
}); });
$app['monolog.payments.handlers'] = $app->share(function ($app) { $app['monolog.payments.handlers'] = function ($app) {
return array( return array(
new StreamHandler(__DIR__.'/../payments.log', Logger::DEBUG), new StreamHandler(__DIR__.'/../payments.log', Logger::DEBUG),
); );
}); };
...@@ -35,21 +35,21 @@ With a dedicated PDO service ...@@ -35,21 +35,21 @@ With a dedicated PDO service
'db_time_col' => 'session_time', 'db_time_col' => 'session_time',
); );
$app['pdo'] = $app->share(function () use ($app) { $app['pdo'] = function () use ($app) {
return new PDO( return new PDO(
$app['pdo.dsn'], $app['pdo.dsn'],
$app['pdo.user'], $app['pdo.user'],
$app['pdo.password'] $app['pdo.password']
); );
}); };
$app['session.storage.handler'] = $app->share(function () use ($app) { $app['session.storage.handler'] = function () use ($app) {
return new PdoSessionHandler( return new PdoSessionHandler(
$app['pdo'], $app['pdo'],
$app['session.db_options'], $app['session.db_options'],
$app['session.storage.options'] $app['session.storage.options']
); );
}); };
Using the DoctrineServiceProvider Using the DoctrineServiceProvider
--------------------------------- ---------------------------------
...@@ -70,13 +70,13 @@ have to make another database connection, simply pass the getWrappedConnection m ...@@ -70,13 +70,13 @@ have to make another database connection, simply pass the getWrappedConnection m
'db_time_col' => 'session_time', 'db_time_col' => 'session_time',
); );
$app['session.storage.handler'] = $app->share(function () use ($app) { $app['session.storage.handler'] = function () use ($app) {
return new PdoSessionHandler( return new PdoSessionHandler(
$app['db']->getWrappedConnection(), $app['db']->getWrappedConnection(),
$app['session.db_options'], $app['session.db_options'],
$app['session.storage.options'] $app['session.storage.options']
); );
}); };
Database structure Database structure
------------------ ------------------
......
...@@ -17,4 +17,3 @@ Silex ...@@ -17,4 +17,3 @@ Silex
providers/index providers/index
web_servers web_servers
changelog changelog
phar
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
<http://silex.sensiolabs.org/get/silex.phar>`_ and storing it somewhere on
the disk. Then, require it in your script::
<?php
require_once __DIR__.'/silex.phar';
$app = new Silex\Application();
$app->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
...@@ -80,7 +80,7 @@ You are encouraged to share yours. ...@@ -80,7 +80,7 @@ You are encouraged to share yours.
Creating a provider Creating a provider
~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~
Providers must implement the ``Silex\ServiceProviderInterface``:: Providers must implement the ``Silex\Api\ServiceProviderInterface``::
interface ServiceProviderInterface interface ServiceProviderInterface
{ {
...@@ -100,7 +100,7 @@ Here is an example of such a provider:: ...@@ -100,7 +100,7 @@ Here is an example of such a provider::
namespace Acme; namespace Acme;
use Silex\Application; use Silex\Application;
use Silex\ServiceProviderInterface; use Silex\Api\ServiceProviderInterface;
class HelloServiceProvider implements ServiceProviderInterface class HelloServiceProvider implements ServiceProviderInterface
{ {
...@@ -161,7 +161,7 @@ All controllers defined by the provider will now be available under the ...@@ -161,7 +161,7 @@ All controllers defined by the provider will now be available under the
Creating a provider Creating a provider
~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~
Providers must implement the ``Silex\ControllerProviderInterface``:: Providers must implement the ``Silex\Api\ControllerProviderInterface``::
interface ControllerProviderInterface interface ControllerProviderInterface
{ {
...@@ -173,7 +173,7 @@ Here is an example of such a provider:: ...@@ -173,7 +173,7 @@ Here is an example of such a provider::
namespace Acme; namespace Acme;
use Silex\Application; use Silex\Application;
use Silex\ControllerProviderInterface; use Silex\Api\ControllerProviderInterface;
class HelloControllerProvider implements ControllerProviderInterface class HelloControllerProvider implements ControllerProviderInterface
{ {
......
...@@ -168,28 +168,28 @@ form by adding constraints on the fields:: ...@@ -168,28 +168,28 @@ form by adding constraints on the fields::
You can register form extensions by extending ``form.extensions``:: 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(); $extensions[] = new YourTopFormExtension();
return $extensions; return $extensions;
})); });
You can register form type extensions by extending ``form.type.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(); $extensions[] = new YourFormTypeExtension();
return $extensions; return $extensions;
})); });
You can register form type guessers by extending ``form.type.guessers``:: 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(); $guessers[] = new YourFormTypeGuesser();
return $guessers; return $guessers;
})); });
Traits Traits
------ ------
......
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());
...@@ -81,11 +81,11 @@ Customization ...@@ -81,11 +81,11 @@ Customization
You can configure Monolog (like adding or changing the handlers) before using You can configure Monolog (like adding or changing the handlers) before using
it by extending the ``monolog`` service:: it by extending the ``monolog`` service::
$app['monolog'] = $app->share($app->extend('monolog', function($monolog, $app) { $app->extend('monolog', function($monolog, $app) {
$monolog->pushHandler(...); $monolog->pushHandler(...);
return $monolog; return $monolog;
})); });
By default, all requests, responses and errors are logged by an event listener 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 registered as a service called `monolog.listener`. You can replace or remove
......
...@@ -432,9 +432,9 @@ The ``users`` setting can be defined as a service that returns an instance of ...@@ -432,9 +432,9 @@ The ``users`` setting can be defined as a service that returns an instance of
`UserProviderInterface `UserProviderInterface
<http://api.symfony.com/master/Symfony/Component/Security/Core/User/UserProviderInterface.html>`_:: <http://api.symfony.com/master/Symfony/Component/Security/Core/User/UserProviderInterface.html>`_::
'users' => $app->share(function () use ($app) { 'users' => function () use ($app) {
return new UserProvider($app['db']); return new UserProvider($app['db']);
}), },
Here is a simple example of a user provider, where Doctrine DBAL is used to Here is a simple example of a user provider, where Doctrine DBAL is used to
store the users:: store the users::
...@@ -532,12 +532,12 @@ service:: ...@@ -532,12 +532,12 @@ service::
use Symfony\Component\Security\Core\Encoder\MessageDigestPasswordEncoder; 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 // use the sha1 algorithm
// don't base64 encode the password // don't base64 encode the password
// use only 1 iteration // use only 1 iteration
return new MessageDigestPasswordEncoder('sha1', false, 1); return new MessageDigestPasswordEncoder('sha1', false, 1);
}); };
Defining a custom Authentication Provider Defining a custom Authentication Provider
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
...@@ -550,14 +550,14 @@ use in your configuration:: ...@@ -550,14 +550,14 @@ use in your configuration::
$app['security.authentication_listener.factory.wsse'] = $app->protect(function ($name, $options) use ($app) { $app['security.authentication_listener.factory.wsse'] = $app->protect(function ($name, $options) use ($app) {
// define the authentication provider object // 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'); return new WsseProvider($app['security.user_provider.default'], __DIR__.'/security_cache');
}); };
// define the authentication listener object // 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 new WsseListener($app['security'], $app['security.authentication_manager']);
}); };
return array( return array(
// the authentication provider id // the authentication provider id
......
...@@ -58,9 +58,9 @@ In this slightly contrived example of a blog API, we're going to change the ...@@ -58,9 +58,9 @@ In this slightly contrived example of a blog API, we're going to change the
$app = new Application(); $app = new Application();
$app['posts.repository'] = $app->share(function() { $app['posts.repository'] = function() {
return new PostRepository; return new PostRepository;
}); };
$app->get('/posts.json', function() use ($app) { $app->get('/posts.json', function() use ($app) {
return $app->json($app['posts.repository']->findAll()); return $app->json($app['posts.repository']->findAll());
...@@ -109,8 +109,8 @@ followed by a single colon (:), followed by the method name. ...@@ -109,8 +109,8 @@ followed by a single colon (:), followed by the method name.
.. code-block:: php .. code-block:: php
$app['posts.controller'] = $app->share(function() use ($app) { $app['posts.controller'] = function() use ($app) {
return new PostController($app['posts.repository']); return new PostController($app['posts.repository']);
}); };
$app->get('/posts.json', "posts.controller:indexJsonAction"); $app->get('/posts.json', "posts.controller:indexJsonAction");
...@@ -37,6 +37,7 @@ Registering ...@@ -37,6 +37,7 @@ Registering
.. code-block:: php .. code-block:: php
$app->register(new Silex\Provider\LocaleServiceProvider());
$app->register(new Silex\Provider\TranslationServiceProvider(), array( $app->register(new Silex\Provider\TranslationServiceProvider(), array(
'locale_fallbacks' => array('en'), 'locale_fallbacks' => array('en'),
)); ));
...@@ -143,7 +144,7 @@ translation files:: ...@@ -143,7 +144,7 @@ translation files::
use Symfony\Component\Translation\Loader\YamlFileLoader; 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->addLoader('yaml', new YamlFileLoader());
$translator->addResource('yaml', __DIR__.'/locales/en.yml', 'en'); $translator->addResource('yaml', __DIR__.'/locales/en.yml', 'en');
...@@ -151,7 +152,7 @@ translation files:: ...@@ -151,7 +152,7 @@ translation files::
$translator->addResource('yaml', __DIR__.'/locales/fr.yml', 'fr'); $translator->addResource('yaml', __DIR__.'/locales/fr.yml', 'fr');
return $translator; return $translator;
})); });
XLIFF-based language files XLIFF-based language files
~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~
......
...@@ -156,12 +156,12 @@ Customization ...@@ -156,12 +156,12 @@ Customization
You can configure the Twig environment before using it by extending the You can configure the Twig environment before using it by extending the
``twig`` service:: ``twig`` service::
$app['twig'] = $app->share($app->extend('twig', function($twig, $app) { $app->extend('twig', function($twig, $app) {
$twig->addGlobal('pi', 3.14); $twig->addGlobal('pi', 3.14);
$twig->addFilter('levenshtein', new \Twig_Filter_Function('levenshtein')); $twig->addFilter('levenshtein', new \Twig_Filter_Function('levenshtein'));
return $twig; return $twig;
})); });
For more information, check out the `official Twig documentation For more information, check out the `official Twig documentation
<http://twig.sensiolabs.org>`_. <http://twig.sensiolabs.org>`_.
...@@ -64,6 +64,14 @@ Moreover, if you have ``twig-bridge`` in your ``composer.json``, you will have a ...@@ -64,6 +64,14 @@ Moreover, if you have ``twig-bridge`` in your ``composer.json``, you will have a
{{ path('hello', {name: 'Fabien'}) }} {{ path('hello', {name: 'Fabien'}) }}
{{ url('hello', {name: 'Fabien'}) }} {# generates the absolute url http://example.org/hello/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 Traits
------ ------
......
...@@ -63,10 +63,10 @@ Pimple is probably the simplest service container out there. It makes strong ...@@ -63,10 +63,10 @@ Pimple is probably the simplest service container out there. It makes strong
use of closures and implements the ArrayAccess interface. use of closures and implements the ArrayAccess interface.
We will start off by creating a new instance of Pimple -- and because We will start off by creating a new instance of Pimple -- and because
``Silex\Application`` extends ``Pimple`` all of this applies to Silex as ``Silex\Application`` extends ``Pimple\Container`` all of this applies to Silex
well:: as well::
$container = new Pimple(); $container = new Pimple\Container();
or:: or::
...@@ -107,19 +107,6 @@ And to retrieve the service, use:: ...@@ -107,19 +107,6 @@ And to retrieve the service, use::
Every time you call ``$app['some_service']``, a new instance of the service is Every time you call ``$app['some_service']``, a new instance of the service is
created. 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 Access container from closure
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
...@@ -139,17 +126,13 @@ options. The dependency is only created when ``some_service`` is accessed, and ...@@ -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 it is possible to replace either of the dependencies by simply overriding
those definitions. those definitions.
.. note::
This also works for shared services.
Going back to our initial example, here's how we could use the container Going back to our initial example, here's how we could use the container
to manage its dependencies:: to manage its dependencies::
$app['user.persist_path'] = '/tmp/users'; $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']); return new JsonUserPersister($app['user.persist_path']);
}); };
Protected closures Protected closures
...@@ -230,13 +213,6 @@ don't want to mess with most of them. ...@@ -230,13 +213,6 @@ don't want to mess with most of them.
the ``MonologServiceProvider`` or define your own ``logger`` service that the ``MonologServiceProvider`` or define your own ``logger`` service that
conforms to the PSR logger interface. 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 Core parameters
--------------- ---------------
...@@ -256,11 +232,6 @@ Core parameters ...@@ -256,11 +232,6 @@ Core parameters
This parameter can be used by the ``UrlGeneratorProvider``. 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** (optional): Returns whether or not the application is running in
debug mode. debug mode.
......
...@@ -25,7 +25,7 @@ If you want more flexibility, use Composer_ instead. Create a ...@@ -25,7 +25,7 @@ If you want more flexibility, use Composer_ instead. Create a
{ {
"require": { "require": {
"silex/silex": "~1.1" "silex/silex": "~2.0"
} }
} }
...@@ -375,9 +375,9 @@ converter based on Doctrine ObjectManager:: ...@@ -375,9 +375,9 @@ converter based on Doctrine ObjectManager::
The service will now be registered in the application, and the The service will now be registered in the application, and the
convert method will be used as converter:: convert method will be used as converter::
$app['converter.user'] = $app->share(function () { $app['converter.user'] = function () {
return new UserConverter(); return new UserConverter();
}); };
$app->get('/user/{user}', function (User $user) { $app->get('/user/{user}', function (User $user) {
// ... // ...
......
...@@ -9,25 +9,17 @@ ...@@ -9,25 +9,17 @@
* file that was distributed with this source code. * 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 <fabien@symfony.com> * @author Fabien Potencier <fabien@symfony.com>
*/ */
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. * Bootstraps the application.
* *
......
...@@ -9,7 +9,9 @@ ...@@ -9,7 +9,9 @@
* file that was distributed with this source code. * file that was distributed with this source code.
*/ */
namespace Silex; namespace Silex\Api;
use Silex\Application;
/** /**
* Interface for controller providers. * Interface for controller providers.
......
<?php
/*
* This file is part of the Silex framework.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Silex\Api;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Pimple\Container;
/**
* Interface for event listener providers.
*
* @author Fabien Potencier <fabien@symfony.com>
*/
interface EventListenerProviderInterface
{
public function subscribe(Container $app, EventDispatcherInterface $dispatcher);
}
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.
{
"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"
}
}
}
...@@ -11,6 +11,8 @@ ...@@ -11,6 +11,8 @@
namespace Silex; namespace Silex;
use Pimple\Container;
use Pimple\ServiceProviderInterface;
use Symfony\Component\HttpFoundation\BinaryFileResponse; use Symfony\Component\HttpFoundation\BinaryFileResponse;
use Symfony\Component\HttpKernel\HttpKernel; use Symfony\Component\HttpKernel\HttpKernel;
use Symfony\Component\HttpKernel\HttpKernelInterface; use Symfony\Component\HttpKernel\HttpKernelInterface;
...@@ -19,7 +21,6 @@ use Symfony\Component\HttpKernel\Event\FilterResponseEvent; ...@@ -19,7 +21,6 @@ use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
use Symfony\Component\HttpKernel\Event\GetResponseEvent; use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\HttpKernel\Event\PostResponseEvent; use Symfony\Component\HttpKernel\Event\PostResponseEvent;
use Symfony\Component\HttpKernel\EventListener\ResponseListener; use Symfony\Component\HttpKernel\EventListener\ResponseListener;
use Symfony\Component\HttpKernel\EventListener\RouterListener;
use Symfony\Component\HttpKernel\Exception\HttpException; use Symfony\Component\HttpKernel\Exception\HttpException;
use Symfony\Component\HttpKernel\KernelEvents; use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Request;
...@@ -29,20 +30,22 @@ use Symfony\Component\HttpFoundation\RedirectResponse; ...@@ -29,20 +30,22 @@ use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\StreamedResponse; use Symfony\Component\HttpFoundation\StreamedResponse;
use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\Routing\RouteCollection; use Symfony\Component\Routing\RouteCollection;
use Symfony\Component\Routing\RequestContext; use Silex\Api\BootableProviderInterface;
use Silex\EventListener\LocaleListener; use Silex\Api\EventListenerProviderInterface;
use Silex\Api\ControllerProviderInterface;
use Silex\EventListener\MiddlewareListener; use Silex\EventListener\MiddlewareListener;
use Silex\EventListener\ConverterListener; use Silex\EventListener\ConverterListener;
use Silex\EventListener\StringToResponseListener; use Silex\EventListener\StringToResponseListener;
use Silex\Provider\RoutingServiceProvider;
/** /**
* The Silex framework class. * The Silex framework class.
* *
* @author Fabien Potencier <fabien@symfony.com> * @author Fabien Potencier <fabien@symfony.com>
*/ */
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 EARLY_EVENT = 512;
const LATE_EVENT = -512; const LATE_EVENT = -512;
...@@ -63,38 +66,31 @@ class Application extends \Pimple implements HttpKernelInterface, TerminableInte ...@@ -63,38 +66,31 @@ class Application extends \Pimple implements HttpKernelInterface, TerminableInte
$app = $this; $app = $this;
$this['logger'] = null; $this['routes'] = function () {
$this['routes'] = $this->share(function () {
return new RouteCollection(); return new RouteCollection();
}); };
$this['controllers'] = $this->share(function () use ($app) { $this['controllers'] = function () use ($app) {
return $app['controllers_factory']; return $app['controllers_factory'];
}); };
$this['controllers_factory'] = function () use ($app) { $this['controllers_factory'] = $this->factory(function () use ($app) {
return new ControllerCollection($app['route_factory']); return new ControllerCollection($app['route_factory']);
}; });
$this['route_class'] = 'Silex\\Route'; $this['route_class'] = 'Silex\\Route';
$this['route_factory'] = function () use ($app) { $this['route_factory'] = $this->factory(function () use ($app) {
return new $app['route_class'](); return new $app['route_class']();
}; });
$this['exception_handler'] = $this->share(function () use ($app) { $this['exception_handler'] = function () use ($app) {
return new ExceptionHandler($app['debug']); return new ExceptionHandler($app['debug']);
}); };
$this['dispatcher_class'] = 'Symfony\\Component\\EventDispatcher\\EventDispatcher'; $this['dispatcher_class'] = 'Symfony\\Component\\EventDispatcher\\EventDispatcher';
$this['dispatcher'] = $this->share(function () use ($app) { $this['dispatcher'] = function () use ($app) {
$dispatcher = new $app['dispatcher_class'](); $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'])) { if (isset($app['exception_handler'])) {
$dispatcher->addSubscriber($app['exception_handler']); $dispatcher->addSubscriber($app['exception_handler']);
} }
...@@ -104,50 +100,31 @@ class Application extends \Pimple implements HttpKernelInterface, TerminableInte ...@@ -104,50 +100,31 @@ class Application extends \Pimple implements HttpKernelInterface, TerminableInte
$dispatcher->addSubscriber(new StringToResponseListener()); $dispatcher->addSubscriber(new StringToResponseListener());
return $dispatcher; return $dispatcher;
}); };
$this['callback_resolver'] = $this->share(function () use ($app) { $this['callback_resolver'] = function () use ($app) {
return new CallbackResolver($app); return new CallbackResolver($app);
}); };
$this['resolver'] = $this->share(function () use ($app) { $this['resolver'] = function () use ($app) {
return new ControllerResolver($app, $app['logger']); 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']); return new HttpKernel($app['dispatcher'], $app['resolver'], $app['request_stack']);
}); };
$this['request_stack'] = $this->share(function () use ($app) { $this['request_stack'] = function () use ($app) {
if (class_exists('Symfony\Component\HttpFoundation\RequestStack')) {
return new 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.http_port'] = 80; $this['request.http_port'] = 80;
$this['request.https_port'] = 443; $this['request.https_port'] = 443;
$this['debug'] = false; $this['debug'] = false;
$this['charset'] = 'UTF-8'; $this['charset'] = 'UTF-8';
$this['locale'] = 'en'; $this['logger'] = null;
$this->register(new RoutingServiceProvider());
foreach ($values as $key => $value) { foreach ($values as $key => $value) {
$this[$key] = $value; $this[$key] = $value;
...@@ -184,11 +161,17 @@ class Application extends \Pimple implements HttpKernelInterface, TerminableInte ...@@ -184,11 +161,17 @@ class Application extends \Pimple implements HttpKernelInterface, TerminableInte
public function boot() public function boot()
{ {
if (!$this->booted) { if (!$this->booted) {
$this->booted = true;
foreach ($this->providers as $provider) { 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 @@ class Application extends \Pimple implements HttpKernelInterface, TerminableInte ...@@ -288,11 +271,11 @@ class Application extends \Pimple implements HttpKernelInterface, TerminableInte
return; 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); $dispatcher->addListener($eventName, $app['callback_resolver']->resolveCallback($callback), $priority);
return $dispatcher; return $dispatcher;
})); });
} }
/** /**
...@@ -470,8 +453,6 @@ class Application extends \Pimple implements HttpKernelInterface, TerminableInte ...@@ -470,8 +453,6 @@ class Application extends \Pimple implements HttpKernelInterface, TerminableInte
* @param null|string $contentDisposition The type of Content-Disposition to set automatically with the filename * @param null|string $contentDisposition The type of Content-Disposition to set automatically with the filename
* *
* @return BinaryFileResponse * @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) public function sendFile($file, $status = 200, array $headers = array(), $contentDisposition = null)
{ {
...@@ -529,17 +510,9 @@ class Application extends \Pimple implements HttpKernelInterface, TerminableInte ...@@ -529,17 +510,9 @@ class Application extends \Pimple implements HttpKernelInterface, TerminableInte
$this->boot(); $this->boot();
} }
$current = HttpKernelInterface::SUB_REQUEST === $type ? $this['request'] : $this['request_error'];
$this['request'] = $request;
$this->flush(); $this->flush();
$response = $this['kernel']->handle($request, $type, $catch); return $this['kernel']->handle($request, $type, $catch);
$this['request'] = $current;
return $response;
} }
/** /**
......
...@@ -11,13 +11,15 @@ ...@@ -11,13 +11,15 @@
namespace Silex; namespace Silex;
use Pimple\Container;
class CallbackResolver class CallbackResolver
{ {
const SERVICE_PATTERN = "/[A-Za-z0-9\._\-]+:[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*/"; const SERVICE_PATTERN = "/[A-Za-z0-9\._\-]+:[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*/";
private $app; private $app;
public function __construct(\Pimple $app) public function __construct(Container $app)
{ {
$this->app = $app; $this->app = $app;
} }
......
...@@ -49,7 +49,7 @@ class ExceptionListenerWrapper ...@@ -49,7 +49,7 @@ class ExceptionListenerWrapper
$code = $exception instanceof HttpExceptionInterface ? $exception->getStatusCode() : 500; $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); $this->ensureResponse($response, $event);
} }
......
...@@ -11,8 +11,8 @@ ...@@ -11,8 +11,8 @@
namespace Silex\Provider; namespace Silex\Provider;
use Silex\Application; use Pimple\Container;
use Silex\ServiceProviderInterface; use Pimple\ServiceProviderInterface;
use Doctrine\DBAL\DriverManager; use Doctrine\DBAL\DriverManager;
use Doctrine\DBAL\Configuration; use Doctrine\DBAL\Configuration;
use Doctrine\Common\EventManager; use Doctrine\Common\EventManager;
...@@ -25,7 +25,7 @@ use Symfony\Bridge\Doctrine\Logger\DbalLogger; ...@@ -25,7 +25,7 @@ use Symfony\Bridge\Doctrine\Logger\DbalLogger;
*/ */
class DoctrineServiceProvider implements ServiceProviderInterface class DoctrineServiceProvider implements ServiceProviderInterface
{ {
public function register(Application $app) public function register(Container $app)
{ {
$app['db.default_options'] = array( $app['db.default_options'] = array(
'driver' => 'pdo_mysql', 'driver' => 'pdo_mysql',
...@@ -60,10 +60,10 @@ class DoctrineServiceProvider implements ServiceProviderInterface ...@@ -60,10 +60,10 @@ class DoctrineServiceProvider implements ServiceProviderInterface
$app['dbs.options'] = $tmp; $app['dbs.options'] = $tmp;
}); });
$app['dbs'] = $app->share(function ($app) { $app['dbs'] = function ($app) {
$app['dbs.options.initializer'](); $app['dbs.options.initializer']();
$dbs = new \Pimple(); $dbs = new Container();
foreach ($app['dbs.options'] as $name => $options) { foreach ($app['dbs.options'] as $name => $options) {
if ($app['dbs.default'] === $name) { if ($app['dbs.default'] === $name) {
// we use shortcuts here in case the default has been overridden // we use shortcuts here in case the default has been overridden
...@@ -74,18 +74,18 @@ class DoctrineServiceProvider implements ServiceProviderInterface ...@@ -74,18 +74,18 @@ class DoctrineServiceProvider implements ServiceProviderInterface
$manager = $app['dbs.event_manager'][$name]; $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 DriverManager::getConnection($options, $config, $manager);
}); };
} }
return $dbs; return $dbs;
}); };
$app['dbs.config'] = $app->share(function ($app) { $app['dbs.config'] = function ($app) {
$app['dbs.options.initializer'](); $app['dbs.options.initializer']();
$configs = new \Pimple(); $configs = new Container();
foreach ($app['dbs.options'] as $name => $options) { foreach ($app['dbs.options'] as $name => $options) {
$configs[$name] = new Configuration(); $configs[$name] = new Configuration();
...@@ -95,40 +95,36 @@ class DoctrineServiceProvider implements ServiceProviderInterface ...@@ -95,40 +95,36 @@ class DoctrineServiceProvider implements ServiceProviderInterface
} }
return $configs; return $configs;
}); };
$app['dbs.event_manager'] = $app->share(function ($app) { $app['dbs.event_manager'] = function ($app) {
$app['dbs.options.initializer'](); $app['dbs.options.initializer']();
$managers = new \Pimple(); $managers = new Container();
foreach ($app['dbs.options'] as $name => $options) { foreach ($app['dbs.options'] as $name => $options) {
$managers[$name] = new EventManager(); $managers[$name] = new EventManager();
} }
return $managers; return $managers;
}); };
// shortcuts for the "first" DB // shortcuts for the "first" DB
$app['db'] = $app->share(function ($app) { $app['db'] = function ($app) {
$dbs = $app['dbs']; $dbs = $app['dbs'];
return $dbs[$app['dbs.default']]; return $dbs[$app['dbs.default']];
}); };
$app['db.config'] = $app->share(function ($app) { $app['db.config'] = function ($app) {
$dbs = $app['dbs.config']; $dbs = $app['dbs.config'];
return $dbs[$app['dbs.default']]; return $dbs[$app['dbs.default']];
}); };
$app['db.event_manager'] = $app->share(function ($app) { $app['db.event_manager'] = function ($app) {
$dbs = $app['dbs.event_manager']; $dbs = $app['dbs.event_manager'];
return $dbs[$app['dbs.default']]; return $dbs[$app['dbs.default']];
}); };
}
public function boot(Application $app)
{
} }
} }
...@@ -11,8 +11,8 @@ ...@@ -11,8 +11,8 @@
namespace Silex\Provider; namespace Silex\Provider;
use Silex\Application; use Pimple\Container;
use Silex\ServiceProviderInterface; use Pimple\ServiceProviderInterface;
use Symfony\Component\Form\Extension\Csrf\CsrfExtension; use Symfony\Component\Form\Extension\Csrf\CsrfExtension;
use Symfony\Component\Form\Extension\Csrf\CsrfProvider\DefaultCsrfProvider; use Symfony\Component\Form\Extension\Csrf\CsrfProvider\DefaultCsrfProvider;
use Symfony\Component\Form\Extension\Csrf\CsrfProvider\SessionCsrfProvider; use Symfony\Component\Form\Extension\Csrf\CsrfProvider\SessionCsrfProvider;
...@@ -28,7 +28,7 @@ use Symfony\Component\Form\ResolvedFormTypeFactory; ...@@ -28,7 +28,7 @@ use Symfony\Component\Form\ResolvedFormTypeFactory;
*/ */
class FormServiceProvider implements ServiceProviderInterface 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')) { 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.'); 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 @@ class FormServiceProvider implements ServiceProviderInterface ...@@ -47,23 +47,23 @@ class FormServiceProvider implements ServiceProviderInterface
$app['form.secret'] = md5(__DIR__); $app['form.secret'] = md5(__DIR__);
$app['form.type.extensions'] = $app->share(function ($app) { $app['form.type.extensions'] = function ($app) {
return array(); return array();
}); };
$app['form.type.guessers'] = $app->share(function ($app) { $app['form.type.guessers'] = function ($app) {
return array(); return array();
}); };
$app['form.extension.csrf'] = $app->share(function ($app) { $app['form.extension.csrf'] = function ($app) {
if (isset($app['translator'])) { if (isset($app['translator'])) {
return new CsrfExtension($app['form.csrf_provider'], $app['translator']); return new CsrfExtension($app['form.csrf_provider'], $app['translator']);
} }
return new CsrfExtension($app['form.csrf_provider']); return new CsrfExtension($app['form.csrf_provider']);
}); };
$app['form.extensions'] = $app->share(function ($app) { $app['form.extensions'] = function ($app) {
$extensions = array( $extensions = array(
$app['form.extension.csrf'], $app['form.extension.csrf'],
new HttpFoundationExtension(), new HttpFoundationExtension(),
...@@ -79,9 +79,9 @@ class FormServiceProvider implements ServiceProviderInterface ...@@ -79,9 +79,9 @@ class FormServiceProvider implements ServiceProviderInterface
} }
return $extensions; return $extensions;
}); };
$app['form.factory'] = $app->share(function ($app) { $app['form.factory'] = function ($app) {
return Forms::createFormFactoryBuilder() return Forms::createFormFactoryBuilder()
->addExtensions($app['form.extensions']) ->addExtensions($app['form.extensions'])
->addTypeExtensions($app['form.type.extensions']) ->addTypeExtensions($app['form.type.extensions'])
...@@ -89,22 +89,18 @@ class FormServiceProvider implements ServiceProviderInterface ...@@ -89,22 +89,18 @@ class FormServiceProvider implements ServiceProviderInterface
->setResolvedTypeFactory($app['form.resolved_type_factory']) ->setResolvedTypeFactory($app['form.resolved_type_factory'])
->getFormFactory() ->getFormFactory()
; ;
}); };
$app['form.resolved_type_factory'] = $app->share(function ($app) { $app['form.resolved_type_factory'] = function ($app) {
return new ResolvedFormTypeFactory(); return new ResolvedFormTypeFactory();
}); };
$app['form.csrf_provider'] = $app->share(function ($app) { $app['form.csrf_provider'] = function ($app) {
if (isset($app['session'])) { if (isset($app['session'])) {
return new SessionCsrfProvider($app['session'], $app['form.secret']); return new SessionCsrfProvider($app['session'], $app['form.secret']);
} }
return new DefaultCsrfProvider($app['form.secret']); return new DefaultCsrfProvider($app['form.secret']);
}); };
}
public function boot(Application $app)
{
} }
} }
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
* file that was distributed with this source code. * 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\HttpKernel\HttpCache\HttpCache as BaseHttpCache;
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Request;
......
...@@ -11,9 +11,11 @@ ...@@ -11,9 +11,11 @@
namespace Silex\Provider; namespace Silex\Provider;
use Silex\Application; use Pimple\Container;
use Silex\ServiceProviderInterface; use Pimple\ServiceProviderInterface;
use Silex\HttpCache; 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\Esi;
use Symfony\Component\HttpKernel\HttpCache\Store; use Symfony\Component\HttpKernel\HttpCache\Store;
use Symfony\Component\HttpKernel\EventListener\EsiListener; use Symfony\Component\HttpKernel\EventListener\EsiListener;
...@@ -23,37 +25,37 @@ use Symfony\Component\HttpKernel\EventListener\EsiListener; ...@@ -23,37 +25,37 @@ use Symfony\Component\HttpKernel\EventListener\EsiListener;
* *
* @author Fabien Potencier <fabien@symfony.com> * @author Fabien Potencier <fabien@symfony.com>
*/ */
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( $app['http_cache.options'] = array_replace(
array( array(
'debug' => $app['debug'], 'debug' => isset($app['debug']) ? $app['debug'] : false,
), $app['http_cache.options'] ), $app['http_cache.options']
); );
return new HttpCache($app, $app['http_cache.store'], $app['http_cache.esi'], $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(); 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']); 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']); return new EsiListener($app['http_cache.esi']);
}); };
$app['http_cache.options'] = array(); $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']);
} }
} }
...@@ -11,8 +11,10 @@ ...@@ -11,8 +11,10 @@
namespace Silex\Provider; namespace Silex\Provider;
use Silex\Application; use Pimple\Container;
use Silex\ServiceProviderInterface; use Pimple\ServiceProviderInterface;
use Silex\Api\EventListenerProviderInterface;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\HttpKernel\Fragment\FragmentHandler; use Symfony\Component\HttpKernel\Fragment\FragmentHandler;
use Symfony\Component\HttpKernel\Fragment\InlineFragmentRenderer; use Symfony\Component\HttpKernel\Fragment\InlineFragmentRenderer;
use Symfony\Component\HttpKernel\Fragment\EsiFragmentRenderer; use Symfony\Component\HttpKernel\Fragment\EsiFragmentRenderer;
...@@ -23,55 +25,49 @@ use Symfony\Component\HttpKernel\UriSigner; ...@@ -23,55 +25,49 @@ use Symfony\Component\HttpKernel\UriSigner;
/** /**
* HttpKernel Fragment integration for Silex. * HttpKernel Fragment integration for Silex.
* *
* This service provider requires Symfony 2.4+.
*
* @author Fabien Potencier <fabien@symfony.com> * @author Fabien Potencier <fabien@symfony.com>
*/ */
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')) { $app['fragment.handler'] = function ($app) {
throw new \LogicException('The HTTP Fragment service provider only works with Symfony 2.4+.'); return new FragmentHandler($app['fragment.renderers'], isset($app['debug']) ? $app['debug'] : false, $app['request_stack']);
} };
$app['fragment.handler'] = $app->share(function ($app) {
return new FragmentHandler($app['fragment.renderers'], $app['debug'], $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 = new InlineFragmentRenderer($app['kernel'], $app['dispatcher']);
$renderer->setFragmentPath($app['fragment.path']); $renderer->setFragmentPath($app['fragment.path']);
return $renderer; return $renderer;
}); };
$app['fragment.renderer.hinclude'] = $app->share(function ($app) { $app['fragment.renderer.hinclude'] = function ($app) {
$renderer = new HIncludeFragmentRenderer(null, $app['uri_signer'], $app['fragment.renderer.hinclude.global_template'], $app['charset']); $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']); $renderer->setFragmentPath($app['fragment.path']);
return $renderer; 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 = new EsiFragmentRenderer($app['http_cache.esi'], $app['fragment.renderer.inline']);
$renderer->setFragmentPath($app['fragment.path']); $renderer->setFragmentPath($app['fragment.path']);
return $renderer; return $renderer;
}); };
$app['fragment.listener'] = $app->share(function ($app) { $app['fragment.listener'] = function ($app) {
return new FragmentListener($app['uri_signer'], $app['fragment.path']); 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']); return new UriSigner($app['uri_signer.secret']);
}); };
$app['uri_signer.secret'] = md5(__DIR__); $app['uri_signer.secret'] = md5(__DIR__);
$app['fragment.path'] = '/_fragment'; $app['fragment.path'] = '/_fragment';
$app['fragment.renderer.hinclude.global_template'] = null; $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']); $renderers = array($app['fragment.renderer.inline'], $app['fragment.renderer.hinclude']);
if (isset($app['http_cache.esi'])) { if (isset($app['http_cache.esi'])) {
...@@ -79,11 +75,11 @@ class HttpFragmentServiceProvider implements ServiceProviderInterface ...@@ -79,11 +75,11 @@ class HttpFragmentServiceProvider implements ServiceProviderInterface
} }
return $renderers; 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']);
} }
} }
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.
...@@ -9,13 +9,13 @@ ...@@ -9,13 +9,13 @@
* file that was distributed with this source code. * 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\Event\GetResponseEvent;
use Symfony\Component\HttpKernel\EventListener\LocaleListener as BaseLocaleListener; use Symfony\Component\HttpKernel\EventListener\LocaleListener as BaseLocaleListener;
use Symfony\Component\HttpFoundation\RequestStack; use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\Routing\RequestContextAwareInterface; use Symfony\Component\Routing\RequestContextAwareInterface;
use Silex\Application;
/** /**
* Initializes the locale based on the current request. * Initializes the locale based on the current request.
...@@ -26,7 +26,7 @@ class LocaleListener extends BaseLocaleListener ...@@ -26,7 +26,7 @@ class LocaleListener extends BaseLocaleListener
{ {
protected $app; 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); parent::__construct($app['locale'], $router, $requestStack);
......
<?php
/*
* This file is part of the Silex framework.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace 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 <fabien@symfony.com>
*/
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']);
}
}
...@@ -11,10 +11,15 @@ ...@@ -11,10 +11,15 @@
namespace Silex\Provider; namespace Silex\Provider;
use Pimple\Container;
use Pimple\ServiceProviderInterface;
use Monolog\Logger; use Monolog\Logger;
use Monolog\Handler\StreamHandler; use Monolog\Handler\StreamHandler;
use Silex\Application; 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 Symfony\Bridge\Monolog\Handler\DebugHandler;
use Silex\EventListener\LogListener; use Silex\EventListener\LogListener;
...@@ -23,9 +28,9 @@ use Silex\EventListener\LogListener; ...@@ -23,9 +28,9 @@ use Silex\EventListener\LogListener;
* *
* @author Fabien Potencier <fabien@symfony.com> * @author Fabien Potencier <fabien@symfony.com>
*/ */
class MonologServiceProvider implements ServiceProviderInterface class MonologServiceProvider implements ServiceProviderInterface, BootableProviderInterface
{ {
public function register(Application $app) public function register(Container $app)
{ {
$app['logger'] = function () use ($app) { $app['logger'] = function () use ($app) {
return $app['monolog']; return $app['monolog'];
...@@ -41,17 +46,17 @@ class MonologServiceProvider implements ServiceProviderInterface ...@@ -41,17 +46,17 @@ class MonologServiceProvider implements ServiceProviderInterface
$app['monolog.logger.class'] = $bridge ? 'Symfony\Bridge\Monolog\Logger' : 'Monolog\Logger'; $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 = new $app['monolog.logger.class']($app['monolog.name']);
$log->pushHandler($app['monolog.handler']); $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']); $log->pushHandler($app['monolog.handler.debug']);
} }
return $log; return $log;
}); };
$app['monolog.handler'] = function () use ($app) { $app['monolog.handler'] = function () use ($app) {
$level = MonologServiceProvider::translateLevel($app['monolog.level']); $level = MonologServiceProvider::translateLevel($app['monolog.level']);
...@@ -63,9 +68,9 @@ class MonologServiceProvider implements ServiceProviderInterface ...@@ -63,9 +68,9 @@ class MonologServiceProvider implements ServiceProviderInterface
return Logger::DEBUG; return Logger::DEBUG;
}; };
$app['monolog.listener'] = $app->share(function () use ($app) { $app['monolog.listener'] = function () use ($app) {
return new LogListener($app['logger']); return new LogListener($app['logger']);
}); };
$app['monolog.name'] = 'myapp'; $app['monolog.name'] = 'myapp';
} }
......
...@@ -11,8 +11,10 @@ ...@@ -11,8 +11,10 @@
namespace Silex\Provider; namespace Silex\Provider;
use Silex\Application; use Pimple\Container;
use Silex\ServiceProviderInterface; use Pimple\ServiceProviderInterface;
use Silex\Api\EventListenerProviderInterface;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\Security\Core\Authentication\Provider\RememberMeAuthenticationProvider; use Symfony\Component\Security\Core\Authentication\Provider\RememberMeAuthenticationProvider;
use Symfony\Component\Security\Http\Firewall\RememberMeListener; use Symfony\Component\Security\Http\Firewall\RememberMeListener;
use Symfony\Component\Security\Http\RememberMe\TokenBasedRememberMeServices; use Symfony\Component\Security\Http\RememberMe\TokenBasedRememberMeServices;
...@@ -23,13 +25,17 @@ use Symfony\Component\Security\Http\RememberMe\ResponseListener; ...@@ -23,13 +25,17 @@ use Symfony\Component\Security\Http\RememberMe\ResponseListener;
* *
* @author Jérôme Tamarelle <jerome@tamarelle.net> * @author Jérôme Tamarelle <jerome@tamarelle.net>
*/ */
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(); return new ResponseListener();
}); };
$app['security.authentication_listener.factory.remember_me'] = $app->protect(function ($name, $options) use ($app) { $app['security.authentication_listener.factory.remember_me'] = $app->protect(function ($name, $options) use ($app) {
if (empty($options['key'])) { if (empty($options['key'])) {
...@@ -57,7 +63,7 @@ class RememberMeServiceProvider implements ServiceProviderInterface ...@@ -57,7 +63,7 @@ class RememberMeServiceProvider implements ServiceProviderInterface
}); });
$app['security.remember_me.service._proto'] = $app->protect(function ($providerKey, $options) use ($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( $options = array_replace(array(
'name' => 'REMEMBERME', 'name' => 'REMEMBERME',
'lifetime' => 31536000, 'lifetime' => 31536000,
...@@ -69,36 +75,32 @@ class RememberMeServiceProvider implements ServiceProviderInterface ...@@ -69,36 +75,32 @@ class RememberMeServiceProvider implements ServiceProviderInterface
'remember_me_parameter' => '_remember_me', 'remember_me_parameter' => '_remember_me',
), $options); ), $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) { $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( $listener = new RememberMeListener(
$app['security'], $app['security'],
$app['security.remember_me.service.'.$providerKey], $app['security.remember_me.service.'.$providerKey],
$app['security.authentication_manager'], $app['security.authentication_manager'],
$app['logger'] isset($app['logger']) ? $app['logger'] : null
); );
return $listener; return $listener;
}); };
}); });
$app['security.authentication_provider.remember_me._proto'] = $app->protect(function ($name, $options) use ($app) { $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); 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'])) { $dispatcher->addSubscriber($app['security.remember_me.response_listener']);
throw new \LogicException('You must register the SecurityServiceProvider to use the RememberMeServiceProvider');
}
$app['dispatcher']->addSubscriber($app['security.remember_me.response_listener']);
} }
} }
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
* file that was distributed with this source code. * 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\RequestContext as SymfonyRequestContext;
use Symfony\Component\Routing\Matcher\UrlMatcherInterface; use Symfony\Component\Routing\Matcher\UrlMatcherInterface;
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
* file that was distributed with this source code. * file that was distributed with this source code.
*/ */
namespace Silex; namespace Silex\Provider\Routing;
use Symfony\Component\HttpFoundation\RedirectResponse; use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\Routing\Matcher\RedirectableUrlMatcher as BaseRedirectableUrlMatcher; use Symfony\Component\Routing\Matcher\RedirectableUrlMatcher as BaseRedirectableUrlMatcher;
......
<?php
/*
* This file is part of the Silex framework.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace 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 <fabien@symfony.com>
*/
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']);
}
}
...@@ -11,8 +11,8 @@ ...@@ -11,8 +11,8 @@
namespace Silex\Provider; namespace Silex\Provider;
use Silex\Application; use Pimple\Container;
use Silex\ServiceProviderInterface; use Pimple\ServiceProviderInterface;
use Symfony\Component\Serializer\Serializer; use Symfony\Component\Serializer\Serializer;
use Symfony\Component\Serializer\Encoder\JsonEncoder; use Symfony\Component\Serializer\Encoder\JsonEncoder;
use Symfony\Component\Serializer\Encoder\XmlEncoder; use Symfony\Component\Serializer\Encoder\XmlEncoder;
...@@ -33,31 +33,20 @@ class SerializerServiceProvider implements ServiceProviderInterface ...@@ -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 * 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}. * 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']); 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()); return array(new JsonEncoder(), new XmlEncoder());
}); };
$app['serializer.normalizers'] = $app->share(function () { $app['serializer.normalizers'] = function () {
return array(new CustomNormalizer(), new GetSetMethodNormalizer()); 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)
{
} }
} }
...@@ -11,21 +11,16 @@ ...@@ -11,21 +11,16 @@
namespace Silex\Provider; namespace Silex\Provider;
use Silex\Application; use Pimple\Container;
use Silex\ServiceProviderInterface; use Pimple\ServiceProviderInterface;
use Silex\ServiceControllerResolver; use Silex\ServiceControllerResolver;
class ServiceControllerServiceProvider implements ServiceProviderInterface 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']); return new ServiceControllerResolver($resolver, $app['callback_resolver']);
})); });
}
public function boot(Application $app)
{
// noop
} }
} }
...@@ -9,29 +9,31 @@ ...@@ -9,29 +9,31 @@
* file that was distributed with this source code. * file that was distributed with this source code.
*/ */
namespace Silex\Provider; namespace Silex\Provider\Session;
use Silex\Application; use Pimple\Container;
use Silex\ServiceProviderInterface; use Symfony\Component\HttpKernel\EventListener\SessionListener as BaseSessionListener;
use Symfony\Component\Routing\Generator\UrlGenerator;
/** /**
* Symfony Routing component Provider for URL generation. * Sets the session in the request.
* *
* @author Fabien Potencier <fabien@symfony.com> * @author Fabien Potencier <fabien@symfony.com>
*/ */
class UrlGeneratorServiceProvider implements ServiceProviderInterface class SessionListener extends BaseSessionListener
{ {
public function register(Application $app) private $app;
{
$app['url_generator'] = $app->share(function ($app) {
$app->flush();
return new UrlGenerator($app['routes'], $app['request_context']); public function __construct(Container $app)
}); {
$this->app = $app;
} }
public function boot(Application $app) protected function getSession()
{ {
if (!isset($this->app['session'])) {
return null;
}
return $this->app['session'];
} }
} }
<?php
/*
* This file is part of the Silex framework.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Silex\Provider\Session;
use Pimple\Container;
use Symfony\Component\HttpKernel\EventListener\TestSessionListener as BaseTestSessionListener;
/**
* Simulates sessions for testing purpose.
*
* @author Fabien Potencier <fabien@symfony.com>
*/
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'];
}
}
...@@ -11,34 +11,33 @@ ...@@ -11,34 +11,33 @@
namespace Silex\Provider; namespace Silex\Provider;
use Silex\Application; use Pimple\Container;
use Silex\ServiceProviderInterface; 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\Handler\NativeFileSessionHandler;
use Symfony\Component\HttpFoundation\Session\Storage\NativeSessionStorage; use Symfony\Component\HttpFoundation\Session\Storage\NativeSessionStorage;
use Symfony\Component\HttpFoundation\Session\Storage\MockFileSessionStorage; use Symfony\Component\HttpFoundation\Session\Storage\MockFileSessionStorage;
use Symfony\Component\HttpFoundation\Session\Session; 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. * Symfony HttpFoundation component Provider for sessions.
* *
* @author Fabien Potencier <fabien@symfony.com> * @author Fabien Potencier <fabien@symfony.com>
*/ */
class SessionServiceProvider implements ServiceProviderInterface class SessionServiceProvider implements ServiceProviderInterface, EventListenerProviderInterface
{ {
private $app; private $app;
public function register(Application $app) public function register(Container $app)
{ {
$this->app = $app; $this->app = $app;
$app['session.test'] = false; $app['session.test'] = false;
$app['session'] = $app->share(function ($app) { $app['session'] = function ($app) {
if (!isset($app['session.storage'])) { if (!isset($app['session.storage'])) {
if ($app['session.test']) { if ($app['session.test']) {
$app['session.storage'] = $app['session.storage.test']; $app['session.storage'] = $app['session.storage.test'];
...@@ -48,77 +47,42 @@ class SessionServiceProvider implements ServiceProviderInterface ...@@ -48,77 +47,42 @@ class SessionServiceProvider implements ServiceProviderInterface
} }
return new Session($app['session.storage']); 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']); 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( return new NativeSessionStorage(
$app['session.storage.options'], $app['session.storage.options'],
$app['session.storage.handler'] $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(); return new MockFileSessionStorage();
}); };
$app['session.listener.test'] = function ($app) {
return new TestSessionListener($app);
};
$app['session.storage.options'] = array(); $app['session.storage.options'] = array();
$app['session.default_locale'] = 'en'; $app['session.default_locale'] = 'en';
$app['session.storage.save_path'] = null; $app['session.storage.save_path'] = null;
} }
public function onEarlyKernelRequest(GetResponseEvent $event) public function subscribe(Container $app, EventDispatcherInterface $dispatcher)
{
$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)
{ {
$app['dispatcher']->addListener(KernelEvents::REQUEST, array($this, 'onEarlyKernelRequest'), 128); $dispatcher->addSubscriber($app['session.listener']);
if ($app['session.test']) { if ($app['session.test']) {
$app['dispatcher']->addListener(KernelEvents::REQUEST, array($this, 'onKernelRequest'), 192); $app['dispatcher']->addSubscriber($app['session.listener.test']);
$app['dispatcher']->addListener(KernelEvents::RESPONSE, array($this, 'onKernelResponse'), -128);
} }
} }
} }
...@@ -11,37 +11,41 @@ ...@@ -11,37 +11,41 @@
namespace Silex\Provider; namespace Silex\Provider;
use Silex\Application; use Pimple\Container;
use Silex\ServiceProviderInterface; 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. * Swiftmailer Provider.
* *
* @author Fabien Potencier <fabien@symfony.com> * @author Fabien Potencier <fabien@symfony.com>
*/ */
class SwiftmailerServiceProvider implements ServiceProviderInterface class SwiftmailerServiceProvider implements ServiceProviderInterface, EventListenerProviderInterface
{ {
public function register(Application $app) public function register(Container $app)
{ {
$app['swiftmailer.options'] = array(); $app['swiftmailer.options'] = array();
$app['mailer.initialized'] = false; $app['mailer.initialized'] = false;
$app['mailer'] = $app->share(function ($app) { $app['mailer'] = function ($app) {
$app['mailer.initialized'] = true; $app['mailer.initialized'] = true;
return new \Swift_Mailer($app['swiftmailer.spooltransport']); 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']); return new \Swift_SpoolTransport($app['swiftmailer.spool']);
}); };
$app['swiftmailer.spool'] = $app->share(function ($app) { $app['swiftmailer.spool'] = function ($app) {
return new \Swift_MemorySpool(); return new \Swift_MemorySpool();
}); };
$app['swiftmailer.transport'] = $app->share(function ($app) { $app['swiftmailer.transport'] = function ($app) {
$transport = new \Swift_Transport_EsmtpTransport( $transport = new \Swift_Transport_EsmtpTransport(
$app['swiftmailer.transport.buffer'], $app['swiftmailer.transport.buffer'],
array($app['swiftmailer.transport.authhandler']), array($app['swiftmailer.transport.authhandler']),
...@@ -65,28 +69,28 @@ class SwiftmailerServiceProvider implements ServiceProviderInterface ...@@ -65,28 +69,28 @@ class SwiftmailerServiceProvider implements ServiceProviderInterface
$transport->setAuthMode($options['auth_mode']); $transport->setAuthMode($options['auth_mode']);
return $transport; return $transport;
}); };
$app['swiftmailer.transport.buffer'] = $app->share(function () { $app['swiftmailer.transport.buffer'] = function () {
return new \Swift_Transport_StreamBuffer(new \Swift_StreamFilters_StringReplacementFilterFactory()); 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( return new \Swift_Transport_Esmtp_AuthHandler(array(
new \Swift_Transport_Esmtp_Auth_CramMd5Authenticator(), new \Swift_Transport_Esmtp_Auth_CramMd5Authenticator(),
new \Swift_Transport_Esmtp_Auth_LoginAuthenticator(), new \Swift_Transport_Esmtp_Auth_LoginAuthenticator(),
new \Swift_Transport_Esmtp_Auth_PlainAuthenticator(), new \Swift_Transport_Esmtp_Auth_PlainAuthenticator(),
)); ));
}); };
$app['swiftmailer.transport.eventdispatcher'] = $app->share(function () { $app['swiftmailer.transport.eventdispatcher'] = function () {
return new \Swift_Events_SimpleEventDispatcher(); 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 // To speed things up (by avoiding Swift Mailer initialization), flush
// messages only if our mailer has been created (potentially used) // messages only if our mailer has been created (potentially used)
if ($app['mailer.initialized']) { if ($app['mailer.initialized']) {
......
...@@ -9,13 +9,14 @@ ...@@ -9,13 +9,14 @@
* file that was distributed with this source code. * 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\Translator as BaseTranslator;
use Symfony\Component\Translation\MessageSelector; 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 <fabien@symfony.com> * @author Fabien Potencier <fabien@symfony.com>
*/ */
...@@ -23,7 +24,7 @@ class Translator extends BaseTranslator ...@@ -23,7 +24,7 @@ class Translator extends BaseTranslator
{ {
protected $app; protected $app;
public function __construct(Application $app, MessageSelector $selector) public function __construct(Container $app, MessageSelector $selector)
{ {
$this->app = $app; $this->app = $app;
......
...@@ -11,9 +11,9 @@ ...@@ -11,9 +11,9 @@
namespace Silex\Provider; namespace Silex\Provider;
use Silex\Application; use Pimple\Container;
use Silex\ServiceProviderInterface; use Pimple\ServiceProviderInterface;
use Silex\Translator; use Silex\Provider\Translation\Translator;
use Symfony\Component\Translation\MessageSelector; use Symfony\Component\Translation\MessageSelector;
use Symfony\Component\Translation\Loader\ArrayLoader; use Symfony\Component\Translation\Loader\ArrayLoader;
use Symfony\Component\Translation\Loader\XliffFileLoader; use Symfony\Component\Translation\Loader\XliffFileLoader;
...@@ -25,18 +25,15 @@ use Symfony\Component\Translation\Loader\XliffFileLoader; ...@@ -25,18 +25,15 @@ use Symfony\Component\Translation\Loader\XliffFileLoader;
*/ */
class TranslationServiceProvider implements ServiceProviderInterface class TranslationServiceProvider implements ServiceProviderInterface
{ {
public function register(Application $app) public function register(Container $app)
{ {
$app['translator'] = $app->share(function ($app) { $app['translator'] = function ($app) {
$translator = new Translator($app, $app['translator.message_selector']); if (!isset($app['locale'])) {
throw new \LogicException('You must register the LocaleServiceProvider to use the TranslationServiceProvider');
// Handle deprecated 'locale_fallback'
if (isset($app['locale_fallback'])) {
$app['locale_fallbacks'] = (array) $app['locale_fallback'];
} }
$translator = new Translator($app, $app['translator.message_selector']);
$translator->setFallbackLocales($app['locale_fallbacks']); $translator->setFallbackLocales($app['locale_fallbacks']);
$translator->addLoader('array', new ArrayLoader()); $translator->addLoader('array', new ArrayLoader());
$translator->addLoader('xliff', new XliffFileLoader()); $translator->addLoader('xliff', new XliffFileLoader());
...@@ -47,17 +44,13 @@ class TranslationServiceProvider implements ServiceProviderInterface ...@@ -47,17 +44,13 @@ class TranslationServiceProvider implements ServiceProviderInterface
} }
return $translator; return $translator;
}); };
$app['translator.message_selector'] = $app->share(function () { $app['translator.message_selector'] = function () {
return new MessageSelector(); return new MessageSelector();
}); };
$app['translator.domains'] = array(); $app['translator.domains'] = array();
$app['locale_fallbacks'] = array('en'); $app['locale_fallbacks'] = array('en');
} }
public function boot(Application $app)
{
}
} }
<?php
/*
* This file is part of the Silex framework.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Silex\Provider;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\HttpKernelInterface;
/**
* Twig extension.
*
* @author Fabien Potencier <fabien@symfony.com>
*
* @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';
}
}
...@@ -11,8 +11,8 @@ ...@@ -11,8 +11,8 @@
namespace Silex\Provider; namespace Silex\Provider;
use Silex\Application; use Pimple\Container;
use Silex\ServiceProviderInterface; use Pimple\ServiceProviderInterface;
use Symfony\Bridge\Twig\Extension\RoutingExtension; use Symfony\Bridge\Twig\Extension\RoutingExtension;
use Symfony\Bridge\Twig\Extension\TranslationExtension; use Symfony\Bridge\Twig\Extension\TranslationExtension;
use Symfony\Bridge\Twig\Extension\FormExtension; use Symfony\Bridge\Twig\Extension\FormExtension;
...@@ -28,26 +28,26 @@ use Symfony\Bridge\Twig\Form\TwigRenderer; ...@@ -28,26 +28,26 @@ use Symfony\Bridge\Twig\Form\TwigRenderer;
*/ */
class TwigServiceProvider implements ServiceProviderInterface class TwigServiceProvider implements ServiceProviderInterface
{ {
public function register(Application $app) public function register(Container $app)
{ {
$app['twig.options'] = array(); $app['twig.options'] = array();
$app['twig.form.templates'] = array('form_div_layout.html.twig'); $app['twig.form.templates'] = array('form_div_layout.html.twig');
$app['twig.path'] = array(); $app['twig.path'] = array();
$app['twig.templates'] = array(); $app['twig.templates'] = array();
$app['twig'] = $app->share(function ($app) { $app['twig'] = function ($app) {
$app['twig.options'] = array_replace( $app['twig.options'] = array_replace(
array( array(
'charset' => $app['charset'], 'charset' => isset($app['charset']) ? $app['charset'] : 'UTF-8',
'debug' => $app['debug'], 'debug' => isset($app['debug']) ? $app['debug'] : false,
'strict_variables' => $app['debug'], 'strict_variables' => isset($app['debug']) ? $app['debug'] : false,
), $app['twig.options'] ), $app['twig.options']
); );
$twig = new \Twig_Environment($app['twig.loader'], $app['twig.options']); $twig = new \Twig_Environment($app['twig.loader'], $app['twig.options']);
$twig->addGlobal('app', $app); $twig->addGlobal('app', $app);
if ($app['debug']) { if (isset($app['debug']) && $app['debug']) {
$twig->addExtension(new \Twig_Extension_Debug()); $twig->addExtension(new \Twig_Extension_Debug());
} }
...@@ -68,19 +68,16 @@ class TwigServiceProvider implements ServiceProviderInterface ...@@ -68,19 +68,16 @@ class TwigServiceProvider implements ServiceProviderInterface
$app['fragment.renderer.hinclude']->setTemplating($twig); $app['fragment.renderer.hinclude']->setTemplating($twig);
$twig->addExtension(new HttpKernelExtension($app['fragment.handler'])); $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'])) { 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']); 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']); return new TwigRenderer($app['twig.form.engine'], $app['form.csrf_provider']);
}); };
$twig->addExtension(new FormExtension($app['twig.form.renderer'])); $twig->addExtension(new FormExtension($app['twig.form.renderer']));
...@@ -92,25 +89,21 @@ class TwigServiceProvider implements ServiceProviderInterface ...@@ -92,25 +89,21 @@ class TwigServiceProvider implements ServiceProviderInterface
} }
return $twig; return $twig;
}); };
$app['twig.loader.filesystem'] = $app->share(function ($app) { $app['twig.loader.filesystem'] = function ($app) {
return new \Twig_Loader_Filesystem($app['twig.path']); 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']); 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( return new \Twig_Loader_Chain(array(
$app['twig.loader.array'], $app['twig.loader.array'],
$app['twig.loader.filesystem'], $app['twig.loader.filesystem'],
)); ));
}); };
}
public function boot(Application $app)
{
} }
} }
...@@ -9,8 +9,9 @@ ...@@ -9,8 +9,9 @@
* file that was distributed with this source code. * 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\Constraint;
use Symfony\Component\Validator\ConstraintValidatorFactoryInterface; use Symfony\Component\Validator\ConstraintValidatorFactoryInterface;
use Symfony\Component\Validator\ConstraintValidator; use Symfony\Component\Validator\ConstraintValidator;
...@@ -24,7 +25,7 @@ use Symfony\Component\Validator\ConstraintValidator; ...@@ -24,7 +25,7 @@ use Symfony\Component\Validator\ConstraintValidator;
class ConstraintValidatorFactory implements ConstraintValidatorFactoryInterface class ConstraintValidatorFactory implements ConstraintValidatorFactoryInterface
{ {
/** /**
* @var \Pimple * @var Container
*/ */
protected $container; protected $container;
...@@ -41,10 +42,10 @@ class ConstraintValidatorFactory implements ConstraintValidatorFactoryInterface ...@@ -41,10 +42,10 @@ class ConstraintValidatorFactory implements ConstraintValidatorFactoryInterface
/** /**
* Constructor * Constructor
* *
* @param \Pimple $container DI container * @param Container $container DI container
* @param array $serviceNames Validator service names * @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->container = $container;
$this->serviceNames = $serviceNames; $this->serviceNames = $serviceNames;
......
...@@ -11,9 +11,9 @@ ...@@ -11,9 +11,9 @@
namespace Silex\Provider; namespace Silex\Provider;
use Silex\Application; use Pimple\Container;
use Silex\ServiceProviderInterface; use Pimple\ServiceProviderInterface;
use Silex\ConstraintValidatorFactory; use Silex\Provider\Validator\ConstraintValidatorFactory;
use Symfony\Component\Validator\Validator; use Symfony\Component\Validator\Validator;
use Symfony\Component\Validator\DefaultTranslator; use Symfony\Component\Validator\DefaultTranslator;
use Symfony\Component\Validator\Mapping\ClassMetadataFactory; use Symfony\Component\Validator\Mapping\ClassMetadataFactory;
...@@ -26,9 +26,9 @@ use Symfony\Component\Validator\Mapping\Loader\StaticMethodLoader; ...@@ -26,9 +26,9 @@ use Symfony\Component\Validator\Mapping\Loader\StaticMethodLoader;
*/ */
class ValidatorServiceProvider implements ServiceProviderInterface 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'); $r = new \ReflectionClass('Symfony\Component\Validator\Validator');
if (isset($app['translator'])) { if (isset($app['translator'])) {
...@@ -42,24 +42,20 @@ class ValidatorServiceProvider implements ServiceProviderInterface ...@@ -42,24 +42,20 @@ class ValidatorServiceProvider implements ServiceProviderInterface
'validators', 'validators',
$app['validator.object_initializers'] $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()); 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(); $validators = isset($app['validator.validator_service_ids']) ? $app['validator.validator_service_ids'] : array();
return new ConstraintValidatorFactory($app, $validators); return new ConstraintValidatorFactory($app, $validators);
}); };
$app['validator.object_initializers'] = $app->share(function ($app) { $app['validator.object_initializers'] = function ($app) {
return array(); return array();
}); };
}
public function boot(Application $app)
{
} }
} }
{
"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"
}
}
}
<?php
/*
* This file is part of the Silex framework.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace 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 <fabien@symfony.com>
*/
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'
<?php
/*
* This file is part of the Silex framework.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
*/
Phar::mapPhar('silex.phar');
require_once 'phar://silex.phar/vendor/autoload.php';
if ('cli' === php_sapi_name() && basename(__FILE__) === basename($_SERVER['argv'][0]) && isset($_SERVER['argv'][1])) {
switch ($_SERVER['argv'][1]) {
case 'update':
$remoteFilename = 'http://silex.sensiolabs.org/get/silex.phar';
$localFilename = __DIR__.'/silex.phar';
file_put_contents($localFilename, file_get_contents($remoteFilename));
break;
case 'check':
$latest = trim(file_get_contents('http://silex.sensiolabs.org/get/version'));
if ($latest != Silex\Application::VERSION) {
printf("A newer Silex version is available (%s).\n", $latest);
} else {
print("You are using the latest Silex version.\n");
}
break;
case 'version':
printf("Silex version %s\n", Silex\Application::VERSION);
break;
default:
printf("Unknown command '%s' (available commands: version, check, and update).\n", $_SERVER['argv'][1]);
}
exit(0);
}
__HALT_COMPILER();
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;
}
}
...@@ -39,9 +39,9 @@ class MonologTraitTest extends \PHPUnit_Framework_TestCase ...@@ -39,9 +39,9 @@ class MonologTraitTest extends \PHPUnit_Framework_TestCase
{ {
$app = new MonologApplication(); $app = new MonologApplication();
$app->register(new MonologServiceProvider(), array( $app->register(new MonologServiceProvider(), array(
'monolog.handler' => $app->share(function () use ($app) { 'monolog.handler' => function () use ($app) {
return new TestHandler($app['monolog.level']); return new TestHandler($app['monolog.level']);
}), },
)); ));
return $app; return $app;
......
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
namespace Silex\Tests\Application; namespace Silex\Tests\Application;
use Silex\Application; use Silex\Application;
use Silex\Provider\UrlGeneratorServiceProvider; use Silex\Provider\RoutingServiceProvider;
/** /**
* UrlGeneratorTrait test cases. * UrlGeneratorTrait test cases.
...@@ -25,7 +25,7 @@ class UrlGeneratorTraitTest extends \PHPUnit_Framework_TestCase ...@@ -25,7 +25,7 @@ class UrlGeneratorTraitTest extends \PHPUnit_Framework_TestCase
{ {
public function testUrl() public function testUrl()
{ {
$app = $this->createApplication(); $app = new UrlGeneratorApplication();
$app['url_generator'] = $translator = $this->getMockBuilder('Symfony\Component\Routing\Generator\UrlGeneratorInterface')->disableOriginalConstructor()->getMock(); $app['url_generator'] = $translator = $this->getMockBuilder('Symfony\Component\Routing\Generator\UrlGeneratorInterface')->disableOriginalConstructor()->getMock();
$translator->expects($this->once())->method('generate')->with('foo', array(), true); $translator->expects($this->once())->method('generate')->with('foo', array(), true);
$app->url('foo'); $app->url('foo');
...@@ -33,17 +33,9 @@ class UrlGeneratorTraitTest extends \PHPUnit_Framework_TestCase ...@@ -33,17 +33,9 @@ class UrlGeneratorTraitTest extends \PHPUnit_Framework_TestCase
public function testPath() public function testPath()
{ {
$app = $this->createApplication(); $app = new UrlGeneratorApplication();
$app['url_generator'] = $translator = $this->getMockBuilder('Symfony\Component\Routing\Generator\UrlGeneratorInterface')->disableOriginalConstructor()->getMock(); $app['url_generator'] = $translator = $this->getMockBuilder('Symfony\Component\Routing\Generator\UrlGeneratorInterface')->disableOriginalConstructor()->getMock();
$translator->expects($this->once())->method('generate')->with('foo', array(), false); $translator->expects($this->once())->method('generate')->with('foo', array(), false);
$app->path('foo'); $app->path('foo');
} }
public function createApplication()
{
$app = new UrlGeneratorApplication();
$app->register(new UrlGeneratorServiceProvider());
return $app;
}
} }
...@@ -416,30 +416,6 @@ class ApplicationTest extends \PHPUnit_Framework_TestCase ...@@ -416,30 +416,6 @@ class ApplicationTest extends \PHPUnit_Framework_TestCase
$app->handle(Request::create('/'), HttpKernelInterface::MASTER_REQUEST, false); $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() public function testSubRequest()
{ {
$app = new Application(); $app = new Application();
...@@ -453,31 +429,10 @@ class ApplicationTest extends \PHPUnit_Framework_TestCase ...@@ -453,31 +429,10 @@ class ApplicationTest extends \PHPUnit_Framework_TestCase
$this->assertEquals('foo', $app->handle(Request::create('/'))->getContent()); $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() public function testRegisterShouldReturnSelf()
{ {
$app = new Application(); $app = new Application();
$provider = $this->getMock('Silex\ServiceProviderInterface'); $provider = $this->getMock('Pimple\ServiceProviderInterface');
$this->assertSame($app, $app->register($provider)); $this->assertSame($app, $app->register($provider));
} }
...@@ -542,6 +497,18 @@ class ApplicationTest extends \PHPUnit_Framework_TestCase ...@@ -542,6 +497,18 @@ class ApplicationTest extends \PHPUnit_Framework_TestCase
$response = $app->handle(Request::create('/foo')); $response = $app->handle(Request::create('/foo'));
$this->assertEquals(301, $response->getStatusCode()); $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 class FooController
......
...@@ -11,13 +11,14 @@ ...@@ -11,13 +11,14 @@
namespace Silex\Tests; namespace Silex\Tests;
use Pimple\Container;
use Silex\CallbackResolver; use Silex\CallbackResolver;
class CallbackResolverTest extends \PHPUnit_Framework_Testcase class CallbackResolverTest extends \PHPUnit_Framework_Testcase
{ {
public function setup() public function setup()
{ {
$this->app = new \Pimple(); $this->app = new Container();
$this->resolver = new CallbackResolver($this->app); $this->resolver = new CallbackResolver($this->app);
} }
......
...@@ -28,9 +28,9 @@ class CallbackServicesTest extends \PHPUnit_Framework_TestCase ...@@ -28,9 +28,9 @@ class CallbackServicesTest extends \PHPUnit_Framework_TestCase
{ {
$app = new Application(); $app = new Application();
$app['service'] = $app->share(function () { $app['service'] = function () {
return new self(); return new self();
}); };
$app->before('service:beforeApp'); $app->before('service:beforeApp');
$app->after('service:afterApp'); $app->after('service:afterApp');
......
...@@ -22,11 +22,11 @@ class LazyDispatcherTest extends \PHPUnit_Framework_TestCase ...@@ -22,11 +22,11 @@ class LazyDispatcherTest extends \PHPUnit_Framework_TestCase
$dispatcherCreated = false; $dispatcherCreated = false;
$app = new Application(); $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; $dispatcherCreated = true;
return $dispatcher; return $dispatcher;
})); });
$app->before(function () {}); $app->before(function () {});
......
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
namespace Silex\Tests; namespace Silex\Tests;
use Silex\LazyUrlMatcher; use Silex\Provider\Routing\LazyUrlMatcher;
/** /**
* LazyUrlMatcher test case. * LazyUrlMatcher test case.
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
namespace Silex\Tests; namespace Silex\Tests;
use Silex\Application; use Silex\Application;
use Silex\Provider\LocaleServiceProvider;
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\HttpKernelInterface; use Symfony\Component\HttpKernel\HttpKernelInterface;
...@@ -25,17 +26,20 @@ class LocaleTest extends \PHPUnit_Framework_TestCase ...@@ -25,17 +26,20 @@ class LocaleTest extends \PHPUnit_Framework_TestCase
public function testLocale() public function testLocale()
{ {
$app = new Application(); $app = new Application();
$app->register(new LocaleServiceProvider());
$app->get('/', function (Request $request) { return $request->getLocale(); }); $app->get('/', function (Request $request) { return $request->getLocale(); });
$response = $app->handle(Request::create('/')); $response = $app->handle(Request::create('/'));
$this->assertEquals('en', $response->getContent()); $this->assertEquals('en', $response->getContent());
$app = new Application(); $app = new Application();
$app->register(new LocaleServiceProvider());
$app['locale'] = 'fr'; $app['locale'] = 'fr';
$app->get('/', function (Request $request) { return $request->getLocale(); }); $app->get('/', function (Request $request) { return $request->getLocale(); });
$response = $app->handle(Request::create('/')); $response = $app->handle(Request::create('/'));
$this->assertEquals('fr', $response->getContent()); $this->assertEquals('fr', $response->getContent());
$app = new Application(); $app = new Application();
$app->register(new LocaleServiceProvider());
$app->get('/{_locale}', function (Request $request) { return $request->getLocale(); }); $app->get('/{_locale}', function (Request $request) { return $request->getLocale(); });
$response = $app->handle(Request::create('/es')); $response = $app->handle(Request::create('/es'));
$this->assertEquals('es', $response->getContent()); $this->assertEquals('es', $response->getContent());
...@@ -44,6 +48,7 @@ class LocaleTest extends \PHPUnit_Framework_TestCase ...@@ -44,6 +48,7 @@ class LocaleTest extends \PHPUnit_Framework_TestCase
public function testLocaleInSubRequests() public function testLocaleInSubRequests()
{ {
$app = new Application(); $app = new Application();
$app->register(new LocaleServiceProvider());
$app->get('/embed/{_locale}', function (Request $request) { return $request->getLocale(); }); $app->get('/embed/{_locale}', function (Request $request) { return $request->getLocale(); });
$app->get('/{_locale}', function (Request $request) use ($app) { $app->get('/{_locale}', function (Request $request) use ($app) {
return $request->getLocale().$app->handle(Request::create('/embed/es'), HttpKernelInterface::SUB_REQUEST)->getContent().$request->getLocale(); return $request->getLocale().$app->handle(Request::create('/embed/es'), HttpKernelInterface::SUB_REQUEST)->getContent().$request->getLocale();
...@@ -52,6 +57,7 @@ class LocaleTest extends \PHPUnit_Framework_TestCase ...@@ -52,6 +57,7 @@ class LocaleTest extends \PHPUnit_Framework_TestCase
$this->assertEquals('fresfr', $response->getContent()); $this->assertEquals('fresfr', $response->getContent());
$app = new Application(); $app = new Application();
$app->register(new LocaleServiceProvider());
$app->get('/embed', function (Request $request) { return $request->getLocale(); }); $app->get('/embed', function (Request $request) { return $request->getLocale(); });
$app->get('/{_locale}', function (Request $request) use ($app) { $app->get('/{_locale}', function (Request $request) use ($app) {
return $request->getLocale().$app->handle(Request::create('/embed'), HttpKernelInterface::SUB_REQUEST)->getContent().$request->getLocale(); return $request->getLocale().$app->handle(Request::create('/embed'), HttpKernelInterface::SUB_REQUEST)->getContent().$request->getLocale();
...@@ -64,6 +70,7 @@ class LocaleTest extends \PHPUnit_Framework_TestCase ...@@ -64,6 +70,7 @@ class LocaleTest extends \PHPUnit_Framework_TestCase
public function testLocaleWithBefore() public function testLocaleWithBefore()
{ {
$app = new Application(); $app = new Application();
$app->register(new LocaleServiceProvider());
$app->before(function (Request $request) use ($app) { $request->setLocale('fr'); }); $app->before(function (Request $request) use ($app) { $request->setLocale('fr'); });
$app->get('/embed', function (Request $request) { return $request->getLocale(); }); $app->get('/embed', function (Request $request) { return $request->getLocale(); });
$app->get('/', function (Request $request) use ($app) { $app->get('/', function (Request $request) use ($app) {
......
...@@ -191,8 +191,8 @@ class MiddlewareTest extends \PHPUnit_Framework_TestCase ...@@ -191,8 +191,8 @@ class MiddlewareTest extends \PHPUnit_Framework_TestCase
{ {
$app = new Application(); $app = new Application();
$app->before(function () use ($app) { $app->before(function (Request $request) use ($app) {
$app['project'] = $app['request']->get('project'); $app['project'] = $request->get('project');
}); });
$app->match('/foo/{project}', function () use ($app) { $app->match('/foo/{project}', function () use ($app) {
......
...@@ -35,11 +35,11 @@ class FormServiceProviderTest extends \PHPUnit_Framework_TestCase ...@@ -35,11 +35,11 @@ class FormServiceProviderTest extends \PHPUnit_Framework_TestCase
$app->register(new FormServiceProvider()); $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(); $extensions[] = new DummyFormTypeExtension();
return $extensions; return $extensions;
})); });
$form = $app['form.factory']->createBuilder('form', array()) $form = $app['form.factory']->createBuilder('form', array())
->add('file', 'file', array('image_path' => 'webPath')) ->add('file', 'file', array('image_path' => 'webPath'))
...@@ -54,11 +54,11 @@ class FormServiceProviderTest extends \PHPUnit_Framework_TestCase ...@@ -54,11 +54,11 @@ class FormServiceProviderTest extends \PHPUnit_Framework_TestCase
$app->register(new FormServiceProvider()); $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()); $guessers[] = new FormTypeGuesserChain(array());
return $guessers; return $guessers;
})); });
$this->assertInstanceOf('Symfony\Component\Form\FormFactory', $app['form.factory']); $this->assertInstanceOf('Symfony\Component\Form\FormFactory', $app['form.factory']);
} }
...@@ -78,9 +78,9 @@ class FormServiceProviderTest extends \PHPUnit_Framework_TestCase ...@@ -78,9 +78,9 @@ class FormServiceProviderTest extends \PHPUnit_Framework_TestCase
); );
$app['locale'] = 'de'; $app['locale'] = 'de';
$app['form.csrf_provider'] = $app->share(function () { $app['form.csrf_provider'] = function () {
return new FakeCsrfProvider(); return new FakeCsrfProvider();
}); };
$form = $app['form.factory']->createBuilder('form', array()) $form = $app['form.factory']->createBuilder('form', array())
->getForm(); ->getForm();
......
...@@ -31,7 +31,7 @@ class HttpCacheServiceProviderTest extends \PHPUnit_Framework_TestCase ...@@ -31,7 +31,7 @@ class HttpCacheServiceProviderTest extends \PHPUnit_Framework_TestCase
'http_cache.cache_dir' => sys_get_temp_dir().'/silex_http_cache_'.uniqid(), '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; return $app;
} }
......
...@@ -185,11 +185,11 @@ class MonologServiceProviderTest extends \PHPUnit_Framework_TestCase ...@@ -185,11 +185,11 @@ class MonologServiceProviderTest extends \PHPUnit_Framework_TestCase
$app->register(new MonologServiceProvider()); $app->register(new MonologServiceProvider());
$app['monolog.handler'] = $app->share(function () use ($app) { $app['monolog.handler'] = function () use ($app) {
$level = MonologServiceProvider::translateLevel($app['monolog.level']); $level = MonologServiceProvider::translateLevel($app['monolog.level']);
return new TestHandler($level); return new TestHandler($level);
}); };
return $app; return $app;
} }
......
...@@ -12,22 +12,20 @@ ...@@ -12,22 +12,20 @@
namespace Silex\Tests\Provider; namespace Silex\Tests\Provider;
use Silex\Application; use Silex\Application;
use Silex\Provider\UrlGeneratorServiceProvider; use Silex\Provider\RoutingServiceProvider;
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Request;
/** /**
* UrlGeneratorProvider test cases. * RoutingProvider test cases.
* *
* @author Igor Wiedler <igor@wiedler.ch> * @author Igor Wiedler <igor@wiedler.ch>
*/ */
class UrlGeneratorServiceProviderTest extends \PHPUnit_Framework_TestCase class RoutingServiceProviderTest extends \PHPUnit_Framework_TestCase
{ {
public function testRegister() public function testRegister()
{ {
$app = new Application(); $app = new Application();
$app->register(new UrlGeneratorServiceProvider());
$app->get('/hello/{name}', function ($name) {}) $app->get('/hello/{name}', function ($name) {})
->bind('hello'); ->bind('hello');
...@@ -43,8 +41,6 @@ class UrlGeneratorServiceProviderTest extends \PHPUnit_Framework_TestCase ...@@ -43,8 +41,6 @@ class UrlGeneratorServiceProviderTest extends \PHPUnit_Framework_TestCase
{ {
$app = new Application(); $app = new Application();
$app->register(new UrlGeneratorServiceProvider());
$app->get('/hello/{name}', function ($name) {}) $app->get('/hello/{name}', function ($name) {})
->bind('hello'); ->bind('hello');
...@@ -62,8 +58,6 @@ class UrlGeneratorServiceProviderTest extends \PHPUnit_Framework_TestCase ...@@ -62,8 +58,6 @@ class UrlGeneratorServiceProviderTest extends \PHPUnit_Framework_TestCase
{ {
$app = new Application(); $app = new Application();
$app->register(new UrlGeneratorServiceProvider());
$app->get('/hello/{name}', function ($name) {}) $app->get('/hello/{name}', function ($name) {})
->bind('hello'); ->bind('hello');
...@@ -81,8 +75,6 @@ class UrlGeneratorServiceProviderTest extends \PHPUnit_Framework_TestCase ...@@ -81,8 +75,6 @@ class UrlGeneratorServiceProviderTest extends \PHPUnit_Framework_TestCase
{ {
$app = new Application(); $app = new Application();
$app->register(new UrlGeneratorServiceProvider());
$app->get('/insecure', function () {}) $app->get('/insecure', function () {})
->bind('insecure_page') ->bind('insecure_page')
->requireHttp(); ->requireHttp();
...@@ -101,8 +93,6 @@ class UrlGeneratorServiceProviderTest extends \PHPUnit_Framework_TestCase ...@@ -101,8 +93,6 @@ class UrlGeneratorServiceProviderTest extends \PHPUnit_Framework_TestCase
{ {
$app = new Application(); $app = new Application();
$app->register(new UrlGeneratorServiceProvider());
$app->get('/secure', function () {}) $app->get('/secure', function () {})
->bind('secure_page') ->bind('secure_page')
->requireHttps(); ->requireHttps();
......
...@@ -200,7 +200,9 @@ class SecurityServiceProviderTest extends WebTestCase ...@@ -200,7 +200,9 @@ class SecurityServiceProviderTest extends WebTestCase
'default' => array( 'default' => array(
'pattern' => '^.*$', 'pattern' => '^.*$',
'anonymous' => true, 'anonymous' => true,
'form' => true, 'form' => array(
'require_previous_session' => false,
),
'logout' => true, 'logout' => true,
'users' => array( 'users' => array(
// password is foo // password is foo
......
...@@ -34,9 +34,9 @@ class SwiftmailerServiceProviderTest extends \PHPUnit_Framework_TestCase ...@@ -34,9 +34,9 @@ class SwiftmailerServiceProviderTest extends \PHPUnit_Framework_TestCase
$app->register(new SwiftmailerServiceProvider()); $app->register(new SwiftmailerServiceProvider());
$app->boot(); $app->boot();
$app['swiftmailer.spool'] = $app->share(function () { $app['swiftmailer.spool'] = function () {
return new SpoolStub(); return new SpoolStub();
}); };
$app->get('/', function() use ($app) { $app->get('/', function() use ($app) {
$app['mailer']->send(\Swift_Message::newInstance()); $app['mailer']->send(\Swift_Message::newInstance());
...@@ -60,9 +60,9 @@ class SwiftmailerServiceProviderTest extends \PHPUnit_Framework_TestCase ...@@ -60,9 +60,9 @@ class SwiftmailerServiceProviderTest extends \PHPUnit_Framework_TestCase
$app->register(new SwiftmailerServiceProvider()); $app->register(new SwiftmailerServiceProvider());
$app->boot(); $app->boot();
$app['swiftmailer.spool'] = $app->share(function () { $app['swiftmailer.spool'] = function () {
return new SpoolStub(); return new SpoolStub();
}); };
$app->get('/', function() use ($app) { }); $app->get('/', function() use ($app) { });
......
...@@ -13,6 +13,7 @@ namespace Silex\Tests\Provider; ...@@ -13,6 +13,7 @@ namespace Silex\Tests\Provider;
use Silex\Application; use Silex\Application;
use Silex\Provider\TranslationServiceProvider; use Silex\Provider\TranslationServiceProvider;
use Silex\Provider\LocaleServiceProvider;
/** /**
* TranslationProvider test cases. * TranslationProvider test cases.
...@@ -28,6 +29,7 @@ class TranslationServiceProviderTest extends \PHPUnit_Framework_TestCase ...@@ -28,6 +29,7 @@ class TranslationServiceProviderTest extends \PHPUnit_Framework_TestCase
{ {
$app = new Application(); $app = new Application();
$app->register(new LocaleServiceProvider());
$app->register(new TranslationServiceProvider()); $app->register(new TranslationServiceProvider());
$app['translator.domains'] = array( $app['translator.domains'] = array(
'messages' => array( 'messages' => array(
...@@ -102,15 +104,6 @@ class TranslationServiceProviderTest extends \PHPUnit_Framework_TestCase ...@@ -102,15 +104,6 @@ class TranslationServiceProviderTest extends \PHPUnit_Framework_TestCase
$this->assertEquals($expected, $result); $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() public function testFallbacks()
{ {
$app = $this->getPreparedApp(); $app = $this->getPreparedApp();
......
...@@ -39,30 +39,6 @@ class TwigServiceProviderTest extends \PHPUnit_Framework_TestCase ...@@ -39,30 +39,6 @@ class TwigServiceProviderTest extends \PHPUnit_Framework_TestCase
$this->assertEquals('Hello john!', $response->getContent()); $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() public function testLoaderPriority()
{ {
$app = new Application(); $app = new Application();
...@@ -71,9 +47,9 @@ class TwigServiceProviderTest extends \PHPUnit_Framework_TestCase ...@@ -71,9 +47,9 @@ class TwigServiceProviderTest extends \PHPUnit_Framework_TestCase
)); ));
$loader = $this->getMock('\Twig_LoaderInterface'); $loader = $this->getMock('\Twig_LoaderInterface');
$loader->expects($this->never())->method('getSource'); $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; return $loader;
}); };
$this->assertEquals('foo', $app['twig.loader']->getSource('foo')); $this->assertEquals('foo', $app['twig.loader']->getSource('foo'));
} }
} }
...@@ -28,8 +28,8 @@ class ValidatorServiceProviderTest extends \PHPUnit_Framework_TestCase ...@@ -28,8 +28,8 @@ class ValidatorServiceProviderTest extends \PHPUnit_Framework_TestCase
public function testRegister() public function testRegister()
{ {
$app = new Application(); $app = new Application();
$app->register(new ValidatorServiceProvider()); $app->register(new ValidatorServiceProvider());
$app->register(new FormServiceProvider());
return $app; return $app;
} }
...@@ -38,9 +38,9 @@ class ValidatorServiceProviderTest extends \PHPUnit_Framework_TestCase ...@@ -38,9 +38,9 @@ class ValidatorServiceProviderTest extends \PHPUnit_Framework_TestCase
{ {
$app = new Application(); $app = new Application();
$app['custom.validator'] = $app->share(function() { $app['custom.validator'] = function() {
return new CustomValidator(); return new CustomValidator();
}); };
$app->register(new ValidatorServiceProvider(), array( $app->register(new ValidatorServiceProvider(), array(
'validator.validator_service_ids' => array( 'validator.validator_service_ids' => array(
...@@ -56,7 +56,7 @@ class ValidatorServiceProviderTest extends \PHPUnit_Framework_TestCase ...@@ -56,7 +56,7 @@ class ValidatorServiceProviderTest extends \PHPUnit_Framework_TestCase
*/ */
public function testConstraintValidatorFactory($app) 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()); $validator = $app['validator.validator_factory']->getInstance(new Custom());
$this->assertInstanceOf('Silex\Tests\Provider\ValidatorServiceProviderTest\Constraint\CustomValidator', $validator); $this->assertInstanceOf('Silex\Tests\Provider\ValidatorServiceProviderTest\Constraint\CustomValidator', $validator);
...@@ -76,9 +76,6 @@ class ValidatorServiceProviderTest extends \PHPUnit_Framework_TestCase ...@@ -76,9 +76,6 @@ class ValidatorServiceProviderTest extends \PHPUnit_Framework_TestCase
*/ */
public function testValidatorConstraint($email, $isValid, $nbGlobalError, $nbEmailError, $app) public function testValidatorConstraint($email, $isValid, $nbGlobalError, $nbEmailError, $app)
{ {
$app->register(new ValidatorServiceProvider());
$app->register(new FormServiceProvider());
$constraints = new Assert\Collection(array( $constraints = new Assert\Collection(array(
'email' => array( 'email' => array(
new Assert\NotBlank(), new Assert\NotBlank(),
......
...@@ -152,12 +152,12 @@ class RouterTest extends \PHPUnit_Framework_TestCase ...@@ -152,12 +152,12 @@ class RouterTest extends \PHPUnit_Framework_TestCase
{ {
$app = new Application(); $app = new Application();
$app->get('/foo', function () use ($app) { $app->get('/foo', function (Request $request) use ($app) {
return new Response($app['request']->getRequestUri()); return new Response($request->getRequestUri());
}); });
$app->error(function ($e) use ($app) { $app->error(function ($e, Request $request, $code) use ($app) {
return new Response($app['request']->getRequestUri()); return new Response($request->getRequestUri());
}); });
foreach (array('/foo', '/bar') as $path) { foreach (array('/foo', '/bar') as $path) {
......
...@@ -23,6 +23,7 @@ class ServiceControllerResolverRouterTest extends RouterTest ...@@ -23,6 +23,7 @@ class ServiceControllerResolverRouterTest extends RouterTest
public function testServiceNameControllerSyntax() public function testServiceNameControllerSyntax()
{ {
$app = new Application(); $app = new Application();
$app->register(new ServiceControllerServiceProvider());
$app['service_name'] = function () { $app['service_name'] = function () {
return new MyController(); return new MyController();
...@@ -35,8 +36,6 @@ class ServiceControllerResolverRouterTest extends RouterTest ...@@ -35,8 +36,6 @@ class ServiceControllerResolverRouterTest extends RouterTest
protected function checkRouteResponse(Application $app, $path, $expectedContent, $method = 'get', $message = null) protected function checkRouteResponse(Application $app, $path, $expectedContent, $method = 'get', $message = null)
{ {
$app->register(new ServiceControllerServiceProvider());
$request = Request::create($path, $method); $request = Request::create($path, $method);
$response = $app->handle($request); $response = $app->handle($request);
$this->assertEquals($expectedContent, $response->getContent(), $message); $this->assertEquals($expectedContent, $response->getContent(), $message);
......
...@@ -13,6 +13,7 @@ namespace Silex\Tests; ...@@ -13,6 +13,7 @@ namespace Silex\Tests;
use Silex\Application; use Silex\Application;
use Silex\WebTestCase; use Silex\WebTestCase;
use Symfony\Component\HttpFoundation\Request;
/** /**
* Functional test cases. * Functional test cases.
...@@ -33,9 +34,9 @@ class WebTestCaseTest extends WebTestCase ...@@ -33,9 +34,9 @@ class WebTestCaseTest extends WebTestCase
return '<h1>title</h1>'; return '<h1>title</h1>';
}); });
$app->match('/server', function () use ($app) { $app->match('/server', function (Request $request) use ($app) {
$user = $app['request']->server->get('PHP_AUTH_USER'); $user = $request->server->get('PHP_AUTH_USER');
$pass = $app['request']->server->get('PHP_AUTH_PW'); $pass = $request->server->get('PHP_AUTH_PW');
return "<h1>$user:$pass</h1>"; return "<h1>$user:$pass</h1>";
}); });
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment