Skip to content

Commit

Permalink
Allow defining no clients and add validation of client definition
Browse files Browse the repository at this point in the history
  • Loading branch information
Seldaek committed Oct 29, 2012
1 parent 77c4b56 commit 39ebcb3
Show file tree
Hide file tree
Showing 3 changed files with 192 additions and 156 deletions.
105 changes: 59 additions & 46 deletions DependencyInjection/Configuration.php
@@ -1,46 +1,59 @@
<?php

/*
* This file is part of the Nelmio SolariumBundle.
*
* (c) Nelmio <hello@nelm.io>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Nelmio\SolariumBundle\DependencyInjection;

use Symfony\Component\Config\Definition\Builder\TreeBuilder;
use Symfony\Component\Config\Definition\ConfigurationInterface;
use Symfony\Component\Config\Definition\Builder\BooleanNodeDefinition;
use Symfony\Component\Config\Definition\Builder\ScalarNodeDefinition;
use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition;

/**
* @author Igor Wiedler <igor@wiedler.ch>
*/
class Configuration implements ConfigurationInterface
{
/**
* {@inheritDoc}
*/
public function getConfigTreeBuilder()
{
$treeBuilder = new TreeBuilder();
$rootNode = $treeBuilder->root('nelmio_solarium');

$rootNode
->children()
->scalarNode('default_client')->cannotBeEmpty()->defaultValue('default')->end()
->arrayNode('clients')
->requiresAtLeastOneElement()
->prototype('array')
->prototype('variable')
->end()
->end()
;

return $treeBuilder;
}
}
<?php

/*
* This file is part of the Nelmio SolariumBundle.
*
* (c) Nelmio <hello@nelm.io>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Nelmio\SolariumBundle\DependencyInjection;

use Symfony\Component\Config\Definition\Builder\TreeBuilder;
use Symfony\Component\Config\Definition\ConfigurationInterface;
use Symfony\Component\Config\Definition\Builder\BooleanNodeDefinition;
use Symfony\Component\Config\Definition\Builder\ScalarNodeDefinition;
use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition;

/**
* @author Igor Wiedler <igor@wiedler.ch>
*/
class Configuration implements ConfigurationInterface
{
/**
* {@inheritDoc}
*/
public function getConfigTreeBuilder()
{
$treeBuilder = new TreeBuilder();
$rootNode = $treeBuilder->root('nelmio_solarium');

$rootNode
->children()
->scalarNode('default_client')->cannotBeEmpty()->defaultValue('default')->end()
->arrayNode('clients')

This comment has been minimized.

Copy link
@cjunge

cjunge Oct 29, 2012

There is a bug here when using multiple config files to define the parameters for the same client name. If I have a client "default" in config.yml, and "default" in config_test.yml then the settings from config_test are not added to the settings in config. The processed settings appear as 2 parts in the array, with no name defined, just numeric indexes.

Adding ->useAttributeAsKey('name') seems to fix this, and it behaves correctly.

I don't see how having 2 clients defined, with the second one being the default could've worked without that settings, as the clients array don't have named indexes to look up.

->canBeUnset()
->prototype('array')
->addDefaultsIfNotSet()
->children()
->scalarNode('client_class')->cannotBeEmpty()->defaultValue('Solarium_Client')->end()
->scalarNode('adapter_class')->cannotBeEmpty()->defaultValue('Solarium_Client_Adapter_Http')->end()
->scalarNode('host')->defaultValue('127.0.0.1')->end()
->scalarNode('port')->defaultValue(8983)->end()
->scalarNode('path')->defaultValue('/solr')->end()
->scalarNode('timeout')->defaultValue(5)->end()
->arrayNode('cores')

This comment has been minimized.

Copy link
@cjunge

cjunge Oct 30, 2012

I believe this should be:
->scalarNode('core')->end()

As Adaptors have only one core (I believe, and there can be multiple clients now). This seems a little inconvenient if there are multiple cores per server, but not too difficult to understand that you now need multiple client definitions for multiple cores.

This comment has been minimized.

Copy link
@Seldaek

Seldaek Oct 30, 2012

Author Member

Thanks, I fixed both your points, if you'd like to try again with the latest.

This comment has been minimized.

Copy link
@wiistriker

wiistriker Oct 30, 2012

Contributor

Seldaek, why we need all this configurations? I mean, various adapter classes get various options and with this code we cant pass them into solarium. What do you think about this?

This comment has been minimized.

Copy link
@Seldaek

Seldaek Oct 31, 2012

Author Member

Well, it looks to me like all Solarium native adapter take the same options. The advantage of this is that you get validation. If you make a typo the framework will tell you instead of you scratching your head why the adapter can't connect for 2hours because you wrote prot instead of port. If it really is a problem I guess we can allow extra keys or maybe a new option to pass an adapter service id instead of the class+args, so you can define your own service with whatever args you want and plug it in here.

->useAttributeAsKey('key')
->canBeUnset()
->prototype('scalar')
->end()
->end()
->end()
->end()
;

return $treeBuilder;
}
}
167 changes: 86 additions & 81 deletions DependencyInjection/NelmioSolariumExtension.php
@@ -1,82 +1,87 @@
<?php

