Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Rework the whole provider for v0.4.0 (now requires Predis v0.8).
Nothing changes for single-client configurations, but there is
a BC for multiple-clients configurations since the addition of
the `boot()` mechanism in Silex essentially made impossible to
keep this feature alive without artificially boot()-ing the
provider (which was no good).

Multiple clients are now supported only when using the new
`Predis\Silex\MultiPredisServiceProvider` but the way clients
are configured remained the same.

Clients in such configuration are accessible in the following
manner:

  $client = $app['predis'][$alias];

It is no more possible to configure a default client responding
to `$app['predis']` due to the nature of the above change.
  • Loading branch information
nrk committed Feb 2, 2013
1 parent 95d7bbe commit cb324ef
Show file tree
Hide file tree
Showing 14 changed files with 457 additions and 351 deletions.
12 changes: 12 additions & 0 deletions CHANGELOG
@@ -1,3 +1,15 @@
v0.4.0 (2013-02-xx)
* The service provider now requires Predis v0.8.

* `Predis\Silex\PredisServiceProvider` is now used only for single-client
configurations while the new `Predis\Silex\MultiPredisServiceProvider`
can be used to configure multiple clients. This is a breaking change from
previous versions in which both configurations were handled by the same
provider class.

* Due to the nature of the above mentioned change, it is no more possible
to define a default client when using a multiple-clients configuration.

v0.3.0 (2012-07-14)
* Fixed service provider configuration after the recent addition of the
`boot()` method in Silex.
Expand Down
2 changes: 1 addition & 1 deletion LICENSE
@@ -1,4 +1,4 @@
Copyright (c) 2011-2012 Daniele Alessandri
Copyright (c) 2011-2013 Daniele Alessandri

Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
Expand Down
58 changes: 21 additions & 37 deletions README.md
@@ -1,37 +1,32 @@
# PredisServiceProvider #

This service provider for the __[Silex](http://silex-project.org)__ microframework enables developers to easily
use __[Predis](http://github.com/nrk/predis)__ in their applications to connect to __[Redis](http://redis.io)__.
This is a service provider for [Silex](http://silex-project.org) that enables developers to easily connect
to [Redis](http://redis.io) by using [Predis](http://github.com/nrk/predis).


## Getting started ##

Using this service provider in your application is easy and requires the use of [Composer](http://packagist.org/about-composer)
to download and set up all the needed dependencies by adding `"predis/service-provider": "0.3.*@stable"` to the
list of `require`d libraries in your `composer.json` file.
Supposing that you have already set up the required dependencies using [Composer](http://packagist.org/about-composer)
and the scheleton of your Silex application is ready, now you simply need to register the service provider
specifying the parameters and options needed to access Redis:

After installing, and supposing that you already have the scheleton of your Silex application ready, you just need
to register the service provider with the parameters needed to access the Redis server instance and configure the
underlying Predis client:

``` php
<?php
/* ... */
```php
$app->register(new Predis\Silex\PredisServiceProvider(), array(
'predis.parameters' => 'tcp://127.0.0.1:6379/',
'predis.parameters' => 'tcp://127.0.0.1:6379',
'predis.options' => array('profile' => '2.2'),
));
/* ... */
```

Both `predis.parameters` and `predis.options` are actually optional and accept the same values of the constructor
method of `Predis\Client`. It is also possible to define multiple clients identified by aliases with their own
parameters and options using `predis.clients`. Each client instance will be initialized lazily upon first access:
This will register a single `Predis\Client` instance accessible by your application using `$app['predis']`.
Both `predis.parameters` and `predis.options` are optional and accept the same values of the constructor
of `Predis\Client`.

``` php
<?php
/* ... */
$app->register(new Predis\Silex\PredisServiceProvider(), array(
Certain applications might need more than one client to reach different servers or configured with different
options such as key prefixing or server profile. In such cases you must use `Predis\Silex\MultiPredisServiceProvider`
and provide a list of clients with their own parameters and options using `predis.clients`:

```php
$app->register(new Predis\Silex\MultiPredisServiceProvider(), array(
'predis.clients' => array(
'first' => 'tcp://127.0.0.1:6379',
'second' => array(
Expand All @@ -47,29 +42,18 @@ $app->register(new Predis\Silex\PredisServiceProvider(), array(
),
),
));
/* ... */
```

If you are looking for simple but complete examples of how to use this extension you can have a look at the
_examples_ directory included in the repository or the test suite in the _tests_ directory.

Client instances will be exposed to your application using `$app['predis'][$alias]` where `$alias` is the key
used to populate the items of `predis.clients`. Each client instance will be initialized lazily upon first access.

## Testing ##

In order to be able to run the test suite of the provider you must run `php composer.phar install` in the root
of the repository to install the needed dependencies.

```bash
$ wget http://getcomposer.org/composer.phar
$ php composer.phar install
$ phpunit
```
You can find more details on how to use this provider in the `examples` directory or the test suite,


## Dependencies ##

- PHP >= 5.3.2
- Predis >= 0.7.0
- Predis >= 0.8.0


## Project links ##
Expand All @@ -89,4 +73,4 @@ of the repository to install the needed dependencies.

## License ##

The code for PredisServiceProvider is distributed under the terms of the __MIT license__ (see LICENSE).
The code for PredisServiceProvider is distributed under the terms of the [MIT license](LICENSE).
2 changes: 1 addition & 1 deletion VERSION
@@ -1 +1 @@
0.3.0
0.4.0-dev
2 changes: 1 addition & 1 deletion composer.json
Expand Up @@ -18,7 +18,7 @@
"minimum-stability": "dev",
"require": {
"php": ">=5.3.2",
"predis/predis": "0.7.*@stable",
"predis/predis": "0.8.*@stable",
"silex/silex": "1.0.*"
}
}
9 changes: 5 additions & 4 deletions examples/multiple.php
Expand Up @@ -4,7 +4,7 @@

$app = new Silex\Application();

$app->register(new Predis\Silex\PredisServiceProvider(), array(
$app->register(new Predis\Silex\MultiPredisServiceProvider(), array(
'predis.clients' => array(
'first' => 'tcp://127.0.0.1:6379',
'second' => array(
Expand All @@ -25,10 +25,11 @@
));

/** routes **/

$app->get('/', function () use ($app) {
$first = var_export($app['predis.first']->info(), true);
$second = var_export($app['predis.second']->info(), true);
$third = var_export($app['predis.third']->info(), true);
$first = var_export($app['predis']['first']->info(), true);
$second = var_export($app['predis']['second']->info(), true);
$third = var_export($app['predis']['third']->info(), true);

return "$first<br/>\n$second<br/>\n$third<br/>\n";
});
Expand Down
File renamed without changes.
54 changes: 54 additions & 0 deletions lib/Predis/Silex/MultiPredisServiceProvider.php
@@ -0,0 +1,54 @@
<?php

/*
* This file is part of the PredisServiceProvider package.
*
* (c) Daniele Alessandri <suppakilla@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Predis\Silex;

use Pimple;
use Silex\Application;

/**
* Exposes multiple and separate instances of Predis\Client to Silex.
*
* @author Daniele Alessandri <suppakilla@gmail.com>
*/
class MultiPredisServiceProvider extends PredisServiceProvider
{
/**
* {@inheritdoc}
*/
protected function getProviderHandler(Application $app, $prefix)
{
return $app->share(function () use ($app, $prefix) {
$clients = new Pimple();

foreach ($app["$prefix.clients"] as $alias => $args) {
$clients[$alias] = $clients->share(function () use ($app, $prefix, $args) {
$initializer = $app["$prefix.client_initializer"];

if (!isset($args['parameters']) && !isset($args['options'])) {
$args = array('parameters' => $args);
}

return $initializer($args);
});
}

return $clients;
});
}

public function register(Application $app)
{
$app["{$this->prefix}.clients"] = array();

parent::register($app);
}
}
95 changes: 44 additions & 51 deletions lib/Predis/Silex/PredisServiceProvider.php
Expand Up @@ -11,13 +11,13 @@

namespace Predis\Silex;

use InvalidArgumentException;
use Predis\Client;
use Silex\Application;
use Silex\ServiceProviderInterface;

use Predis\Client;

/**
* Exposes one or more client instances of Predis to Silex.
* Exposes a single instance of Predis\Client to Silex.
*
* @author Daniele Alessandri <suppakilla@gmail.com>
*/
Expand All @@ -31,12 +31,12 @@ class PredisServiceProvider implements ServiceProviderInterface
protected $prefix;

/**
* @param string $predix Prefix name used to register the service provider in Silex.
* @param string $prefix Prefix name used to register the service provider in Silex.
*/
public function __construct($prefix = 'predis')
{
if (empty($prefix)) {
throw new \InvalidArgumentException('The specified prefix is not valid.');
throw new InvalidArgumentException('The specified prefix is not valid.');
}

$this->prefix = $prefix;
Expand All @@ -47,57 +47,20 @@ public function __construct($prefix = 'predis')
*/
public function boot(Application $app)
{
$prefix = $this->prefix;

if (!isset($app["$prefix.default_parameters"])) {
$app["$prefix.default_parameters"] = array();
}

if (!isset($app["$prefix.default_options"])) {
$app["$prefix.default_options"] = array();
}

if (isset($app["$prefix.clients"])) {
foreach ($app["$prefix.clients"] as $alias => $args) {
if (in_array($alias, self::$reserved, true)) {
throw new \InvalidArgumentException("The specified alias '$alias' is not valid.");
}

$app["$prefix.$alias"] = $app->share(function () use ($app, $prefix, $args) {
$initializer = $app["$prefix.client_initializer"];

if (!isset($args['parameters'])) {
if (!isset($args['options']) && !isset($args['default'])) {
$args = array('parameters' => $args);
}
}

return $initializer($args);
});

if (is_array($args) && isset($args['default']) && $args['default'] == true) {
$app[$prefix] = $app->share(function () use ($app, $prefix, $alias) {
return $app["$prefix.$alias"];
});
}
}
} else {
$app[$prefix] = $app->share(function () use ($app, $prefix) {
$initializer = $app["$prefix.client_initializer"];

return $initializer($app);
});
}
// NOOP
}

/**
* {@inheritdoc}
* Returns the anonymous function that will be used by the service provider
* to lazily-initialize new instances of Predis\Client.
*
* @param Application $app
* @param string $prefix
* @return \Closure
*/
public function register(Application $app)
protected function getClientInitializer(Application $app, $prefix)
{
$prefix = $this->prefix;

$app["$prefix.client_initializer"] = $app->protect(function ($arguments) use ($app, $prefix) {
return $app->protect(function ($arguments) use ($app, $prefix) {
$extract = function ($bag, $key) use ($app, $prefix) {
$default = "default_$key";

Expand Down Expand Up @@ -127,4 +90,34 @@ public function register(Application $app)
return new Client($parameters, $options);
});
}

/**
* Returns the anonymous function that will be used by the service provider
* to handle accesses to the root prefix.
*
* @param Application $app
* @param string $prefix
* @return mixed
*/
protected function getProviderHandler(Application $app, $prefix)
{
return $app->share(function () use ($app, $prefix) {
$initializer = $app["$prefix.client_initializer"];

return $initializer($app);
});
}

/**
* {@inheritdoc}
*/
public function register(Application $app)
{
$prefix = $this->prefix;

$app["$prefix.default_parameters"] = array();
$app["$prefix.default_options"] = array();
$app["$prefix.client_initializer"] = $this->getClientInitializer($app, $prefix);
$app["$prefix"] = $this->getProviderHandler($app, $prefix);
}
}

0 comments on commit cb324ef

Please sign in to comment.