/*
* This file is part of the Nelmio SolariumBundle.
*
* (c) Nelmio <hello@nelm.io>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Nelmio\SolariumBundle\DependencyInjection;

use Symfony\Component\Config\Definition\Processor;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
use Symfony\Component\DependencyInjection\Loader\XmlFileLoader;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\DependencyInjection\DefinitionDecorator;

/**
* @author Igor Wiedler <igor@wiedler.ch>
*/
class NelmioSolariumExtension extends Extension
{
public function load(array $configs, ContainerBuilder $container)
{
$processor = new Processor();
$configuration = new Configuration();
$config = $processor->processConfiguration($configuration, $configs);

if ($container->getParameter('kernel.debug') === true) {
$is_debug = true;
$loader = new XmlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
$loader->load('logger.xml');
} else {
$is_debug = false;
}

$default_client = $config['default_client'];

foreach ($config['clients'] as $name => $client_options) {
$client_name = sprintf('solarium.client.%s', $name);
$adapter_name = sprintf('solarium.client.adapter.%s', $name);

if (isset($client_options['client_class'])) {
$client_class = $client_options['client_class'];
unset($client_options['client_class']);
} else {
$client_class = 'Solarium_Client';
}

if (isset($client_options['adapter_class'])) {
$adapter_class = $client_options['adapter_class'];
unset($client_options['adapter_class']);
} else {
$adapter_class = 'Solarium_Client_Adapter_Http';
}

$clientDefinition = new Definition($client_class);
$container->setDefinition($client_name, $clientDefinition);

if ($name == $default_client) {
$container->setAlias('solarium.client', $client_name);
}

$container
->setDefinition($adapter_name, new Definition($adapter_class))
->setArguments(array($client_options));

$adapter = new Reference($adapter_name);
$container->getDefinition($client_name)->addMethodCall('setAdapter', array($adapter));

if ($is_debug) {
$logger = new Reference('solarium.data_collector');
$container->getDefinition($client_name)->addMethodCall('registerPlugin', array($client_name . '.logger', $logger));
}
}
}
<?php

/*
* This file is part of the Nelmio SolariumBundle.
*
* (c) Nelmio <hello@nelm.io>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Nelmio\SolariumBundle\DependencyInjection;

use Symfony\Component\Config\Definition\Processor;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
use Symfony\Component\DependencyInjection\Loader\XmlFileLoader;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\DependencyInjection\DefinitionDecorator;

/**
* @author Igor Wiedler <igor@wiedler.ch>
*/
class NelmioSolariumExtension extends Extension
{
public function load(array $configs, ContainerBuilder $container)
{
$processor = new Processor();
$configuration = new Configuration();
$config = $processor->processConfiguration($configuration, $configs);

if ($container->getParameter('kernel.debug') === true) {
$is_debug = true;
$loader = new XmlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
$loader->load('logger.xml');
} else {
$is_debug = false;
}

$default_client = $config['default_client'];
if (!count($config['clients'])) {
$config['clients'][$default_client] = array();
} elseif (count($config['clients']) === 1) {
$default_client = key($config['clients']);
}

foreach ($config['clients'] as $name => $client_options) {
$client_name = sprintf('solarium.client.%s', $name);
$adapter_name = sprintf('solarium.client.adapter.%s', $name);

if (isset($client_options['client_class'])) {
$client_class = $client_options['client_class'];
unset($client_options['client_class']);
} else {
$client_class = 'Solarium_Client';
}

if (isset($client_options['adapter_class'])) {
$adapter_class = $client_options['adapter_class'];
unset($client_options['adapter_class']);
} else {
$adapter_class = 'Solarium_Client_Adapter_Http';
}

$clientDefinition = new Definition($client_class);
$container->setDefinition($client_name, $clientDefinition);

if ($name == $default_client) {
$container->setAlias('solarium.client', $client_name);
}

$container
->setDefinition($adapter_name, new Definition($adapter_class))
->setArguments(array($client_options));

$adapter = new Reference($adapter_name);
$container->getDefinition($client_name)->addMethodCall('setAdapter', array($adapter));

if ($is_debug) {
$logger = new Reference('solarium.data_collector');
$container->getDefinition($client_name)->addMethodCall('registerPlugin', array($client_name . '.logger', $logger));
}
}
}
}
76 changes: 47 additions & 29 deletions README.md
Expand Up @@ -12,7 +12,7 @@ Add NelmioSolariumBundle in your composer.json:
```js
{
"require": {
"nelmio/solarium-bundle": "dev-master"
"nelmio/solarium-bundle": "1.*"
}
}
```
Expand All @@ -39,26 +39,28 @@ Add the NelmioSolariumBundle to your AppKernel.php

Quick-start configuration:

nelmio_solarium:
clients:
default: ~
```yaml
nelmio_solarium: ~
```

Gives you Solarium_Client with default options (`http://localhost:8983/solr`)
Gives you a Solarium_Client service with default options (`http://localhost:8983/solr`)

```php
$client = $this->get('solarium.client');
```

Configure your client:

nelmio_solarium:
clients:
default:
host: localhost
port: 8983
path: /solr
core: active
timeout: 5
```yaml
nelmio_solarium:
clients:
default:
host: localhost
port: 8983
path: /solr
core: active
timeout: 5
```

## Usage

Expand All @@ -73,13 +75,15 @@ For more information see the [Solarium documentation](http://www.solarium-projec

## Multiple clients

nelmio_solarium:
clients:
default:
host: 192.168.1.2
another:
host: 192.168.1.3
```yaml
nelmio_solarium:
clients:
default:
host: 192.168.1.2

another:
host: 192.168.1.3
```

```php
$defaultClient = $this->get('solarium.client');
Expand All @@ -89,23 +93,37 @@ For more information see the [Solarium documentation](http://www.solarium-projec
You may also change `default` name with your own, but don't forget change `default_client` option if you want to get access to
`solarium.client` service

nelmio_solarium:
default_client: firstOne
clients:
firstOne:
host: 192.168.1.2
anotherOne:
host: 192.168.1.3
```yaml
nelmio_solarium:
default_client: firstOne
clients:
firstOne:
host: 192.168.1.2

anotherOne:
host: 192.168.1.3
```

```php
$firstOneClient = $this->get('solarium.client');
//or
$firstOneClient = $this->get('solarium.client.firstOne');

$anotherOneClient = $this->get('solarium.client.anotherOne');
```

## Overriding Classes

To change the adapter or client classes, you can set the client_class and adapter_class options:

```yaml
nelmio_solarium:
default_client: firstOne
clients:
default:
client_class: Solarium_Client
adapter_class: Solarium_Client_Adapter_Http
```

## License

Expand Down

0 comments on commit 39ebcb3

Please sign in to comment.